Skip to content

Commit 9ea2f74

Browse files
authored
feat: implement arm64 & amd64 native images (#13)
* Make + Docker: Implement arm64 & amd64 native images This PR updates the Docker image such that it can be successfully built and used as either a linux/amd64 image or a linux/amd64 image. The Makefile has been given a new `buildx` command to utilise Docker's multi-platorm building capability to build and push (!!!) both images. This is separate from the `build` command as since one of the arch's will be compiled under emulation, and therefore `buildx` can take a long time to complete (took ~2h on my 8 core old gaming laptop). Some other things added along the way: * Makefile take REPOSITORY and TAG arguments, such that building local images and testing is easier to do. Out of scope: * Haven't integrated it with GitHub actions, as I'm not that familiar with it, but figured this was a good first step. Known issues: * For arm64 images, can't get linux-musl test in `make test` to pass. Wondering if we need to explicitly install the amd64 version via apt? Have yet to experiment. Cross compiling to `x86_64-apple-darwin` works perfectly though on arm64 host. Work on #12 * Review: Get musl tests working. * Support for aarch64-apple-darwin Resolves #12
1 parent 8e3c65e commit 9ea2f74

File tree

3 files changed

+57
-11
lines changed

3 files changed

+57
-11
lines changed

Makefile

+32-7
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,34 @@
1+
REPOSITORY ?= joseluisq
2+
TAG ?= latest
3+
4+
15
build:
26
docker build \
3-
-t joseluisq/rust-linux-darwin-builder:latest \
7+
-t $(REPOSITORY)/rust-linux-darwin-builder:$(TAG) \
48
-f docker/Dockerfile .
59
.PHONY: build
610

11+
12+
# Use to build both arm64 and amd64 images at the same time.
13+
# WARNING! Will automatically push, since multi-platform images are not available locally.
14+
# Use `REPOSITORY` arg to specify which container repository to push the images to.
15+
buildx:
16+
docker run --privileged --rm tonistiigi/binfmt --install linux/amd64,linux/arm64
17+
docker buildx create --name darwin-builder --driver docker-container --bootstrap
18+
docker buildx use darwin-builder
19+
docker buildx build \
20+
--platform linux/amd64,linux/arm64 \
21+
--push \
22+
-t $(REPOSITORY)/rust-linux-darwin-builder:$(TAG) \
23+
-f docker/Dockerfile .
24+
25+
.PHONY: buildx
26+
727
test:
828
@docker run --rm -it \
929
-v $(PWD):/drone/src \
1030
-w /drone/src \
11-
joseluisq/rust-linux-darwin-builder:latest \
31+
$(REPOSITORY)/rust-linux-darwin-builder:$(TAG) \
1232
make test-ci
1333
.PHONY: test
1434

@@ -17,14 +37,19 @@ test-ci:
1737
@rustc -vV
1838
@echo
1939
@cd tests/hello-world \
20-
&& echo "Compiling application (linux-musl x86_64)..." \
21-
&& cargo build --release --target x86_64-unknown-linux-musl \
22-
&& du -sh target/x86_64-unknown-linux-musl/release/helloworld \
23-
&& ./target/x86_64-unknown-linux-musl/release/helloworld \
40+
&& echo "Compiling application (linux-musl $$(uname -m))..." \
41+
&& cargo build --release --target "$$(uname -m)-unknown-linux-musl" \
42+
&& du -sh target/$$(uname -m)-unknown-linux-musl/release/helloworld \
43+
&& ./target/$$(uname -m)-unknown-linux-musl/release/helloworld \
2444
&& echo \
2545
&& echo "Compiling application (apple-darwin x86_64)..." \
2646
&& cargo build --release --target x86_64-apple-darwin \
27-
&& du -sh target/x86_64-apple-darwin/release/helloworld
47+
&& du -sh target/x86_64-apple-darwin/release/helloworld \
48+
&& echo \
49+
&& echo "Compiling application (apple-darwin aarch64)..." \
50+
&& cargo build --release --target aarch64-apple-darwin \
51+
&& du -sh target/aarch64-apple-darwin/release/helloworld
52+
2853
.ONESHELL: test-ci
2954

3055
promote:

docker/Dockerfile

+14-3
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,10 @@ ENV PATH=/root/.cargo/bin:/usr/local/musl/bin:/usr/local/sbin:/usr/local/bin:/us
9191
# `--target` to musl so that our users don't need to keep overriding it manually.
9292
RUN set -eux \
9393
&& curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain $TOOLCHAIN \
94-
&& rustup target add x86_64-unknown-linux-musl \
94+
&& rustup target add $(uname -m)-unknown-linux-musl \
9595
&& rustup target add armv7-unknown-linux-musleabihf \
9696
&& rustup target add x86_64-apple-darwin \
97+
&& rustup target add aarch64-apple-darwin \
9798
&& true
9899
ADD docker/cargo-config.toml /root/.cargo/config
99100

@@ -112,17 +113,23 @@ RUN set -eux \
112113
# component. It's possible that this will cause bizarre and terrible things to
113114
# happen. There may be "sanitized" header
114115
RUN set -eux \
116+
&& dpkgArch="$(dpkg --print-architecture)" \
117+
&& case "${dpkgArch##*-}" in \
118+
amd64) config='';; \
119+
arm64) config='-mno-outline-atomics';; \
120+
*) echo >&2 "unsupported architecture: ${dpkgArch}"; exit 1 ;; \
121+
esac \
115122
&& echo "Building OpenSSL ${OPENSSL_VERSION}..." \
116123
&& ls /usr/include/linux \
117124
&& mkdir -p /usr/local/musl/include \
118125
&& ln -s /usr/include/linux /usr/local/musl/include/linux \
119-
&& ln -s /usr/include/x86_64-linux-gnu/asm /usr/local/musl/include/asm \
126+
&& ln -s "/usr/include/$(uname -m)-linux-gnu/asm" /usr/local/musl/include/asm \
120127
&& ln -s /usr/include/asm-generic /usr/local/musl/include/asm-generic \
121128
&& cd /tmp \
122129
&& curl -LO "https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz" \
123130
&& tar xvzf "openssl-${OPENSSL_VERSION}.tar.gz" \
124131
&& cd "openssl-${OPENSSL_VERSION}" \
125-
&& env CC=musl-gcc ./Configure no-shared no-zlib -fPIC --prefix=/usr/local/musl -DOPENSSL_NO_SECURE_MEMORY linux-x86_64 \
132+
&& env CC=musl-gcc ./Configure no-shared no-zlib -fPIC --prefix=/usr/local/musl -DOPENSSL_NO_SECURE_MEMORY ${config} "linux-$(uname -m)" \
126133
&& env C_INCLUDE_PATH=/usr/local/musl/include/ make depend \
127134
&& env C_INCLUDE_PATH=/usr/local/musl/include/ make -j$(nproc) \
128135
&& make -j$(nproc) install_sw \
@@ -161,9 +168,13 @@ RUN set -eux \
161168
&& true
162169

