OpenCV2.4.4 移植到arm平台过程详解,及 __extern_inline 错误的解决方案
2013-08-01 18:28
876 查看
在做porting 移植移植Opencv之前, 需要提前了解下CMAKE cross compiling的工作原理。 因为现在opencv 自从2.0版本后采用 cmake编译, 而以前的版本用的是autotools。 编译的方式发送了变化, 所以看下cmake 还是很有必要的。 这里可以参考下: http://www.vtk.org/Wiki/CMake_Cross_Compiling
1/ 环境配置好了, cmake -DCMAKE_TOOLCHAIN_FILE=mytoolchain.cmake . , 这一步可以生成makefile文件。 其中 mytoolchain.cmake 文件是自己写的,可以参考上面提供的网址的内容。
2/ cmake执行成功后,执行make命令。 在编译 gl_core_3_1.cpp 这个文件的时候,会提示 __extern_inline 错误。 下面就是我的解决方案:
9.在 /home/sundh/opencv-2.4.4/build/modules/core/precomp.hpp 里面加代码:
运行命令编译, 发现 没有出现 #error “_extern_inline define” 和 #error “_extern_inline“ 的错误。可见,修改precomp.hpp 文件对编译是完全没有影响的,感觉编译根本就没有包含/home/sundh/opencv-2.4.4/build/modules/core/precomp.hpp 这个文件一样。 验证我们的猜想,删除/home/sundh/opencv-2.4.4/build/modules/core/precomp.hpp文件,
然后用 arm-v7a15v3r1-linux-gnueabi-g++ … -include"/home/sundh/opencv-2.4.4/build/modules/core/precomp.hpp"-Winvalid-pch -o CMakeFiles/opencv_core.dir/src/gl_core_3_1.cpp.o -c/home/sundh/opencv-2.4.4/modules/core/src/gl_core_3_1.cpp,居然不报找不到precomp.hpp
文件的错误。
10.额, 问题很严重了哦。 重新make发现 生成了precom.hpp 和 precomp.hpp.gch 。 precomp.hpp.gch这个东西是 gcc的一种预编译技术——预编译头技术,就是将头文件先编译成一种二进制中间格式,以供后续编译使用的。
gcc在编译过程中会自动查找相应的.gch文件,并且自动检测其可用性,如果不可用,gcc会给出警告,然后使用对应的.h文件,抛弃当前.gch。
噢,这下明白了一点, arm-v7a15v3r1-linux-gnueabi-g++ … -include"/home/sundh/opencv-2.4.4/build/modules/core/precomp.hpp"-Winvalid-pch -o CMakeFiles/opencv_core.dir/src/gl_core_3_1.cpp.o -c/home/sundh/opencv-2.4.4/modules/core/src/gl_core_3_1.cpp运行时,真正用到的是
*.gch 文件, 相应的头文件是可有可无的。 呵呵,
11. 那我把precomp.hpp.gch删除掉,编译就会用到precom.hpp文件了。 尝试了下,是这样的。在precom.hpp文件中添加log, 是能打出来的, 但执行arm-v7a15v3r1-linux-gnueabi-g++…-include "/home/sundh/opencv-2.4.4/build/modules/core/precomp.hpp"-Winvalid-pch
-o CMakeFiles/opencv_core.dir/src/gl_core_3_1.cpp.o -c/home/sundh/opencv-2.4.4/modules/core/src/gl_core_3_1.cpp却不报错了。 问题有来了? 看来precomp.hpp.gch不止包含了precom.hpp的文件信息, 而且还包含了其他的一些信息。 看来要研究precom.hpp 如何生存precomp.hpp.gch文件了。
12. precom.hpp 如何生存precomp.hpp.gch?? 怎么生存的。 测试发现做cmake … 这步的时候,生存了precom.hpp 如何生存precomp.hpp.gch 这个文件夹。 那具体生成的命令是什么呢?
用 cmake … --trace ..可以把cmake生存makefile的编译过程显示出来,而且是超级详细哦。呵呵,一下子感觉到前面的路,豁然开朗。保存这样的信息到文件A中。
13.在文件A中查找关键字precomp.hpp.gch, 可以看到这样的命令:
/home/sundh/opencv-2.4.4/cmake/OpenCVPCHSupport.cmake(117): SET(_command ${CMAKE_CXX_COMPILER} ${_compile_FLAGS} -x c++-header -o/home/sundh/opencv-2.4.4/build/modules/core/precomp.hpp.gch/opencv_core_Release.gch/home/sundh/opencv-2.4.4/build/modules/core/precomp.hpp
) 原来是在这里通过这条命令生成的,接着查找_compile_FLAGS的值是什么,就这样。一直可以找到
14,经过很长时间的调整查找,可以找到这样的命令:
/usr/local/share/cmake-2.8/Modules/FindZLIB.cmake(56): FIND_PATH(ZLIB_INCLUDE_DIR NAMES zlib.h ${${search}}PATH_SUFFIXES include
)
/usr/local/share/cmake-2.8/Modules/FindZLIB.cmake(57): FIND_LIBRARY(ZLIB_LIBRARY NAMES ${ZLIB_NAMES} ${${search}}PATH_SUFFIXES lib
)
CMakeList.txt 里面会调用 cmake里面的 FindZLIB.cmake文件,
这个文件是cmake自己搞的一套查找zlib头文件和库文件的脚本。PATH_SUFFIXES后面是什么东东?呀,被震惊到了。居然要找路径中包含
include和 lib
的文件夹。也就是说你的zlib库文件和头文件要放到lib和include
的文件夹下,
不然是找不到的。
15 .回想下,因为arm编译工具链把这个zlib给剪辑掉了,所以zlib库是我自己编译的。我给zlib头文件和库文件的文件名都是随便取的一个,与include/lib不相符.
额,被cmake内部的配置脚本给阴了。
16. 总结: cmake中的FindZLIB.cmake脚本要查找zlib的头文件和库文件,如果找不到,就会到/usr/include和/usr/lib下面找。这时肯定是能找到的,结果就把
/usr/include路径放到头文件的搜索路径里面去。这时候进行arm编译的时候,就会使用/usr/include下面的头文件。结果就会出现很奇葩的错误。
1/ 环境配置好了, cmake -DCMAKE_TOOLCHAIN_FILE=mytoolchain.cmake . , 这一步可以生成makefile文件。 其中 mytoolchain.cmake 文件是自己写的,可以参考上面提供的网址的内容。
2/ cmake执行成功后,执行make命令。 在编译 gl_core_3_1.cpp 这个文件的时候,会提示 __extern_inline 错误。 下面就是我的解决方案:
9.在 /home/sundh/opencv-2.4.4/build/modules/core/precomp.hpp 里面加代码:
运行命令编译, 发现 没有出现 #error “_extern_inline define” 和 #error “_extern_inline“ 的错误。可见,修改precomp.hpp 文件对编译是完全没有影响的,感觉编译根本就没有包含/home/sundh/opencv-2.4.4/build/modules/core/precomp.hpp 这个文件一样。 验证我们的猜想,删除/home/sundh/opencv-2.4.4/build/modules/core/precomp.hpp文件,
然后用 arm-v7a15v3r1-linux-gnueabi-g++ … -include"/home/sundh/opencv-2.4.4/build/modules/core/precomp.hpp"-Winvalid-pch -o CMakeFiles/opencv_core.dir/src/gl_core_3_1.cpp.o -c/home/sundh/opencv-2.4.4/modules/core/src/gl_core_3_1.cpp,居然不报找不到precomp.hpp
文件的错误。
10.额, 问题很严重了哦。 重新make发现 生成了precom.hpp 和 precomp.hpp.gch 。 precomp.hpp.gch这个东西是 gcc的一种预编译技术——预编译头技术,就是将头文件先编译成一种二进制中间格式,以供后续编译使用的。
gcc在编译过程中会自动查找相应的.gch文件,并且自动检测其可用性,如果不可用,gcc会给出警告,然后使用对应的.h文件,抛弃当前.gch。
噢,这下明白了一点, arm-v7a15v3r1-linux-gnueabi-g++ … -include"/home/sundh/opencv-2.4.4/build/modules/core/precomp.hpp"-Winvalid-pch -o CMakeFiles/opencv_core.dir/src/gl_core_3_1.cpp.o -c/home/sundh/opencv-2.4.4/modules/core/src/gl_core_3_1.cpp运行时,真正用到的是
*.gch 文件, 相应的头文件是可有可无的。 呵呵,
11. 那我把precomp.hpp.gch删除掉,编译就会用到precom.hpp文件了。 尝试了下,是这样的。在precom.hpp文件中添加log, 是能打出来的, 但执行arm-v7a15v3r1-linux-gnueabi-g++…-include "/home/sundh/opencv-2.4.4/build/modules/core/precomp.hpp"-Winvalid-pch
-o CMakeFiles/opencv_core.dir/src/gl_core_3_1.cpp.o -c/home/sundh/opencv-2.4.4/modules/core/src/gl_core_3_1.cpp却不报错了。 问题有来了? 看来precomp.hpp.gch不止包含了precom.hpp的文件信息, 而且还包含了其他的一些信息。 看来要研究precom.hpp 如何生存precomp.hpp.gch文件了。
12. precom.hpp 如何生存precomp.hpp.gch?? 怎么生存的。 测试发现做cmake … 这步的时候,生存了precom.hpp 如何生存precomp.hpp.gch 这个文件夹。 那具体生成的命令是什么呢?
用 cmake … --trace ..可以把cmake生存makefile的编译过程显示出来,而且是超级详细哦。呵呵,一下子感觉到前面的路,豁然开朗。保存这样的信息到文件A中。
13.在文件A中查找关键字precomp.hpp.gch, 可以看到这样的命令:
/home/sundh/opencv-2.4.4/cmake/OpenCVPCHSupport.cmake(117): SET(_command ${CMAKE_CXX_COMPILER} ${_compile_FLAGS} -x c++-header -o/home/sundh/opencv-2.4.4/build/modules/core/precomp.hpp.gch/opencv_core_Release.gch/home/sundh/opencv-2.4.4/build/modules/core/precomp.hpp
) 原来是在这里通过这条命令生成的,接着查找_compile_FLAGS的值是什么,就这样。一直可以找到
14,经过很长时间的调整查找,可以找到这样的命令:
/usr/local/share/cmake-2.8/Modules/FindZLIB.cmake(56): FIND_PATH(ZLIB_INCLUDE_DIR NAMES zlib.h ${${search}}PATH_SUFFIXES include
)
/usr/local/share/cmake-2.8/Modules/FindZLIB.cmake(57): FIND_LIBRARY(ZLIB_LIBRARY NAMES ${ZLIB_NAMES} ${${search}}PATH_SUFFIXES lib
)
CMakeList.txt 里面会调用 cmake里面的 FindZLIB.cmake文件,
这个文件是cmake自己搞的一套查找zlib头文件和库文件的脚本。PATH_SUFFIXES后面是什么东东?呀,被震惊到了。居然要找路径中包含
include和 lib
的文件夹。也就是说你的zlib库文件和头文件要放到lib和include
的文件夹下,
不然是找不到的。
15 .回想下,因为arm编译工具链把这个zlib给剪辑掉了,所以zlib库是我自己编译的。我给zlib头文件和库文件的文件名都是随便取的一个,与include/lib不相符.
额,被cmake内部的配置脚本给阴了。
16. 总结: cmake中的FindZLIB.cmake脚本要查找zlib的头文件和库文件,如果找不到,就会到/usr/include和/usr/lib下面找。这时肯定是能找到的,结果就把
/usr/include路径放到头文件的搜索路径里面去。这时候进行arm编译的时候,就会使用/usr/include下面的头文件。结果就会出现很奇葩的错误。
//filename: mytoolchain.cmake set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR arm) set(CMAKE_C_COMPILER $ENV{CROSS_COMPILE}gcc) set(CMAKE_CXX_COMPILER $ENV{CROSS_COMPILE}g++) set(CMAKE_FIND_ROOT_PATH $ENV{CROSS_ROOT_PATH} $ENV{OPENSOURCE_DIR}/Utility/ZLIB/1.2.6) SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_INSTALL_PREFIX .)
#filename: opencv.sh #!/bin/bash #This is opencv shell script OPENCV_ROOT=`pwd` export OPENCV_ROOT if [ ! -d "opencv-2.4.4" ]; then echo "Unpacking opencv source ..." tar jxvf OpenCV-2.4.4a.tar.bz2 fi CROSS_ROOT_PATH=/home/data001/toolchain/toolchain/arm-v7a15v3r1-20121018/bin/../arm-v7a15v3r1-linux-gnueabi/sys-root if [ ! -n "$CROSS_COMPILE" ]; then export CROSS_COMPILE=arm-v7a15v3r1-linux-gnueabi- fi if [ ! -d "opencv-2.4.4/build" ];then mkdir opencv-2.4.4/build cp mytoolchain.cmake opencv-2.4.4/build cp opencv-2.4.4/modules/imgproc/src/smooth.cpp opencv-2.4.4/modules/imgproc/src/smooth.cpp.bak cp -f src/smooth.cpp opencv-2.4.4/modules/imgproc/src #echo "add ZLIB to the directory" #mkdir $ENV{OPENSOURCE_DIR}/Utility/ZLIB/1.2.6/include #mkdir $ENV{OPENSOURCE_DIR}/Utility/ZLIB/1.2.6/lib ln -sf $OPENSOURCE_DIR/Utility/ZLIB/1.2.6/Inc $OPENSOURCE_DIR/Utility/ZLIB/1.2.6/include ln -sf $OPENSOURCE_DIR}Utility/ZLIB/1.2.6/Lib/FOXP/dbg $OPENSOURCE_DIR/Utility/ZLIB/1.2.6/lib echo "cmake..., make -j8" cd opencv-2.4.4/build cmake -DCMAKE_TOOLCHAIN_FILE=mytoolchain.cmake -DBUILD_opencv_highgui=OFF -DBUILD_opencv_apps=OFF -DBUILD_opencv_legacy=OFF -DBUILD_opencv_ml=OFF -DBUILD_opencv_nonfree=OFF -DBUILD_opencv_python=OFF -DBUILD_opencv_ts=OFF -DBUILD_opencv_stitching=OFF -DBUILD_opencv_video=OFF -DBUILD_opencv_videostab=OFF -DBUILD_opencv_world=OFF -DWITH_TIFF=OFF -DWITH_JPEG=OFF -DWITH_OPENEXR=OFF -DWITH_PNG=OFF -DWITH_JASPER=OFF .. make clean; make -j8 else echo "make -j8" cd opencv-2.4.4/build make -j8 fi echo "copy opencv-2.4.4 header files and library" if [ -d "$OPENCV_ROOT/Inc" ];then rm -rf $OPENCV_ROOT/Inc fi if [ -d "$OPENCV_ROOT/Lib" ];then rm -rf $OPENCV_ROOT/Lib fi mkdir $OPENCV_ROOT/Inc mkdir $OPENCV_ROOT/Lib cp -f $OPENCV_ROOT/opencv-2.4.4/build/lib/*.so* $OPENCV_ROOT/Lib cp -rf $OPENCV_ROOT/opencv-2.4.4/include/opencv $OPENCV_ROOT/Inc cp -rf $OPENCV_ROOT/opencv-2.4.4/include/opencv2 $OPENCV_ROOT/Inc cp -rf $OPENCV_ROOT/opencv-2.4.4/modules/calib3d/include/opencv2/* $OPENCV_ROOT/Inc/opencv2 cp -rf $OPENCV_ROOT/opencv-2.4.4/modules/core/include/opencv2/* $OPENCV_ROOT/Inc/opencv2 cp -rf $OPENCV_ROOT/opencv-2.4.4/modules/features2d/include/opencv2/* $OPENCV_ROOT/Inc/opencv2 cp -rf $OPENCV_ROOT/opencv-2.4.4/modules/flann/include/opencv2/* $OPENCV_ROOT/Inc/opencv2 cp -rf $OPENCV_ROOT/opencv-2.4.4/modules/imgproc/include/opencv2/* $OPENCV_ROOT/Inc/opencv2 cp -rf $OPENCV_ROOT/opencv-2.4.4/modules/photo/include/opencv2/* $OPENCV_ROOT/Inc/opencv2 cp -rf $OPENCV_ROOT/opencv-2.4.4/modules/objdetect/include/opencv2/* $OPENCV_ROOT/Inc/opencv2
相关文章推荐
- 【Linux开发】OpenCV在ARM-linux上的移植过程遇到的问题2---CMAKE配置问题
- OpenCV在ARM平台上的移植
- OpenCV4Android开发之旅(三)----Windows平台Eclipse、MinGW配置OpenCV2.4.4(C++接口调用) 全过程(附:MinGW编译OpenCV2.4.4)
- OpenCV移植到OMAP3730平台全过程
- OpenCV移植到ARM平台---Opencv with ffmpeg to ARM移植总结
- OpenCV在ARM-linux上的移植过程遇到的问题3---共享库中嵌套库居然带路径【未解决】
- 如何在arm平台上运行Jetty5(包含移植jamvm + classpath过程)(1)
- 【OpenCV】arm-linux-gcc 3.4.1 移植OpenCV 1.0 出现[cvpyrsegmentation.lo] Error 1 错误
- beagleboard上dvsdk移植----ARM调用DSP过程详解
- 基于Hi3559A ARM64位嵌入式平台的OpenCV 2.4/3.1 移植
- OpenCV在ARM-linux上的移植过程遇到的问题3—共享库中嵌套库居然带路径
- 将交叉编译好的OpenCV移植到ARM平台
- 【Linux开发】OpenCV在ARM-linux上的移植过程遇到的问题1---cvNamedWindow调用报错的问题
- OpenCV移植到ARM 全过程
- 【Linux开发】OpenCV在ARM-linux上的移植过程遇到的问题4---共享库中嵌套库带路径【已解决】
- 基于Hi3559A ARM64位嵌入式平台的OpenCV2.4.9+ffmpeg2.0.7移植及应用
- OPENCV在ARM平台的移植
- 移植编译bcm sdk6.4.8 过程-平台arm-linux cortex-a9双核,系xilinx soc
- OpenCV移植到ARM 全过程
- Opencv2.0移植ARM(Cortex A8)全过程