如何排查C++链接库之间链接顺序问题

今天浪费了8个小时排查了一个 C++ 库编译后依赖的cuda符号找不到的问题。后面在凑巧的情况下在 链接库的地方加了一个可能会用到的库,结果就通过了。但是凑巧肯定是有更深刻的原因,再反复验证,实际上是这样的:

link(A)
link(B)
link(mm)

我加的 mm 库后链接就通过了。但是 mm 是没有理由要加的。另外一个人这样写也不行

link(mm)
link(A)
link(B)

这是一个奇怪的问题,我就去看了 mm 库里做了啥,就是没看出有啥特别的。但是A实际上是一组link库的变量名,我再打印了 A,发现A里面就含有 mm。

于是我改成

link(B)
link(A)

就通过了,不需要手工加 mm

这个解决了后,我感觉获得了一个经验,B以后应该都写在A之前。

但是,这是知识么?这他妈是老中医。于是我又去问了下GPT,如何判断多个链接库之间的依赖顺序。GPT这个很复杂,不能那么容易搞定,但是推荐我可以用 ldd 命令先看下一个库链接了那些其他库。

于是我就尝试了下 ldd mm, 它就列出了

  libxxx1=> not found
  libxxx2=-> not found 
  ...

这下就清楚多了,虽然不是自动的,但是在分析的时候判断就容易多了,有依据了,不是靠猜来解决问题了。

如果我有时间,还可以写一个Python脚本来做这个事情。如果有很多A和小库的详细映射和经验依赖关系配置。那么当需要多个链接的时候,也是可以快速给出更靠谱的顺序分析建议。不需要 100%解决问题,如果能 90%就可以节省大量时间。

毕竟 make build 下都要等好久。

附:GCC 关于链接顺序的说明:https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html

-l library

Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX compliance and is not recommended.)

The -l option is passed directly to the linker by GCC. Refer to your linker documentation for exact details. The general description below applies to the GNU linker.

The linker searches a standard list of directories for the library. The directories searched include several standard system directories plus any that you specify with -L.

Static libraries are archives of object files, and have file names like liblibrary.a. Some targets also support shared libraries, which typically have names like liblibrary.so. If both static and shared libraries are found, the linker gives preference to linking with the shared library unless the -static option is used.

It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, ‘foo.o -lz bar.o’ searches library ‘z’ after file foo.o but before bar.o. If bar.o refers to functions in ‘z’, those functions may not be loaded.
`

--end--

posted @ 2023-09-21 00:13  ffl  阅读(72)  评论(0编辑  收藏  举报