163170
ENV X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_DIR=/usr/local/musl/ \
171+
AARCH64_UNKNOWN_LINUX_MUSL_OPENSSL_DIR=/usr/local/musl/ \
164172
X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_STATIC=1 \
173+
AARCH64_UNKNOWN_LINUX_MUSL_OPENSSL_STATIC=1 \
165174
PQ_LIB_STATIC_X86_64_UNKNOWN_LINUX_MUSL=1 \
175+
PQ_LIB_STATIC_AARCH64_UNKNOWN_LINUX_MUSL=1 \
166176
PG_CONFIG_X86_64_UNKNOWN_LINUX_GNU=/usr/bin/pg_config \
177+
PG_CONFIG_AARCH64_UNKNOWN_LINUX_GNU=/usr/bin/pg_config \
167178
PKG_CONFIG_ALLOW_CROSS=true \
168179
PKG_CONFIG_ALL_STATIC=true \
169180
LIBZ_SYS_STATIC=1 \

docker/cargo-config.toml

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
[build]
2-
# Target musl-libc by default when running Cargo.
2+
# Target musl-libc by default when running Cargo
33
target = "x86_64-unknown-linux-musl"
44

55
[target.armv7-unknown-linux-musleabihf]
66
linker = "arm-linux-gnueabihf-gcc"
77

8+
[target.aarch64-unknown-linux-gnu]
9+
linker = "aarch64-linux-gnu-gcc"
10+
11+
[target.aarch64-unknown-linux-musl]
12+
linker = "aarch64-linux-gnu-gcc"
13+
814
[target.x86_64-apple-darwin]
915
linker = "x86_64-apple-darwin21.4-clang"
1016
ar = "x86_64-apple-darwin21.4-ar"
17+
18+
[target.aarch64-apple-darwin]
19+
linker = "arm64e-apple-darwin21.4-clang"
20+
ar = "arm64e-apple-darwin21.4-ar"

0 commit comments

Comments
 (0)