问题:
海思Hi3518平台上边编译Opencv-3.3.0最后编译时出现“__sync_fetch_and_add_4”。
Log如下:
/opt/hisi-linux-nptl/arm-hisiv100-linux/bin/../lib/gcc/arm-hisiv100-linux-uclibcgnueabi/4.4.1/../../../../arm-hisiv100-linux-uclibcgnueabi/bin/ld: ../../bin/opencv_version: hidden symbol `__sync_fetch_and_add_4' in /opt/hisi-linux-nptl/arm-hisiv100-linux/bin/../lib/gcc/arm-hisiv100-linux-uclibcgnueabi/4.4.1/libgcc.a(linux-atomic.o) is referenced by DSO
/opt/hisi-linux-nptl/arm-hisiv100-linux/bin/../lib/gcc/arm-hisiv100-linux-uclibcgnueabi/4.4.1/../../../../arm-hisiv100-linux-uclibcgnueabi/bin/ld: final link failed: Nonrepresentable section on output
原因:
在连接时找不到__sync_fetch_and_add_4的定义,了解到是因为GCC版本过低问题,此函数是内联函数,用于数据的原子操作。
解决:
参照博文https://blog.youkuaiyun.com/leishengsheng/article/details/79723809,可下载相关的文件。 为了更加严谨,使用平台的编译器的AR和Randlib,暂时系统的AR和Randlib的软连接做如下修改:
$sudo rm /usr/bin/ar && sudo ln -s /opt/hisi-linux-nptl/arm-hisiv100-linux/bin/arm-hisiv100-linux-uclibcgnueabi-ar /usr/bin/ar
$sudo rm /usr/bin/ranlib && sudo ln -s /opt/hisi-linux-nptl/arm-hisiv100-linux/target/bin//arm-hisiv100nptl-linux-ranlib /usr/bin/ranlib
本人如果不做如上俩个修改,会出现如下提示:
libtool: link: ar cru .libs/liblinux-atomic.a .libs/linux-atomic.o
ar: `u' modifier ignored since `D' is the default (see `U') // 没做如上修改时,验证过这个ar是指向ubuntu自带的ar,并非是海思平台的arm-hisiv100-linux-uclibcgnueabi-ar,ranlib同理。
假设文件已经编译好,路径如下:/home/huangxiaowen/Project/SmartCamera/Hi3518_SDK_V1.0.A.0/fixlowgcc/linux-atomic.o
本人是在opencv-3.3.0/build目录里边编译,修改CMakeCache.txt文件里边的CMAKE_EXE_LINKER_FLAGS,如下:
CMAKE_EXE_LINKER_FLAGS:STRING= -lpthread -lrt /home/huangxiaowen/Project/SmartCamera/Hi3518_SDK_V1.0.A.0/fixlowgcc/linux-atomic.a
然后编译,发现编译OK了,opencv-3.3.0/build/bin目录下生成了opencv_version文件。其实应该是要改依赖的地方,赖了。
也可以手动编译(需要额外添加红色字体部分,即linux-atomic.a的路径),如下:
$cd /home/huangxiaowen/Project/SmartCamera/Hi3518_SDK_V1.0.A.0/opencv-3.3.0/build/apps/version && /usr/bin/cmake -E cmake_link_script CMakeFiles/opencv_version.dir/link.txt --verbose=1
/opt/hisi-linux-nptl/arm-hisiv100-linux/target/bin/arm-hisiv100nptl-linux-g++ -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winit-self -Wno-comment -fdiagnostics-show-option -fomit-frame-pointer -ffunction-sections -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG -DNDEBUG -lpthread -lrt CMakeFiles/opencv_version.dir/opencv_version.cpp.obj -o ../../bin/opencv_version ../../lib/libopencv_highgui.so ../../lib/libopencv_videoio.so ../../lib/libopencv_imgcodecs.so ../../lib/libopencv_imgproc.so ../../lib/libopencv_core.so /home/huangxiaowen/Project/SmartCamera/Hi3518_SDK_V1.0.A.0/fixlowgcc/.libs/liblinux-atomic.a
以上这么长的命令,是在opencv-3.3.0/build路径下make VERBOSE=1编译打印出来的,具体的编译指令要看自己的编译配置,编译输出信息做变换。
- 使用新版本GCC(如4.6.0)的文件linux-atomic.c重新生成linux-atomic.o文件。
- 修改连接脚本或者是手动编译。