fix(compilation): use cross for statically linking against musl #36
			
				
			
		
		
		
	|  | @ -9,5 +9,6 @@ | ||||||
| !src | !src | ||||||
| !tests | !tests | ||||||
| !web | !web | ||||||
|  | !target/x86_64-unknown-linux-musl/release/rbd | ||||||
| 
 | 
 | ||||||
| web/node_modules | web/node_modules | ||||||
|  |  | ||||||
|  | @ -939,6 +939,7 @@ version = "0.4.6" | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda" | checksum = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  |  "pkg-config", | ||||||
|  "vcpkg", |  "vcpkg", | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
|  | @ -1221,6 +1222,7 @@ dependencies = [ | ||||||
|  "jwt", |  "jwt", | ||||||
|  "mimalloc", |  "mimalloc", | ||||||
|  "openssl", |  "openssl", | ||||||
|  |  "pq-sys", | ||||||
|  "rand", |  "rand", | ||||||
|  "rocket", |  "rocket", | ||||||
|  "rocket_sync_db_pools", |  "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 = { version = "1.4.7", features = ["postgres", "uuidv07", "chrono"] } | ||||||
| diesel_migrations = "1.4.0" | diesel_migrations = "1.4.0" | ||||||
| # To properly compile libpq statically | # To properly compile libpq statically | ||||||
| openssl = "0.10.36" | openssl = "*" | ||||||
| # For password hashing & verification | # For password hashing & verification | ||||||
| rust-argon2 = "0.8.3" | rust-argon2 = "0.8.3" | ||||||
| rand = "0.8.4" | rand = "0.8.4" | ||||||
|  | @ -38,6 +38,11 @@ base64 = "0.13.0" | ||||||
| figment = { version = "*", features = [ "yaml" ] } | figment = { version = "*", features = [ "yaml" ] } | ||||||
| mimalloc = { version = "0.1.26", default_features = false } | mimalloc = { version = "0.1.26", default_features = false } | ||||||
| 
 | 
 | ||||||
|  | [dependencies.pq-sys] | ||||||
|  | version = "*" | ||||||
|  | default-features = false | ||||||
|  | features = ["pkg-config"] | ||||||
|  | 
 | ||||||
| [profile.release] | [profile.release] | ||||||
| lto = "fat" | lto = "fat" | ||||||
| panic = "abort" | 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" \ | COPY target/x86_64-unknown-linux-musl/release/rbd / | ||||||
|     CC="musl-gcc -fPIC -pie -static" \ | RUN ["/rbd"] | ||||||
|     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 |  | ||||||
|  |  | ||||||
|  | @ -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
 | # Dumb-init version
 | ||||||
| DI_VER  ?= 1.2.5 | 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 | .PHONY: all | ||||||
| all: build | all: build-debug | ||||||
| 
 | 
 | ||||||
| .PHONY: builder | .PHONY: builder | ||||||
| builder: | builder: | ||||||
| 	docker build \
 | 	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 | .PHONY: build-debug | ||||||
| docker: builder | build-debug: builder | ||||||
| 	docker run \
 | 	cross build --target "$(TARGET)-musl" | ||||||
| 		--rm \
 |  | ||||||
| 		-v "$$PWD:/usr/src" \
 |  | ||||||
| 		--workdir "/usr/src" \
 |  | ||||||
| 		-it \
 |  | ||||||
| 		rusty-builder:latest \
 |  | ||||||
| 		bash build.sh |  | ||||||
| 
 | 
 | ||||||
|  | .PHONY: run | ||||||
|  | run: builder | ||||||
|  | 	docker-compose up -d --build && docker-compose logs -f app | ||||||
| 
 | 
 | ||||||
| # libpq builds openssl as a dependency
 | .PHONY: release | ||||||
| .PHONY: build | build-release: builder | ||||||
| build: libpq | 	cross build --target "$(TARGET)-musl" --release | ||||||
| 
 |  | ||||||
| .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)" |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| # ====UTILITIES FOR DEVELOPMENT=====
 | # ====UTILITIES FOR DEVELOPMENT=====
 | ||||||
| ## The tests require a database, so we run them like this
 | ## The tests require a database, so we run them like this
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,7 @@ | ||||||
|  | fn main() { | ||||||
| 
				
					
						maximdeclercq
						commented  
						Review
						 This script was required to tell cargo what to link. This script was required to tell cargo what to link. | |||||||
|  |     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' | version: '3' | ||||||
| 
 | 
 | ||||||
| services: | services: | ||||||
|  |   app: | ||||||
|  |     build: '.' | ||||||
|   db: |   db: | ||||||
|     image: 'postgres:13-alpine' |     image: 'postgres:13-alpine' | ||||||
|     restart: 'always' |     restart: 'always' | ||||||
| 
 |  | ||||||
|     environment: |     environment: | ||||||
|       - 'POSTGRES_DB=rb' |       - 'POSTGRES_DB=rb' | ||||||
|       - 'POSTGRES_USER=rb' |       - 'POSTGRES_USER=rb' | ||||||
|  | @ -14,6 +15,5 @@ services: | ||||||
|       - '5432:5432' |       - '5432:5432' | ||||||
|     volumes: |     volumes: | ||||||
|       - 'db-data:/var/lib/postgresql/data' |       - 'db-data:/var/lib/postgresql/data' | ||||||
| 
 |  | ||||||
| volumes: | volumes: | ||||||
|   db-data: |   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.
 | // compilation succeeds in the release Docker image.
 | ||||||
| extern crate openssl; | extern crate openssl; | ||||||
| #[macro_use] | #[macro_use] | ||||||
| extern crate rocket; | extern crate diesel; | ||||||
| #[macro_use] | #[macro_use] | ||||||
| extern crate diesel_migrations; | extern crate diesel_migrations; | ||||||
| #[macro_use] | #[macro_use] | ||||||
| extern crate diesel; | extern crate rocket; | ||||||
| 
 | 
 | ||||||
| use figment::{ | use figment::{ | ||||||
|     providers::{Env, Format, Yaml}, |     providers::{Env, Format, Yaml}, | ||||||
|  |  | ||||||
		Reference in New Issue
	
	
This flag is important for not using PIC.