hamaronの日記

Tech & Research

iOS版のOpenCV利用でリンクエラーが出る時の対処法

安定しているのかどうかが良く分からないiOS向けOpenCVの動作を確認するため、
最新版のOpenCV2.4.3(バイナリ版)を導入し以下のサンプルをXcodeでコンパイル&実行してみました。

OpenCV iOS - Video Processing — OpenCV 2.4.9.0 documentation

さて、このサンプルプログラムを動かそうと思った時に残念ながら若干はまってしまいましたので、需要は多くないと思いますが、起きた問題とその解決方法を記録しておきます。


問題 : リンクエラーでコンパイルが失敗してしまう

次のようなエラーメッセージが出てコンパイルが停止します。典型的なリンクエラーですね。

Undefined symbols for architecture i386:
"std::__1::__vector_base_common::__throw_length_error() const", referenced from:
__ZNSt3__16vectorImNS_9allocatorImEEE6assignIPmEENS_9enable_ifIXsr21
__is_forward_iteratorIT_EE5valueEvE4typeES7_S7_ in opencv2(matrix.o)
std::__1::vector >::vector(unsigned long) in opencv2(matrix.o)
std::__1::vector >::__append(unsigned long) in opencv2(matrix.o)
std::__1::vector, std::__1::allocator > >::vector(unsigned long) in opencv2(matrix.o)
...
(中略)
...
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

不思議だったのは、opencv2.frameworkは当然のこと、サンプルページに書かれていたframeworkをすべてプロジェクトに追加しているにも関わらずリンクエラーが出てしまっていることでした。


解決方法

Xcodeのプロジェクトの設定からC++ Standard Libraryを "LLVM C++ standard library with C++ 11 support" に変更する。


おまけ : 考えられる原因

今回の問題は主に次の2つの要因が重なって起きたものだと考えられます。

  1. OpenCVを自前でビルドせず(自分の環境では失敗)、プリビルドされたバイナリ版のOpenCVを使っていたこと
  2. いくつかのWebサイトのアドバイスに従って、ext/atomicity.hが見つからないエラーを回避するために、Xcodeのプロジェクト設定の項目であるc++ Language DialectとC++ Standard LibraryをCompiler Default にしていたこと

iOS向けのOpenCVのプリビルド版は当然(?)、apple標準のappale-llvm-compilerでビルドされているわけですが、不幸にも自分の環境ではCompiler DefaultがLLVMではなくGCCになっていたので、LLVMでビルドされて生成されていたオブジェクトファイルをGCC側から参照できなかったというわけです。ちゃんちゃん。