OpenCV2.4.4 移植到arm平臺過程詳解,及 __extern_inline 錯誤的解決方案

在做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庫文件和頭文件要放到libinclude 的文件夾下,  不然是找不到的。

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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章