Android.mk中预编译静态库链接顺序是否敏感?OpenCV链接报错求助
嘿,我来帮你捋清楚这两个问题——这在NDK+ROS+OpenCV的开发场景里确实是容易踩的坑。
一、Android.mk中预编译静态库的链接顺序是否敏感?
答案是绝对敏感!静态库的链接器(ld)是按从左到右的顺序处理库文件的:当它处理一个静态库时,只会提取当前能解决未定义符号的目标文件,处理完之后就不会再回头用后面的库去解决前面库的符号问题。举个例子,如果库A依赖库B里的函数,那你必须把A放在B的前面,不然链接器处理A的时候找不到B的符号,就会抛出undefined reference错误。
二、解决OpenCV静态库"undefined reference"错误的具体方案
结合你说的用ROS官网脚本生成文件、修改STLIBS里OpenCV包的情况,90%以上是链接顺序不对导致的。给你几个可行的解决思路:
先梳理OpenCV库的依赖链:OpenCV的静态库之间有明确的依赖关系,比如
opencv_highgui依赖opencv_imgproc和opencv_core,opencv_imgproc又依赖opencv_core。正确的链接顺序应该是依赖别人的库在前,被依赖的库在后。比如你应该写成:STLIBS += opencv_highgui opencv_imgproc opencv_core反过来的话,链接器先处理
opencv_core,之后遇到opencv_imgproc里引用opencv_core的符号时,不会再回去扫描opencv_core,自然就会报错。调整ROS生成的STLIBS变量顺序:你可以用Ctrl-F找到
STLIBS里的OpenCV相关条目,把它们的顺序改成符合依赖关系的样子。比如原来如果是opencv_core opencv_imgproc opencv_highgui,就把它反过来调整。用分组选项临时救急(不推荐长期用):如果实在搞不清依赖顺序,可以用链接器的
--start-group和--end-group选项把所有OpenCV库包裹起来,让链接器反复扫描这些库直到所有符号都被解决。在Android.mk里可以这么写:LOCAL_LDFLAGS += -Wl,--start-group LOCAL_STATIC_LIBRARIES += opencv_core opencv_imgproc opencv_highgui [其他OpenCV库] LOCAL_LDFLAGS += -Wl,--end-group不过这个方法会增加编译时间,所以还是建议尽量理清楚正确的依赖顺序。
内容的提问来源于stack exchange,提问作者CHEN Shixi

