hishidaの開発blog

EBシリーズ(EBPocket,EBWin,EBMac,EBStudio),KWIC Finder,xdoc2txt,読書尚友の開発者ブログ

Xcode および AndroidでのSTLの利用について

STL(Standard Template Library )はC++の標準ライブラリで、クラスとテンプレートの利用により、vectorやmap、listのような一般的なアルゴリズムを任意の型に対して使用できる。自分でアルゴリズムを実装するよりも、STLを使用した方が信頼性や性能面で向上することが期待できる。STLはISO/ANSI標準に組み込まれているので、C++を使うなら使わない手は無い。
WindowsVisual Studio では標準でSTLが使用できるが(VSのバージョンによって対応状況が違うが)、STLを使用したプログラムをXcodeAndroidにポートしようとすると、若干の注意がいる。

Android

AndroidのNDKでは、STLの実装の一つであるSTLPortが使用できる。Application.mkで、次の定義を指定するだけでSTLPortが有効になる。

APP_STL:=stlport_static

Gnuのlibstdc++を使う場合は、次のようにすればいいらしい。

APP_STL := gnustl_static

(EBPocket for AndroidSTLPortを使用している)

Xcode

XcodeSTLを使う場合、ちょっと面倒な問題がある。
Xcodeでは、Mac OS X 10.6(Snow leopard)までは、C++の標準ライブラリとしてGnuのlibstdc++が使用されてきた。
XcodeC++コンパイラは以前はGnu C++だったが、現在はLLVMとClang(クラン)に変わっている。Clangの標準C++ライブラリがlibc++であり、現在はこちらがAppleの標準である。
libstdc++はC++の最新規格であるC++11に対応していないので、C++11を使用するためにはlibc++を使う必要がある。
ここで問題は、libc++はMac OS X 10.7(lion)以降が必要であり、Mac OS X 10.6(Snow Leopard)にはlibc++.dylibが存在しないということ。つまり、libc++を使用すると、自動的にSnow Leopordは切り捨てられてしまう。なお、Mac OS X 10.6でlibc++をビルドすることはできるようだが、一般ユーザにはかなり難しい。(LLVMとClangをビルドしたのち、libc++をビルドする)
Xcodeでは、libstdc++を使うかlibc++を使うかは選択ができる。C++11を使用せず、Snow Leopordもサポートしたいのであれば、libstdc++を使うという選択肢もある。
Compiler Defaultでは、C++ライブラリはlibc++になっている。これをlibstdc++に変えるには、

TARGET
Build Settings
Apple LLVM 6.0 - Language - C++
C++ Standard Library : libstdc++(GNU C++ standard library)

C++11を使う場合は、C++ Standard Library をlibc++にするだけではなく、Language Dialectを指定しないとコンパイルエラーになる。

TARGET
Build Settings
Apple LLVM 6.0 - Language - C++
C++ Language Dialect : c++0x
C++ Standard Library : libc++

なお、Mac OS用のアプリでlibc++を使う場合、

Build Phases
 Link Binary With Libraries

で、libc++.dylibを追加する必要がある。標準ライブラリなのに面倒な話だ。iOSではlibc++.dylibの追加は必要ない。