概述
今天在公司忙活的时候,协助同事排查了一个C/C++程序编译没问题,运行报undefined symbol的问题,故而博文记录,用于备忘
问题排查
程序代码使用CMake作为构建脚本,分析了CMakefile,发现需要链接的库在脚本里面都写上了,而且编译没报错,但是一运行就会报undefined symbol。
ldd命令查看程序链接的库,发现包含对应undefined symbol函数的动态库并没有链接上,然后去该程序的源码搜索,也没有发现undefined symbol函数的声明以及使用。接着分析各个链接库,逐个排查,发现该符号链接是在某个链接的.a库中使用,但是该.a文件也已经链接进来了,为啥对应函数的动态库链接不上?
结论
经过一通折腾,发现是CMake脚本的target_link_libraries顺序导致该问题。
原本的脚本顺序是
...
target_link_libraries(sample_add XX XX XX) //.so动态库
target_link_libraries(sample_add lib*.a) //.a静态库
...
因为当前编译的源码并没有声明或者使用到对应的undefined symbol函数,故而第一个target_link_libraries先链接动态库的时候,链接器直接将没有相关函数引用的动态库过滤掉了,然后第二个target_link_libraries链接静态库的时候,包含对应的undefined symbol函数,这就导致该函数没有获取到正确的地址引用,从而引起undefined symbol错误。
正确的写法
...
target_link_libraries(sample_add lib*.a XXX XXX)
...
至于为啥这两类库要分开写,我也不清楚同事。不过写代码有些时候就是会有这种人为非故意导致的问题,没啥办法避免…