最近在用Rust语言写一个轻量级的数据同步工具(DP),由于是在MacBook Pro M2上做的开发,通过cargo build –release编译后的执行文件,无法在x86_64架构的Linux系统上运行。虽然rustup提供了交叉编译的能力,但开发环境安装不同架构平台的工具链,很容易导致混乱,于是我决定通过Dockerfile来进行DP的”交叉”编译
静态链接
通过使用x86_64-musl镜像,构建静态链接执行文件
1 2 3 4 5 6 7 8 9 10
FROM messense/rust-musl-cross:x86_64-musl as build RUN USER=root cargo new --bin ep-dp WORKDIR /ep-dp COPY ./Cargo.lock ./Cargo.lock COPY ./Cargo.toml ./Cargo.toml COPY ./src ./src RUN cargo build --release
FROM scratch AS export-stage COPY --from=build /ep-dp/target/x86_64-unknown-linux-musl/release/ep-dp .
导出构建文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
DOCKER_BUILDKIT=1 docker build -f Dockerfile . --output . && mv ep-dp ep-dp:musl # 编译报错如下 # error: failed to run custom build commandfor `openssl-sys v0.9.90` # ... # run pkg_config fail: pkg-config has not been configured to support cross-compilation. # ... # Could not find directory of OpenSSL installation, and this `-sys` crate cannot # proceed without this knowledge. If OpenSSL is installed and this crate had # trouble finding it, you can set the `OPENSSL_DIR` environment variable for the # compilation process. # 解决方法 # 在Cargo.toml中添加 openssl = { version = "0.10", features = ["vendored"] }
1 2 3
# on centos [root@m dp]# ldd ep-dp:musl statically linked
FROM messense/rust-musl-cross:x86_64-musl as build RUN USER=root cargo new --bin ep-dp WORKDIR /ep-dp COPY ./Cargo.lock ./Cargo.lock COPY ./Cargo.toml ./Cargo.toml COPY ./src ./src RUN cargo build --release
[root@m dp]# ls -lah ep-dp:musl -rwxr-xr-x 1 x x 15M Aug 7 09:44 ep-dp:musl [root@m dp]# ls -lah ep-dp:centos -rwxr-xr-x 1 x x 8.6M Aug 7 16:04 ep-dp:centos
系统兼容
静态链接执行文件拥有更好的兼容性,而动态链接执行文件的运行环境需要包含所需依赖库
1 2 3 4 5 6 7 8 9 10 11 12 13
# on Alpine [root@x dp]# ldd ep-dp:centos /lib64/ld-linux-x86-64.so.2 (0x7ffffff65000) libz.so.1 => /lib/libz.so.1 (0x7fffff4c5000) Error loading shared library libgcc_s.so.1: No such file or directory (needed by ep-dp:centos) librt.so.1 => /lib64/ld-linux-x86-64.so.2 (0x7ffffff65000) libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7ffffff65000) libm.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7ffffff65000) libdl.so.2 => /lib64/ld-linux-x86-64.so.2 (0x7ffffff65000) libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7ffffff65000)