【问题标题】:Statically linking a binary that uses regex_macros静态链接使用 regex_macros 的二进制文件
【发布时间】:2015-04-02 08:45:43
【问题描述】:

我刚刚意识到,当我使用 regex_macros crate 时,通过 Cargo 创建的 Rust 二进制文件是动态链接的。这有点问题,因为当我更新到regex_macros 的较新版本时,创建的二进制文件将停止工作。

有办法解决吗?

这是一个最小的例子:

#![feature(plugin)]
#[plugin]
extern crate regex_macros;


fn main() {}

编译它并查看链接的内容会发现:

uh@macaron:~/linking-test (master)$ otool -L target/linking-test
target/linking-test:
    /Users/uh/linking-test/target/deps/libregex_macros-bdbdbfedad0748ac.dylib (compatibility version 0.0.0, current version 0.0.0)
    x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/librustc-4e7c5e5c.dylib (compatibility version 0.0.0, current version 0.0.0)
    x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/libflate-4e7c5e5c.dylib (compatibility version 0.0.0, current version 0.0.0)
    x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/libgetopts-4e7c5e5c.dylib (compatibility version 0.0.0, current version 0.0.0)
    x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/librustc_back-4e7c5e5c.dylib (compatibility version 0.0.0, current version 0.0.0)
    x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/libsyntax-4e7c5e5c.dylib (compatibility version 0.0.0, current version 0.0.0)
    x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/libfmt_macros-4e7c5e5c.dylib (compatibility version 0.0.0, current version 0.0.0)
    x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/libarena-4e7c5e5c.dylib (compatibility version 0.0.0, current version 0.0.0)
    x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/libterm-4e7c5e5c.dylib (compatibility version 0.0.0, current version 0.0.0)
    x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/libgraphviz-4e7c5e5c.dylib (compatibility version 0.0.0, current version 0.0.0)
    x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/librbml-4e7c5e5c.dylib (compatibility version 0.0.0, current version 0.0.0)
    x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/libserialize-4e7c5e5c.dylib (compatibility version 0.0.0, current version 0.0.0)
    x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/liblog-4e7c5e5c.dylib (compatibility version 0.0.0, current version 0.0.0)
    x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/librustc_llvm-4e7c5e5c.dylib (compatibility version 0.0.0, current version 0.0.0)
    x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/libstd-4e7c5e5c.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)
    /usr/lib/libedit.3.dylib (compatibility version 2.0.0, current version 3.0.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)

如您所见,第一个链接的 dylib 具有进入项目所在目录的绝对路径,即使执行 cargo clean 也可能会破坏可执行文件。

【问题讨论】:

  • 哎呀,你是对的。
  • 您能否展示一个包含足够信息的最小可重现示例,以便其他人重现您的问题?
  • 好主意。我会试着看看我是否能想出一个最小的例子。我在编译我的项目(github.com/ujh/iomrascalai)时注意到了它,但是那个已经很大了,当然不适合调试。
  • 尝试使用#[plugin] #[no_link] extern crate regex_macros;
  • 是的,它就在文档中……谢谢! :)

标签: rust rust-cargo


【解决方案1】:

这里缺少的微小细节是#[no_link],正如BurntSushi5 的评论中所述。所以把代码改成:

#![feature(plugin)]
#[plugin] #[no_link] extern crate regex_macros;


fn main() {}

将静态链接 regex_macros crate。

【讨论】:

  • "静态链接 regex_macros crate" - 一个名为 #[no_link] 的属性不应该根本不链接它吗?
【解决方案2】:

我认为您误认为二进制文件是动态链接的(至少默认情况下不是)。

我刚刚使用 Cargo (cargo new --bin foo) 创建了一个全新的二进制项目,添加了 regex crate 并在源代码中使用它。我编译了二进制文件,然后使用otool 列出了动态库(我在 OS X 上):

$ otool -L target/statik
target/statik:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

这似乎表明唯一的动态链接是核心系统库(在 Linux 上,我相信它是 glibc)。

【讨论】:

  • 当我使用我的项目 (github.com/ujh/iomrascalai) 时,我会得到很多输出,而你只能得到那一行。我将尝试提出一个最小的例子......
猜你喜欢
  • 2015-02-27
  • 1970-01-01
  • 1970-01-01
  • 2011-02-13
  • 1970-01-01
  • 2016-04-22
  • 1970-01-01
  • 2015-03-19
  • 1970-01-01
相关资源
最近更新 更多