迁移至Petalinux 2018后编译依赖自定义OpenCV2.4的CPP程序遇未定义引用问题
从你的描述来看,这个问题大概率是链接顺序错误导致的,再结合Petalinux版本升级带来的环境变化,我们可以一步步排查:
1. 修正链接器的依赖顺序(最关键的修复)
GCC链接器是按从左到右的顺序处理文件和库的:它会先处理目标文件,记录下未解析的符号,再从后续的库中查找这些符号。你的Makefile里把OpenCV库放在了目标文件$(APP_OBJS)前面,这就导致链接器处理库的时候还没看到需要这些符号的代码,自然不会把库中的符号关联进去。
修改你的$(APP)规则:
$(APP): $(APP_OBJS) $(CXX) -o $@ $(LDFLAGS) -L$(OPENCV_DIR)/lib $(APP_OBJS) $(OPENCV_LIBS) $(LDLIBS)
把$(APP_OBJS)移到$(OPENCV_LIBS)前面,让链接器先处理你的代码,再从OpenCV库中找需要的符号。
2. 确认交叉编译工具链的正确性
Petalinux 2018使用的工具链版本比2015更新,你需要确保$(CXX)是Petalinux提供的交叉编译器,而不是主机系统的g++。
可以显式指定交叉编译器(根据你的目标架构调整,比如ARM32位的工具链通常是arm-linux-gnueabihf-g++):
CC = arm-linux-gnueabihf-g++ CXX = arm-linux-gnueabihf-g++
另外,确保你是在Petalinux的构建环境中执行编译(比如先运行source petalinux_settings.sh),这样环境变量会自动配置正确的交叉编译工具链。
3. 检查OpenCV库的编译兼容性
虽然你用的是同一个OpenCV版本(2.4.11),但在Petalinux 2018环境下重新编译时,可能因为工具链变化导致库的兼容性问题:
- 检查OpenCV编译时的
CMakeCache.txt,确认WITH_NONFREE选项是开启的(因为你用到了nonfree模块); - 确认库文件的架构和目标平台匹配:你提供的
libopencv_stitching.so.2.4.11是32位ARM EABI5,这和Petalinux 2018的ARM目标平台是兼容的,但要确保所有OpenCV库都是用相同的工具链编译的; - 检查
$(OPENCV_DIR)/lib下的符号链接:比如libopencv_core.so应该指向libopencv_core.so.2.4.11,如果缺失符号链接,链接器可能找不到库。
4. 补充必要的系统库依赖
OpenCV的很多模块依赖系统库,比如线程库、动态链接库,你可以尝试把这些加到OPENCV_LIBS中:
OPENCV_LIBS = -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_contrib -lopencv_legacy -lopencv_flann -lpthread -ldl
5. 验证头文件与库路径的一致性
确认OPENCV_DIR指向的路径下:
include/opencv2目录包含所有你用到的头文件(比如core.hpp、nonfree/nonfree.hpp);lib目录包含所有你链接的库文件(比如libopencv_core.so.2.4.11)。
按照以上步骤调整后,重新运行petalinux-build -c appname应该就能解决链接错误了。
内容的提问来源于stack exchange,提问作者William

