fix(compilation): use cross for statically linking against musl
							parent
							
								
									3d024db2e9
								
							
						
					
					
						commit
						490dfcf2f2
					
				|  | @ -9,5 +9,6 @@ | |||
| !src | ||||
| !tests | ||||
| !web | ||||
| !target/x86_64-unknown-linux-musl/release/rbd | ||||
| 
 | ||||
| web/node_modules | ||||
|  |  | |||
|  | @ -939,6 +939,7 @@ version = "0.4.6" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda" | ||||
| dependencies = [ | ||||
|  "pkg-config", | ||||
|  "vcpkg", | ||||
| ] | ||||
| 
 | ||||
|  | @ -1221,6 +1222,7 @@ dependencies = [ | |||
|  "jwt", | ||||
|  "mimalloc", | ||||
|  "openssl", | ||||
|  "pq-sys", | ||||
|  "rand", | ||||
|  "rocket", | ||||
|  "rocket_sync_db_pools", | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ serde = { version = "1.0.127", features = [ "derive" ] } | |||
| diesel = { version = "1.4.7", features = ["postgres", "uuidv07", "chrono"] } | ||||
| diesel_migrations = "1.4.0" | ||||
| # To properly compile libpq statically | ||||
| openssl = "0.10.36" | ||||
| openssl = "*" | ||||
| # For password hashing & verification | ||||
| rust-argon2 = "0.8.3" | ||||
| rand = "0.8.4" | ||||
|  | @ -38,6 +38,11 @@ base64 = "0.13.0" | |||
| figment = { version = "*", features = [ "yaml" ] } | ||||
| mimalloc = { version = "0.1.26", default_features = false } | ||||
| 
 | ||||
| [dependencies.pq-sys] | ||||
| version = "*" | ||||
| default-features = false | ||||
| features = ["pkg-config"] | ||||
| 
 | ||||
| [profile.release] | ||||
| lto = "fat" | ||||
| panic = "abort" | ||||
|  |  | |||
|  | @ -0,0 +1,3 @@ | |||
| [target.x86_64-unknown-linux-musl] | ||||
| image = "rusty-builder:x86_64-unknown-linux" | ||||
| 
 | ||||
							
								
								
									
										21
									
								
								Dockerfile
								
								
								
								
							
							
						
						
									
										21
									
								
								Dockerfile
								
								
								
								
							|  | @ -1,19 +1,4 @@ | |||
| FROM rust:1.54 | ||||
| FROM scratch | ||||
| 
 | ||||
| ENV PREFIX="/usr/src/out/prefix" \ | ||||
|     CC="musl-gcc -fPIC -pie -static" \ | ||||
|     LD_LIBRARY_PATH="$PREFIX" \ | ||||
|     PKG_CONFIG_PATH="/usr/local/lib/pkgconfig" \ | ||||
|     PATH="/usr/local/bin:/root/.cargo/bin:$PATH" | ||||
| 
 | ||||
| RUN apt update && \ | ||||
|     apt install -y --no-install-recommends \ | ||||
|         musl-dev \ | ||||
|         musl-tools \ | ||||
|         libpq-dev \ | ||||
|         libssl-dev && \ | ||||
|     rustup target add x86_64-unknown-linux-musl && \ | ||||
|     mkdir "$PREFIX" && \ | ||||
|     echo "$PREFIX/lib" >> /etc/ld-musl-x86_64.path | ||||
| 
 | ||||
| WORKDIR /usr/src/app | ||||
| COPY target/x86_64-unknown-linux-musl/release/rbd / | ||||
| RUN ["/rbd"] | ||||
|  |  | |||
|  | @ -0,0 +1,68 @@ | |||
| # Cross-compile for a specific target triplet (x86_64 by default) | ||||
| ARG TARGET | ||||
| ARG CORES=4 | ||||
| FROM rustembedded/cross:${TARGET}-musl | ||||
| 
 | ||||
| # Create download directory | ||||
| RUN mkdir /src | ||||
| 
 | ||||
| ### Environment | ||||
| # Configure compiler | ||||
| ENV MAKE="make -j$CORES" \ | ||||
|     CC="musl-gcc -fPIE -pie -static" \ | ||||
|     PREFIX=/usr/local/x86_64-linux-musl \ | ||||
|     RUSTFLAGS="-C relocation-model=static" | ||||
| # Configure paths | ||||
| ENV PATH=$PREFIX/bin:$PATH \ | ||||
|     C_INCLUDE_PATH=$PREFIX/include \ | ||||
|     LD_LIBRARY_PATH=$PREFIX/lib | ||||
| # Configure pkg-config | ||||
| ENV PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig \ | ||||
|     PKG_CONFIG_ALLOW_CROSS=true \ | ||||
|     PKG_CONFIG_ALL_STATIC=true | ||||
| 
 | ||||
| # Install development libraries | ||||
| RUN apt-get update && apt-get install -y \ | ||||
|     bison \ | ||||
|     flex \ | ||||
|     musl-dev \ | ||||
|     musl-tools | ||||
| 
 | ||||
| ### OpenSSL | ||||
| ARG SSL_VER | ||||
| # Download OpenSSL | ||||
| RUN curl -sSL "https://www.openssl.org/source/openssl-${SSL_VER}.tar.gz" | tar -xzC /src | ||||
| # Build OpenSSL statically | ||||
| RUN cd "/src/openssl-${SSL_VER}" \ | ||||
|     && ./Configure \ | ||||
|         no-shared \ | ||||
|         no-zlib \ | ||||
|         -fPIC \ | ||||
|         --prefix=$PREFIX \ | ||||
|         --openssldir=$PREFIX/ssl \ | ||||
|         linux-x86_64 \ | ||||
|     && $MAKE depend \ | ||||
|     && $MAKE \ | ||||
|     && $MAKE install | ||||
| # Configure OpenSSL crate | ||||
| ENV OPENSSL_STATIC=true \ | ||||
|     OPENSSL_NO_VENDOR=true | ||||
| 
 | ||||
| ### PostgreSQL | ||||
| ARG PQ_VER | ||||
| # Download PostgreSQL | ||||
| RUN curl -sSL "https://ftp.postgresql.org/pub/source/v${PQ_VER}/postgresql-${PQ_VER}.tar.gz" | tar -xzC /src | ||||
| # Build PostgreSQL statically | ||||
| RUN cd "/src/postgresql-${PQ_VER}" \ | ||||
|     && CPPFLAGS=-I$PREFIX/include LDFLAGS="-L$PREFIX/lib" \ | ||||
|         ./configure \ | ||||
|         --with-openssl \ | ||||
|         --without-readline \ | ||||
|         --without-zlib \ | ||||
|         --prefix=$PREFIX \ | ||||
|         --host=$TARGET \ | ||||
|     && ${MAKE} -C src/interfaces/libpq all-static-lib \ | ||||
|     && ${MAKE} -C src/interfaces/libpq install-lib-pc \ | ||||
|     && ${MAKE} -C src/interfaces/libpq install-lib-static \ | ||||
|     && ${MAKE} -C src/bin/pg_config \ | ||||
|     && ${MAKE} -C src/bin/pg_config install | ||||
							
								
								
									
										139
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										139
									
								
								Makefile
								
								
								
								
							|  | @ -6,133 +6,36 @@ SSL_VER ?= 1.1.1k | |||
| # Dumb-init version
 | ||||
| DI_VER  ?= 1.2.5 | ||||
| 
 | ||||
| # Compilation target triplet
 | ||||
| # Supported targets: https://github.com/rust-embedded/cross#supported-targets
 | ||||
| TARGET = x86_64-unknown-linux | ||||
| CORES != nproc | ||||
| 
 | ||||
| # =====AUTO-GENERATED VARIABLES=====
 | ||||
| # This is such a lovely oneliner
 | ||||
| # NOTE: $(dir PATH) outputs a trailing slash
 | ||||
| OUT_DIR     ?= $(dir $(abspath $(lastword $(MAKEFILE_LIST))))out | ||||
| 
 | ||||
| PREFIX      := $(OUT_DIR)/prefix | ||||
| OPENSSL_DIR := $(OUT_DIR)/openssl-$(SSL_VER) | ||||
| PQ_DIR      := $(OUT_DIR)/postgresql-$(PQ_VER) | ||||
| DI_DIR      := $(OUT_DIR)/dumb-init-$(DI_VER) | ||||
| 
 | ||||
| # Used in various make calls to specify parallel recipes
 | ||||
| CORES       != nproc | ||||
| 
 | ||||
| 
 | ||||
| # =====ENVIRONMENT VARIABLES=====
 | ||||
| export CC := musl-gcc -fPIC -pie -static | ||||
| export LD_LIBRARY_PATH := $(PREFIX) | ||||
| export PKG_CONFIG_PATH := /usr/local/lib/pkgconfig | ||||
| export PATH := /usr/local/bin:/root/.cargo/bin:$(PATH) | ||||
| 
 | ||||
| 
 | ||||
| # TODO check for header files (openssl-dev, libpq-dev) both for Arch & Ubuntu
 | ||||
| 
 | ||||
| # Create the out dir
 | ||||
| $(shell mkdir -p "$(PREFIX)") | ||||
| 
 | ||||
| 
 | ||||
| # =====BUILDING THE STATIC BINARY=====
 | ||||
| .PHONY: all | ||||
| all: build | ||||
| all: build-debug | ||||
| 
 | ||||
| .PHONY: builder | ||||
| builder: | ||||
| 	docker build \
 | ||||
| 		-t rusty-builder:latest - < docker/Dockerfile.builder | ||||
| 		--build-arg TARGET=$(TARGET) \
 | ||||
| 		--build-arg CORES=$(CORES) \
 | ||||
| 		--build-arg SSL_VER=$(SSL_VER) \
 | ||||
| 		--build-arg PQ_VER=$(PQ_VER) \
 | ||||
| 		--tag rusty-builder:$(TARGET) \
 | ||||
| 		--file Dockerfile.build \
 | ||||
| 		. | ||||
| 
 | ||||
| .PHONY: docker | ||||
| docker: builder | ||||
| 	docker run \
 | ||||
| 		--rm \
 | ||||
| 		-v "$$PWD:/usr/src" \
 | ||||
| 		--workdir "/usr/src" \
 | ||||
| 		-it \
 | ||||
| 		rusty-builder:latest \
 | ||||
| 		bash build.sh | ||||
| .PHONY: build-debug | ||||
| build-debug: builder | ||||
| 	cross build --target "$(TARGET)-musl" | ||||
| 
 | ||||
| .PHONY: run | ||||
| run: builder | ||||
| 	docker-compose up -d --build && docker-compose logs -f app | ||||
| 
 | ||||
| # libpq builds openssl as a dependency
 | ||||
| .PHONY: build | ||||
| build: libpq | ||||
| 
 | ||||
| .PHONY: clean | ||||
| clean: clean-openssl clean-libpq clean-di | ||||
| 	@ echo "Note: this only cleans the C dependencies, not the Cargo cache." | ||||
| 	rm -rf "$(PREFIX)" | ||||
| 
 | ||||
| # This is used inside the Dockerfile
 | ||||
| .PHONY: pathfile | ||||
| pathfile: | ||||
| 	echo "$(PREFIX)/lib" >> /etc/ld-musl-x86_64.path | ||||
| 
 | ||||
| 
 | ||||
| ## =====OPENSSL=====
 | ||||
| # Download the source code & configure the project
 | ||||
| $(OPENSSL_DIR)/Configure: | ||||
| 	curl -sSL "https://www.openssl.org/source/openssl-$(SSL_VER).tar.gz" | \
 | ||||
| 		tar -xzC "$(OUT_DIR)" | ||||
| 	cd "$(OPENSSL_DIR)" && \
 | ||||
| 		CC="$(CC) -idirafter /usr/include -idirafter /usr/include/x86_64-linux-gnu/" ./Configure \
 | ||||
| 			no-zlib \
 | ||||
| 			no-shared \
 | ||||
| 			--prefix="$(PREFIX)" \
 | ||||
| 			--openssldir="$(PREFIX)/ssl" \
 | ||||
| 			linux-x86_64 | ||||
| 
 | ||||
| # Build OpenSSL
 | ||||
| .PHONY: openssl | ||||
| openssl: $(OPENSSL_DIR)/Configure | ||||
| 	cd "$(OPENSSL_DIR)" && env C_INCLUDE_PATH="$(PREFIX)/include" $(MAKE) depend 2> /dev/null | ||||
| 	cd "$(OPENSSL_DIR)" && $(MAKE) -j$(CORES) | ||||
| 	cd "$(OPENSSL_DIR)" && $(MAKE) install_sw | ||||
| 
 | ||||
| .PHONY: clean-openssl | ||||
| clean-openssl: | ||||
| 	rm -rf "$(OPENSSL_DIR)" | ||||
| 
 | ||||
| 
 | ||||
| ## =====LIBPQ=====
 | ||||
| # Download the source code & configure the project
 | ||||
| $(PQ_DIR)/configure: | ||||
| 	curl -sSL "https://ftp.postgresql.org/pub/source/v$(PQ_VER)/postgresql-$(PQ_VER).tar.gz" | \
 | ||||
| 		tar -xzC "$(OUT_DIR)" | ||||
| 	cd "$(PQ_DIR)" && \
 | ||||
| 		LDFLAGS="-L$(PREFIX)/lib" CFLAGS="-I$(PREFIX)/include" ./configure \
 | ||||
| 			--without-readline \
 | ||||
| 			--with-openssl \
 | ||||
| 			--without-zlib \
 | ||||
| 			--prefix="$(PREFIX)" \
 | ||||
| 			--host=x86_64-unknown-linux-musl | ||||
| 
 | ||||
| .PHONY: libpq | ||||
| libpq: openssl $(PQ_DIR)/configure | ||||
| 	cd "$(PQ_DIR)/src/interfaces/libpq" && $(MAKE) -j$(CORES) all-static-lib | ||||
| 	cd "$(PQ_DIR)/src/interfaces/libpq" && $(MAKE) install install-lib-static | ||||
| 	cd "$(PQ_DIR)/src/bin/pg_config" && $(MAKE) -j$(CORES) | ||||
| 	cd "$(PQ_DIR)/src/bin/pg_config" && $(MAKE) install | ||||
| 
 | ||||
| .PHONY: clean-libpq | ||||
| clean-libpq: | ||||
| 	rm -rf "$(PQ_DIR)" | ||||
| 
 | ||||
| 
 | ||||
| # =====DUMB-INIT=====
 | ||||
| # NOTE: this is only used inside the Docker image, but it's here for completeness.
 | ||||
| $(DI_DIR)/Makefile: | ||||
| 	curl -sSL "https://github.com/Yelp/dumb-init/archive/refs/tags/v$(DI_VER).tar.gz" | \
 | ||||
| 		tar -C "$(OUT_DIR)" -xz | ||||
| 
 | ||||
| .PHONY: di | ||||
| di: $(DI_DIR)/Makefile | ||||
| 	make -C "$(DI_DIR)" build | ||||
| 
 | ||||
| .PHONY: clean-di | ||||
| clean-di: | ||||
| 	rm -rf "$(DI_DIR)" | ||||
| 
 | ||||
| .PHONY: release | ||||
| build-release: builder | ||||
| 	cross build --target "$(TARGET)-musl" --release | ||||
| 
 | ||||
| # ====UTILITIES FOR DEVELOPMENT=====
 | ||||
| ## The tests require a database, so we run them like this
 | ||||
|  |  | |||
|  | @ -0,0 +1,7 @@ | |||
| fn main() { | ||||
|     println!("cargo:rustc-link-lib=static=c"); | ||||
|     println!("cargo:rustc-link-lib=static=dl"); | ||||
|     println!("cargo:rustc-link-lib=static=ssl"); | ||||
|     println!("cargo:rustc-link-lib=static=pq"); | ||||
| } | ||||
| 
 | ||||
|  | @ -2,10 +2,11 @@ | |||
| version: '3' | ||||
| 
 | ||||
| services: | ||||
|   app: | ||||
|     build: '.' | ||||
|   db: | ||||
|     image: 'postgres:13-alpine' | ||||
|     restart: 'always' | ||||
| 
 | ||||
|     environment: | ||||
|       - 'POSTGRES_DB=rb' | ||||
|       - 'POSTGRES_USER=rb' | ||||
|  | @ -14,6 +15,5 @@ services: | |||
|       - '5432:5432' | ||||
|     volumes: | ||||
|       - 'db-data:/var/lib/postgresql/data' | ||||
| 
 | ||||
| volumes: | ||||
|   db-data: | ||||
|  |  | |||
|  | @ -1,28 +0,0 @@ | |||
| # vim: ft=dockerfile | ||||
| FROM rust:1.54 | ||||
| 
 | ||||
| ENV PREFIX="/usr/src/out/prefix" \ | ||||
|     CC="musl-gcc -fPIC -pie -static" \ | ||||
|     LD_LIBRARY_PATH="$PREFIX" \ | ||||
|     PKG_CONFIG_PATH="/usr/local/lib/pkgconfig" \ | ||||
|     PATH="/usr/local/bin:/root/.cargo/bin:$PATH" | ||||
| 
 | ||||
| WORKDIR /usr/src/app | ||||
| 
 | ||||
| RUN groupadd -g 1000 builder && \ | ||||
|     useradd -u 1000 -g 1000 builder && \ | ||||
|     mkdir -p "$PREFIX" && \ | ||||
|     chown -R builder:builder /usr/src/app && \ | ||||
|     apt update && \ | ||||
|     apt install -y --no-install-recommends \ | ||||
|         musl-dev \ | ||||
|         musl-tools \ | ||||
|         libpq-dev \ | ||||
|         libssl-dev && \ | ||||
|     rustup target add x86_64-unknown-linux-musl && \ | ||||
|     echo "$PREFIX/lib" >> /etc/ld-musl-x86_64.path | ||||
| 
 | ||||
| 
 | ||||
| USER builder | ||||
| 
 | ||||
| CMD ["cargo", "test"] | ||||
|  | @ -2,11 +2,11 @@ | |||
| // compilation succeeds in the release Docker image.
 | ||||
| extern crate openssl; | ||||
| #[macro_use] | ||||
| extern crate rocket; | ||||
| extern crate diesel; | ||||
| #[macro_use] | ||||
| extern crate diesel_migrations; | ||||
| #[macro_use] | ||||
| extern crate diesel; | ||||
| extern crate rocket; | ||||
| 
 | ||||
| use figment::{ | ||||
|     providers::{Env, Format, Yaml}, | ||||
|  |  | |||
		Reference in New Issue