詳解如何將android工具鏈作為獨立編譯器使用

來源:互聯網
上載者:User

現在已經可以把Android NDK提供的工具鏈以獨立編譯器的方式使用了!如果你已經有了自己的構建系統,這就很有用了。 一個典型的應用情境是調用一個依賴於CC環境變數開源庫的'configure'指令碼進行跨平台編譯。   本文檔將解釋如何那樣做。 1 選擇你的工具鏈:首先 ,你需要確定你的獨立工具鏈所面向的目標CPU加構,是ARM-based裝置、x86-based裝置,還是MIPS-based裝置。每個架構對應不同的工具鏈名字:     * arm-linux-androideabi-4.6   => 面向ARM-based Android裝置   * x86-4.6                     => 面向x86-based Android裝置   * mipsel-linux-android-4.6    => 面向MIPS-based Android裝置   2 選擇你的sysroot:你應該瞭解的第二項事情是你想面向那一級Android nativeAPI 。每一級都提供了不同的API,它們被文檔doc/STABLE-APIS.html所描述,並對應於$NDK/platforms的子檔案夾。這使得你可以定義指向你的'sysroot'的路徑 ,GCC路徑下包含系統標頭檔和庫。通常看起來像這樣:     SYSROOT=$NDK/platforms/android-<level>/arch-<arch>/   <level> 是API level 數,<arch> 是體繫結構("arm", "x86", 和"mips" 都可以作為值)。例如,如果你面向 Android2.2 (a.k.a. Froyo),你應使用:      SYSROOT=$NDK/platforms/android-8/arch-arm   注意:X86 和MIPS體系僅在android-9才開始支援。 3調用編譯器(笨辦法):使用--sysroot選項調用編譯器,以表明你所面向的平台的系統檔案的路徑。例如: export CC="$NDK/toolchains/<name>/prebuilt/<system>/bin/<prefix>gcc--sysroot=$SYSROOT" $CC -o foo.o -c foo.c   <name> 是工具鏈的名字,<system> 是宿主系統,<prefix> 是特定工具鏈的首碼。例如,如果你在Linux上使用NDK r5 工具鏈,你將使用:   exportCC="$NDK/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc--sysroot=$SYSROOT"   就像你看到的,這很囉嗦,但的確能工作!   注意:     直接使用NDK 工具鏈具有很多限制:     你不能使用任何C++ STL (無論是STLport 或GNU libstdc++) 。也不能使用異常和RTTI。   4調用編譯器(容易的辦法):NDK 允許你建立一個"自訂的" 工具鏈並安裝以使生活更簡單。例如,下面的命令:   $NDK/build/tools/make-standalone-toolchain.sh --platform=android-5--install-dir=/tmp/my-android-toolchain   這將建立一個檔案夾,名為 /tmp/my-android-toolchain,包含一個android-5/arch-armsysroot的考貝和工具鏈的執行檔案。   注意,預設下,ARM-based GCC 4.6 工具鏈將被指令碼所選擇。使用'--arch=x86' 來指定x86-based 的GCC,使用'--arch=mips' 來指定MIPS-based 的GCC,或使用 '--toolchain=<name>'來指定。例如:     --toolchain=x86-4.4.3               # select x86 GCC 4.4.3 compiler  --toolchain=mipsel-linux-android-4.6  # select MIPS GCC 4.6compiler, same as --arch=mips   如果你想,可以通過添加 --llvm-version=3.1 來把clang/llvm3.1也考貝過去。你可以在之後直接使用它。就像:      exportPATH=/tmp/my-android-toolchain/bin:$PATH    exportCC=arm-linux-androideabi-gcc   # or export CC=clang    exportCXX=arm-linux-androideabi-g++  # or export CXX=clang++   注意,不使用 --install-dir 選項,make-standalone-toolchain.sh將建立一個名為/tmp/ndk/<toolchain-name>.tar.bz2的tarball。這使你可以很容易的儲存並重新發布二進位工具包。 另一個重要的好處是這個獨立的工具鏈將包含一個GNU libstdc++的考貝,它能支援異常和RTTI (當你連結到libstdc++ 或 libsupc++)。   重點:工具鏈執行檔案不依賴於或包含宿主上的特點路徑,換句話說,它們可以被安裝於任何位置,或移動到另外位置。   注意:你依然可以對新的工具鏈使用—sysroot選項,但是現在變簡單了! 5 ABI 相容性:通過ARM 工具鏈產生的機器碼應該與官方的Android 'armeabi' ABI相容。推薦使用-mthumb 編譯標誌來強制產生16位Thumb-1指令 (預設是32-bit 的)。   如果你想面向'armeabi-v7a' ABI,你應該確保下面的標誌被使用:     CFLAGS='-march=armv7-a-mfloat-abi=softfp -mfpu=vfpv3-d16'   註:第一個標誌啟用Thumb-2指令,第二個啟用H/W FPU指令同時確保浮點參數被傳入核心寄存器,這是ABI相容的關鍵。*不要*分開使用這些標誌!   如果你想使用Neon指令,你需要改變-mfpu編譯標誌:     CFLAGS='-march=armv7-a-mfloat-abi=softfp -mfpu=neon'   注意這會強制使用VFPv3-D32。 還要確保下面兩個標誌也提供給連結器:     LDFLAGS='-march=armv7-a-Wl,--fix-cortex-a8'   註:第一個標誌指示連結器為armv7-a選擇合適的libgcc.a、libgcov.a和crt*.o。第二個標誌用於在某些Cortex-A8裝置中繞過一個CPU bug。   如果上面這些還不能滿足你,那麼你最好不要用獨立的工具鏈了,而是堅守NDK構建系統,它將為你處理所有細節。   當你面向x86 ABI 或MIPS ABI時你不需要使用任何特定的編譯器標誌。   6 警告和限制: Windows support:Windows下的二進位檔案*不*依賴於Cygwin。好訊息是它們因此會運行快,壞訊息是它們不明白Cygwin的路徑形式,比如/cygdrive/c/foo/bar (而不是 C:/foo/bar)。   NDK構建系統保證所有從Cygwin傳給編譯器的路徑都被自動轉換,並且為你應付那些難搞的事情。如果有一個自訂構建系統,你需要自己應付所有的問題。   註:當前沒有支援Cygwin / MSys的計劃。   wchar_t 支援:  在Android 2.3之前,Android平台並不真的支援wchar_t。這表示: l  如果你面向android-9 或更高平台,wchar_t的大小是4bytes,並且大多數C庫中的寬位元組函數都可用(例外是多位元組編解碼函數和wsprintf/wsscanf函數)。 l  如果你面向任何更低的API level,wchar_t 只有一個位元組並且任何寬位元組函數都 不能用。   我們建議所有開發人員都移除對wchar_t的任何依賴,並且轉換到更好的方式。Android所提供的支援僅僅是為了協助整合已存在的代碼。   異常、RTTI和STL:  工具鏈執行檔案默入是支援C++異常和RTTI的。所以當你不需要時,使用-fno-exceptions和-fno-rtti來禁止它們 (產生更少的機器碼)。   註:如果你想使用這些特性,你將需要明確的連結到libsupc++。要這樣做,在要在連結成二進位檔案時使用-lsupc++ :       arm-linux-androideabi-g++ .... -lsupc++   C++ STL 支援:  獨立工具鏈也帶有一個GNU libstdc++ 庫的考貝,它提供了C++標準模版庫的一個實現。要使用它,你還需要連結到正確的庫:   l  使用-lstdc++ 來連結靜態庫版。這保證了所有需要的C++ STL代碼都包含到了你的最終檔案中。這是推薦的方式。 l  使用-lgnustl_shared 來連結動態庫版。如果你使用此方式,你需要確保libgnustl_shared.so也被複製到你的裝置中。此檔案位於:  $TOOLCHAIN/arm-linux-androideabi/lib/ for ARM toolchains.  $TOOLCHAIN/i686-linux-android/lib/    for x86 ones.  $TOOLCHAIN/mipsel-linux-android/lib/  for MIPS toolchains.   動態庫版的GNU libstdc++不叫libstdc++.so的原因是這將導致在運行時與系統自己的最小C++運行時(/system/lib/libstdc++.so)衝突。這對靜態庫就沒影響了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.