轉載:http://blog.csdn.net/smfwuxiao/article/details/6587709
首先需要確定目標機器的指令集。
如果是 x86 的機器,用 x86-4.4.3 版本的工具鏈;如果是 arm 指令的,用 arm-linux-androideabi-4.4.3 版本 (x86-4.4.3 和 arm-linux-androideabi-4.4.3 位於ndk目錄中)
1、gcc 的sysroot 選項
sysroot 選項設定 gcc 在編譯原始碼的時候,尋找標頭檔案和庫檔案的根目錄。可以這樣呼叫 gcc --sysroot=/tmp/gcc-arm (及其他選項)。NDK 根目錄下的 platforms 目錄中的各個子目錄的路徑都可以直接傳給 gcc --sysroot=<dir>。為了簡化操作,可以在linux系統的命令終端執行以下命令,設定SYSROOT環境變數,$NDK是ndk的根目錄。
$ SYSROOT=$NDK/platforms/android-8/arch-arm
2、呼叫 NDK gcc(第1種方法)。 設定 SYSROOT之後,要把它傳給 gcc 的 --sysroot 選項。由於unix/linux自帶的gcc並非交叉編譯工具,而我們需要使用的是ndk中提供的交叉編譯工具(也是gcc),所以需要想辦法讓編譯指令碼找到ndk中的gcc,而不要去尋找系統中的gcc。而 unix/linux 系統的編譯指令碼常常會用 CC 環境變數來引用編譯器,所以通過把 CC 設定為ndk中的gcc的路徑,就能幫助編譯指令碼找到正確的gcc(我們還能順便加上--sysroot選項)。
將CC 按如下設定
$ export CC="$NDK/toolchains/<name>/prebuilt/<host-system>/bin/<prefix>gcc --sysroot=$SYSROOT"
$ $CC -o foo.o -c foo.c (不必執行這一行,這條命令是呼叫gcc編譯程式)
上面第1行之後之後,再去執行./configure 就可以編譯出arm程式了。不過還需要考慮共享庫的連結問題,要確保該程式沒有連結ndk未提供的共享庫。該方法的缺陷就是,不能使用 C++ STL(STLport 或 GNU libstdc++ ),也不能使用異常機制和RTTI。
3、呼叫NDK編譯器(第2種方法,更簡單)
android ndk 提供指令碼,允許自己定製一套工具鏈。例如:
$NDK/build/tools/make-standalone-toolchain.sh --platform=android-5 --install-dir=/tmp/my-android-toolchain [ --arch=x86 ]
將會在/tmp/my-android-toolchain 中建立 sysroot 環境和 工具鏈。--arch 選項選擇目標程式的指令架構,預設是為 arm。
如果不加 --install-dir 選項,則會建立 /tmp/ndk/<toolchain-name>.tar.bz2。
(執行 make-standalone-toolchain.sh --help 檢視幫助。)
執行之後,這樣使用:
$ export PATH=/tmp/my-android-toolchain/bin:$PATH
$ export CC=arm-linux-androideabi-gcc
$ export CXX=arm-linux-androideabi-g++
$ export CXXFLAGS="-lstdc++"
執行完以上設定環境變數的命令之後,就可以直接編譯了(例如,執行 ./configure 然後 make 得到的就是 arm 程式了)。不用再設定 sysroot, CC 了。而且,可以使用 STL,異常,RTTI。
4、ABI 相容性
ndk 同時支援 arm5 和 arm7,一般只用 arm5就好了。arm7是高階一點的,NDK 預設也是 arm5 。
推薦加上 -mthumb 選項給gcc,來生成 16-bit Thumb-1 指令。
如果要用 arm7,可以設定 CFLAGS='-march=armv7-a -mfloat-abi=softfp', 使用 Thumb-2 指令,且這兩個選項不能分開!
5、警告 & 限制
5.1 Windows支援
Windows 上的NDK 工具鏈不依賴 Cygwin,因而速度比用 Cygwin 快一點,但是這些工具不能理解
Cygwin 的路徑名(例如, /cygdrive/c/foo/bar)。只能理解 C: /cygdrive/c/foo/bar 這類路徑
不過,NDK 提供的build工具能夠很好地應對上述問題(ndk-build)
5.2 wchar_t 支援
wchar_t 型別僅從 Android 2.3 開始支援。
在 android-9 上, wchar_t 是 4位元組。 並且 C語言庫提供支援寬字元的函式
(例外:multi-byte 編碼/解碼 函式 和 wsprintf/wsscanf )
在android-9 以前的平臺上,wchar_t 是1位元組,而且寬字元函式不起作用。
建議不使用 wchar_t,提供 wchar_t 支援是為了方便移植以前的程式碼。
5.3 異常, RTTI 和 STL
NDK 工具鏈預設支援C++異常和RTTI(Run Time Type Information),可以用 -fno-exception 和 -fno-rtti 關閉(生成的機器碼更小)
注意: 如果要用這兩個特性,需要顯式連結 libsupc++。例如: arm-linux-androideabi-g++ .... -lsupc++
NDK 提供了 libstdc++,因而可以用 STL,但需要顯式連結 libstdc++ ( gcc ... -lstdc++)。不過在將來可以不用手動指定這個連結引數。