带Rust的便携式二进制文件

时间:2014-10-05 12:14:39

标签: ld static-linking rust rust-cargo

我在使用rust构建可移植可执行文件时遇到了问题。

在Ubuntu上运行仅使用cargo build构建的可执行文件失败并显示

./test: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by ./test)

使用rustc ... -C link-args=-static构建无法正确链接(ld ./test的输出):

ld: error in ./test(.eh_frame); no .eh_frame_hdr table will be created.

除了在具有旧glibc版本的旧系统上构建之外,有没有办法解决这个问题?

2 个答案:

答案 0 :(得分:3)

Glibc没有静态链接(就像我们可能喜欢的那样,它可以防止这种情况发生)。因此,系统库(libstd等)始终依赖于构建它们的glibc版本。这就是为什么linux集群中的buildbots mozilla使用的是centos的旧版本。

请参阅https://github.com/rust-lang/rust/issues/9545https://github.com/rust-lang/rust/issues/7283

不幸的是,此时我认为除了确保构建一个比你要部署的glibc更旧的系统之外,没有其他解决办法。

答案 1 :(得分:1)

为避免GLIBC错误,您可以针对静态替代libc musl编译自己的Rust版本。

获取最新的稳定版musl并使用选项--disable-shared构建它:

$ mkdir musldist
$ PREFIX=$(pwd)/musldist
$ ./configure --disable-shared --prefix=$PREFIX

然后针对musl构建Rust:

$ ./configure --target=x86_64-unknown-linux-musl --musl-root=$PREFIX --prefix=$PREFIX

然后构建你的项目

$ echo 'fn main() { println!("Hello, world!"); }' > main.rs
$ rustc --target=x86_64-unknown-linux-musl main.rs
$ ldd main
    not a dynamic executable

有关详细信息,请查看文档的advanced linking部分。

正如原始文件中所述:

  

但是,您可能需要针对musl重新编译本机库   在他们被联系起来之前。

您也可以使用rustup

删除rustup.sh

安装的旧Rust
$ sudo /usr/local/lib/rustlib/uninstall.sh # only if you have 
$ rm $HOME/.rustup

安装rustup

$ curl https://sh.rustup.rs -sSf | sh
$ rustup default nightly  #just for ubuntu 14.04 (stable Rust 1.11.0 has linking issue)
$ rustup target add x86_64-unknown-linux-musl
$ export PATH=$HOME/.cargo/bin:$PATH
$ cargo new --bin hello && cd hello
$ cargo run --target=x86_64-unknown-linux-musl
$ ldd target/x86_64-unknown-linux-musl/debug/hello
    not a dynamic executable