【发布时间】:2016-11-19 16:06:05
【问题描述】:
我有一个项目依赖于 Hyper 和 Diesel,因此依赖于原生库 OpenSSL 和 libpq。该项目基于 nightly Rust 构建,因为它使用编译器插件。
我目前的尝试是在 Docker 容器上构建。我有 MUSL libc 和库 make'd 并以前缀 /usr/local/musl 安装。我使用以下命令运行cargo:(不确定某些选项是否是多余的,我对编译器链不太熟悉,甚至不确定它们是否最终到达链接器,但我必须试试吧。)
LDFLAGS="-static -L/usr/local/musl/lib" \
LD_LIBRARY_PATH=/usr/local/musl/lib:$LD_LIBRARY_PATH \
CFLAGS="-I/usr/local/musl/include" \
PKG_CONFIG_PATH=/usr/local/musl/lib/pkgconfig \
cargo build --release --target=x86_64-unknown-linux-musl
当我ldd 生成的文件时,它会显示:
$ ldd server
linux-vdso.so.1 (0x00007fffb878e000)
libpq.so.5 => /usr/local/musl/lib/libpq.so.5 (0x00007f4d730e7000)
libssl.so.1.0.0 => /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0 (0x00007f4d72e82000)
libcrypto.so.1.0.0 => /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0 (0x00007f4d72a85000)
libc.so => /usr/local/musl/lib/libc.so (0x00007f4d727f6000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f4d725f2000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4d72246000)
/lib/ld64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x000055e2124a2000)
有所有动态链接的东西,有些甚至使用“x86_64-linux-gnu”链!出了什么问题?
我可以毫无问题地制作静态链接的简单纯 Rust 项目。 ldd 说它们是静态链接的,它们运行没有问题,不像我遇到问题的可执行文件。
当我将 --verbose 与 Cargo 一起使用时,我得到了以下 rustc 命令,它实际上构建了可执行文件:http://pastebin.com/ywv0zNBK(糟糕,那个有自定义的 outdir 和 -Z print-link-args,由我添加)
添加print-link-args 标志,我得到以下链接器命令:http://pastebin.com/Aw43qd7h
如何让cargo 或rustc 相信我想要一个静态二进制文件?
【问题讨论】:
-
我很确定答案是:“你不会,很容易”。您需要将 libpq 和 OpenSSL 重新构建为静态库(并链接到 MUSL?)。然后,您必须弄清楚如何更改相应的 Rust 库以链接到静态版本。我有 70% 的把握,但不完全是。
-
问题是,我确实针对 MUSL 重建了它们,前缀为
/usr/local/musl。而且我试图通过尝试正确设置环境来让相应的库链接到静态版本,但显然我失败了。你说的好像我必须自己修改库,是你的意思吗? -
我的意思是,一旦你编译了 C 库的 MUSL 版本(做得很好!),你将不得不检查每个 Rust 绑定以弄清楚如何更改它们的链接方式并什么。例如,openssl has environment variables。
-
感谢有关环境变量的指针!这是一个重要的线索。
标签: rust static-linking rust-cargo musl