Android NDK 工具鏈的使用方法(Standalone Toolchain)

王慶發表於2013-09-03

轉載: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++)。不過在將來可以不用手動指定這個連結引數。

相關文章