HiGHS无法链接,出现“未定义引用”错误。

4

在 Arch Linux x86_64 上,使用 Rust 1.66.0 稳定版和 g++ 12.2.0。

我遇到了一个问题,无法链接 good-lp crate,并将其缩小到了间接依赖项 highs-sys,即使在我的代码之外也是如此。

这在最新的主分支(c785240)、v1.2.2 和 v0.2.1(我通过 good-lp 成功使用了数月)的干净检查中发生。因此,这不是 highs-sys 中的新问题,很可能是我的工具链的问题。

版本:

$ cargo --version
cargo 1.66.0 (d65d197ad 2022-11-15)
$ rustc --version
rustc 1.66.0 (69f9c33d7 2022-12-12)
$ cc --version
cc (GCC) 12.2.0
...
$ ld --version
GNU ld (GNU Binutils) 2.39.0
...

克隆和构建:

$ git clone --recursive https://github.com/rust-or/highs-sys
$ cd highs-sys
$ cargo build
...
    Finished dev [unoptimized + debuginfo] target(s) in 3m 35s
$ cargo test --lib
    Finished test [unoptimized + debuginfo] target(s) in 0.04s
     Running unittests src/lib.rs (target/debug/deps/highs_sys-96b0b941fcc31775)

running 2 tests
test bindgen_test_layout___fsid_t ... ok
test bindgen_test_layout_imaxdiv_t ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

目前一切都很好。问题出现在我们尝试使用生成的库时,即使是使用自己的集成测试:

$ cargo test --test test_highs_call
   Compiling highs-sys v1.2.2 (/tmp/highs-sys)
error: linking with `cc` failed: exit status: 1
  |
  = note: "cc" "-m64" "/tmp/rustccbaKBt/symbols.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.110gvlokoswtomfn.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.13y9v90q7e3dvfo2.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.17wo7aophf8in4vn.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.1cdkl7c2apbn7crn.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.1dj1sbwseam0n9ft.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.1hgigplg6qv30idz.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.1ms9q0du418ic26n.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.1tcgu3qw79kuuw1h.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.1vs3h8jyr2rojt51.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.20xdzk038hc30h4j.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.25ph4lcxn1xxn6fn.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.27am5w6h2agsxcl7.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.2djhnnv2jm2ibcl3.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.2i1j9l2lu5t0k0vu.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.2meo5gq21h6h8bqe.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.2ol9s57flfu167qp.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.2s2g91x597h8e2ey.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.2v1cfn4oct7skc3q.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.2v9apdn2isgwdl5q.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.2wpeqt6tzxghqi56.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.2yk7p7w6ixraj427.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.2z4b238c1zbjnij6.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.2zlr9mnhg9hyf02g.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.32cfoccwtdvhq06x.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.33nztruk7k2tts8x.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.3cvdzi91jork7mds.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.3fb9xf8nxxzcec41.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.3is6rgf4g5g16vl3.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.3s3dhxd64ny5tive.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.3wn5g0h8q5u3bxky.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.4150s6y93i5ma35t.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.4335j389sygn8m99.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.44i1r6id1s31acf1.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.4injouqsnun7hcvt.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.4nb66ozge3nmeuwq.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.4p2li2uv9dxcrx2d.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.4pz1m3mlzi8imskl.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.4tg55omun1u77yh3.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.4thto7zkdscqxses.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.4vrsyb4og25lcxo8.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.4z0e0rsh1apo67mr.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.50cxv68n1h5055a5.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.515xy9o2bj3al2ry.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.59no2g8u5zmbleot.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.5b574862nrupsals.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.5fu18wwg3p5nmrsh.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.5gi5ablibidmtrpd.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.kjht10drvblu37w.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.ugtef95uy6fok7q.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.xcjfvort5vhydtl.rcgu.o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.3mrzemp57wngq71t.rcgu.o" "-Wl,--as-needed" "-L" "/tmp/highs-sys/target/debug/deps" "-L" "/tmp/highs-sys/target/debug/build/highs-sys-21b14ce07e65289c/out/lib" "-L" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libtest-5678a62cd2e949f2.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgetopts-cafb712826ee2a26.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunicode_width-bb4ac1585c9c1153.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_std-69fab17bbe87f87e.rlib" "/tmp/highs-sys/target/debug/deps/libhighs_sys-addd17046a23d2a8.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-a11e3ca400b3ed09.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-3e82a3fced649488.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libobject-53a4330185981bcb.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libmemchr-2a8b57667b4852b5.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libaddr2line-9370462deca12c5a.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgimli-7da763b8d3620472.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-5bde27582a7f5af7.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_detect-1204e05b2d47e3d7.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-43987de2766b6923.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-d6499a0705316aa5.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libminiz_oxide-c9a27c90d8fbf11e.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libadler-8f159929cbfdfaf1.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-d2f1e8f3bb5cba95.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-9862f486269f442f.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-0434381f2f012ae2.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-68549403a59fd02e.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-4cefb2045f924a5b.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-272615fc4f10c50d.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-860619b93700e7eb.rlib" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-b73e5b4656934876.rlib" "-Wl,-Bdynamic" "-lstdc++" "-lgomp" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-znoexecstack" "-L" "/home/thomas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "/tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro,-znow" "-nodefaultlibs"
  = note: /usr/bin/ld: /tmp/highs-sys/target/debug/deps/test_highs_call-e669101ae4108d78.5gi5ablibidmtrpd.rcgu.o: in function `test_highs_call::highs_call':
          /tmp/highs-sys/tests/test_highs_call.rs:88: undefined reference to `Highs_lpCall'
          collect2: error: ld returned 1 exit status
          
  = note: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
  = note: use the `-l` flag to specify native libraries to link
  = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)

