OpenCV 2.2をARM用にクロスビルドしたらハマった件

OpenCVをARM用にクロスコンパイルしたところ、色々ハマったのでメモ。

環境

手順

基本は、以下のページを参考に。
OpenCV Installation Guide on Debian and Ubuntu

OpenCVはビルドシステムにCMakeを使っているので、以下のページを見ながらtoolchain fileというのを作る。
CMake Cross Compiling

最終的に、手順は以下のようになった。

  1. 必要なクロスライブラリをひたすらインストール*2
  2. tar xjvf OpenCV-2.2.0.tar.bz2
  3. cd OpenCV-2.2.0
  4. mkdir armel
  5. cd armel
  6. vi armel.cmake
  7. cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_TOOLCHAIN_FILE:PATH=./armel.cmake ..
  8. make
  9. make install

armel.cmakeの中身は以下*3

set(CROSS_PREFIX arm-linux-gnueabi-)
set(CROSS_TOOLCHAIN_PATH /usr/arm-linux-gnueabi)

# specify the cross-toolchain (compiler, header and library directories)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR armel)
set(CMAKE_C_COMPILER ${CROSS_PREFIX}gcc)
set(CMAKE_CXX_COMPILER ${CROSS_PREFIX}g++)
set(CMAKE_INCLUDE_PATH ${CROSS_TOOLCHAIN_PATH}/include)
set(CMAKE_LIBRARY_PATH ${CROSS_TOOLCHAIN_PATH}/lib)
set(CMAKE_INSTALL_PREFIX ${CROSS_TOOLCHAIN_PATH}/)

#set(CMAKE_FIND_ROOT_PATH ${ARMADEUS_ROOT_CTC} ${CMAKE_INCLUDE_PATH})

# search for programs in the build host directories
set(CMAKE_FIND_ROOT_PATH ${CROSS_TOOLCHAIN_PATH})

# for libraries and headers in the target directories
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

ハマりポイント

普通にビルドするとビルドエラーが出るので、いくつか修正します。

expl が定義されていない

エラーメッセージ

/root/OpenCV-2.2.0/modules/ml/src/gbt.cpp:474: error: 'expl' was not declared in this scope

以下の修正を適用。

fixed GBTrees build on NetBSD & Android; fixed GPU brute force matcher test build on MacOSX

SIFTが未定義*4

エラーメッセージ

../../lib/libopencv_features2d.so.2.2.0: undefined reference to `cv::SIFT::SIFT(double, bool, bool, int, int, int, int)'
../../lib/libopencv_features2d.so.2.2.0: undefined reference to `cv::SIFT::CommonParams::CommonParams()'
../../lib/libopencv_features2d.so.2.2.0: undefined reference to `cv::SIFT::DescriptorParams::DescriptorParams()'
../../lib/libopencv_features2d.so.2.2.0: undefined reference to `cv::SIFT::DetectorParams::DetectorParams()'
../../lib/libopencv_features2d.so.2.2.0: undefined reference to `cv::SIFT::operator()(cv::Mat const&, cv::Mat const&, std::vector >&, cv::Mat&, bool) const'
../../lib/libopencv_features2d.so.2.2.0: undefined reference to `cv::SIFT::operator()(cv::Mat const&, cv::Mat const&, std::vector >&) const'
../../lib/libopencv_features2d.so.2.2.0: undefined reference to `cv::SIFT::SIFT(double, double, int, int, int, int)'

以下の修正を適用。

added empty implementation of SIFT class methods throwing exception if ARM


さすが、元々Intelのプロジェクトだっただけあって、Intel以外のプラットフォームではあまりテストされてないっぽいですね。

*1:Squeeze使えよというツッコミは無しの方向でお願いします。

*2:[http://armadillo.atmark-techno.com/howto/install-cross-libraries:title=クロス開発用ライブラリをインストールする方法]とか参照。

*3:どうも、ライブラリがインストールされているかどうかの判断を、ビルドPCのライブラリを見て判断してるっぽいので、何か間違ってるはず。

*4:[http://d.hatena.ne.jp/kokekome/20110204/1296821782:title=OpenCV 2.2 - kokekomeのハードウェアな日記?]がきっかけで、この問題に気づきました。ありがとうございます。