< 返回版块

none 发表于 2024-04-27 16:14

Tags:link,静态链接

Mac系统下开发的一个程序,用 pkg-config crate 在 build.rs 里静态链接本地安装的库,build日志里能看到 -L /path/xxx -l static=xxx, 但生成的二进制文件里还是以动态库的形式依赖的,一旦本地库升级,二进制就因为找不到依赖的 dylib 而打不开,大家有遇到过这问题吗?

build.rs 里是这样依赖的: pkg_config::Config::new().statik(true).probe("xxx").unwrap();

评论区

写评论
作者 none 2024-04-28 15:24

刚试了 nightly 版本下也存在这个问题,已提 issue.

TinusgragLin 2024-04-28 13:15

不知道这算不算是 rustc 的 bug,在lib目录中同时有动态库和静态库的情况下,哪怕参数设置了静态链接,还是会去链接动态库。

我试了一下,这种情况下 rustc (1.77.2 (25ef9e3d8 2024-04-09))也是能正常静态链接的,当然这是我这边(linux)的情况,如果楼主这个可以在最新稳定版本下复现的话,应该可以提个 issue。

作者 none 2024-04-28 12:53

感谢你的回复。

我的 lib 目录里同时存在动态库 .dylib 和 静态库 .a 文件,我尝试了把 .dylib 重命名后,出来的可执行文件就是静态链接的了。

不知道这算不算是 rustc 的 bug,在lib目录中同时有动态库和静态库的情况下,哪怕参数设置了静态链接,还是会去链接动态库。

--
👇
TinusgragLin: (补充:看了一下 ldd 的输出,没有看到 libcrypto,应该是静态链接了)

TinusgragLin 2024-04-28 12:16

(补充:看了一下 ldd 的输出,没有看到 libcrypto,应该是静态链接了)

TinusgragLin 2024-04-28 12:13

我猜大概率是因为只有 .so 动态链接库,所以回退到动态链接了,我自己试了一下,openssl 3.3.0 的源码 ./Configure --no-shared && make 之后,可以得到 libcrypto.a,然后我用这个程序试了一下:

use std::ffi::{c_char, CStr};

extern "C" {
    fn ossl_dh_gen_type_id2name(id: i32) -> *const c_char;
}

fn main() {
    let ptr = unsafe { ossl_dh_gen_type_id2name(0) };
    let str = unsafe { CStr::from_ptr(ptr) };
    println!("Hello, {str:?}");
}

可以通过 rustc -L /home/me/Downloads/openssl-3.3.0/ -l static=crypto src/main.rs 编译,运行可以得到:

Hello, "generator"

看起来没问题。

作者 none 2024-04-28 11:34

好像和 pkg-config 没啥关系,我写了个单文件测试程序静态链接本地 libcrypto 库,用 rustc 编译:

rustc main.rs -L native='/usr/local/Cellar/openssl@3/3.3.0/lib' -l static=crypto

结果出来的可执行文件,用 otool -L main 工具可以看到是动态链接 libcrypto 库的

不知道是不是编译参数写的不对。。。

TinusgragLin 2024-04-27 17:56

楼主可以提供更多的信息吗?这样即使大家之前没遇到过这个问题,也可以帮助你一起分析。我并不是这方面的老手,如果是我的话,可能会先看看 ldd 的输出是否可以确认动态链接的就是 xx 库,再手动看看 pkg-config --libs xx --cflags --static 的输出,或者 xx 库 .pc 文件的内容,再看看系统中 xx 库是不是提供了 .a 文件,如果只有 .so 的话,不知道是不是会回退到动态链接?

1 共 7 条评论, 1 页