error: could not compile `highs-sys` due to previous error

另一个集成测试 test_highs_functions 也会出现类似的输出,但该文件中使用的所有 Highs_* 函数都未定义。
详细的构建输出:
$ cargo build --verbose --test test_highs_call
...
   Compiling highs-sys v1.2.2 (/tmp/highs-sys)
     Running `rustc --crate-name test_highs_call --edition=2018 tests/test_highs_call.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 --test -C metadata=e669101ae4108d78 -C extra-filename=-e669101ae4108d78 --out-dir /tmp/highs-sys/target/debug/deps -C incremental=/tmp/highs-sys/target/debug/incremental -L dependency=/tmp/highs-sys/target/debug/deps --extern highs_sys=/tmp/highs-sys/target/debug/deps/libhighs_sys-addd17046a23d2a8.rlib -L native=/tmp/highs-sys/target/debug/build/highs-sys-21b14ce07e65289c/out/lib`
...
... and then the above error again 

当手动运行rustc命令时,也会出现相同的错误。

手动运行cc命令失败,因为/tmp/rustccbaKBt/symbols.o已被删除,但如果我从命令行中删除它,则会再次出现相同的错误。

该符号在此文件中被标记为未定义(U):

$ nm target/debug/deps/test_highs_call-e669101ae4108d78.5gi5ablibidmtrpd.rcgu.o | grep Highs_lpCall
                 U Highs_lpCall

而且它在这个命令行中稍后被定义(T),正如它应该的那样:

$ nm /tmp/highs-sys/target/debug/deps/libhighs_sys-addd17046a23d2a8.rlib | grep Highs_lpCall
nm: lib.rmeta: no symbols
00000000 T Highs_lpCall

然而,所有符号都显示在地址00000000处,这对我这个外行人来说似乎很可疑。

老实说,我不确定这是否是高峰问题,但使用其他链接到C API的库对我来说都正常工作。

还尝试了使用gcc11,它仍然作为单独的软件包在存储库中可用:

$ export CC=/usr/bin/gcc-11
$ export CXX=/usr/bin/g++-11
$ export RUSTFLAGS="-C linker=/usr/bin/gcc-11"

这也会导致出现“未定义引用”错误。这很奇怪,因为我已经使用GCC 11有一段时间了。

但是当我将这些变量设置为使用clang而不是gcc时...

$ export CC=/usr/bin/clang
$ export CXX=/usr/bin/clang++
$ export RUSTFLAGS="-C link-arg=-fuse-ld=lld"

...然后它成功链接并且测试是绿色的!但这不是一个适当的解决方案。

你有什么更好的想法吗?

1个回答

2

原来这是由于链接时优化(LTO)造成的。

libhighs.a 是使用 GCC 通过 -flto -fno-fat-lto-objects 编译的 C++ 代码编译而成,导致它只向存档中发出 GCC 中间字节码,而不是实际的机器码。这些标志是通过其选项 INTERPROCEDURAL_OPTIMIZATION 由 CMake 添加的。

但是因为在链接时未启用 LTO,因此在链接时也没有生成任何机器码。通常 GNU 链接器会处理这个问题,但我认为当 libhighs.a 链接到一个 .rlib crate 时,字节码可能已经无法使用或丢失了(假设,未经检查)。而且我也不想在 Rust 代码中使用 GNU 链接器,因为那样我将失去在 Rust 代码上使用 LTO 的选项(Rust 总是使用 LLVM 位码)。

所以目前,我认为最好的解决方案是在C++ HiGHS构建中禁用LTO。我向highs-sys提交了一个问题,并参与了一个问题,以使LTO更加可选。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接