重裝系統後把 cygwin 也重新在線安裝了一下,但發現 -mno-cygwin 盡然不能用了,找不到 crt2.o ,這些文件明明是存在的,搜索了一下官方的問答,說是安裝順序的問題,把mingw的幾個包重新裝一遍即可,試驗了幾次也沒效果,無奈,只能自己找原因,看看 /lib/gcc/i686-pc-mingw32/3.4.4/specs 文件,很多路徑指向了 /usr/i686-pc-mingw32/sys-root ,再看看 /usr/i686-pc-mingw32/lib ,也都是些指向 sys-root 的 link ,而這個目錄根本就不存在,真正的文件是在 /lib/mingw 裡的。在 /usr/i686-pc-mingw32 下建一個 sys-root 目錄,把 lib 下的文件復制過來,再試試編譯,所有問題解決! 難道說 cygwin 忘記把這些文件放到安裝包裡?應該不是吧,cygwin 也需要發展,並打算慢慢廢棄一些陳舊的東西,gcc3應該也懶得繼續維護,打算讓用戶全換到gcc4上去,眾所周知cygwin的已經不支持-mno-cygwin了,需要編譯純windows的東西由獨立的mingw64以cross toolchain方式替代。畢竟mingw是獨立的,並非cygwin的一部分,而且mingw的MSYS在某些方面足以跟 cygwin 唱對台戲。要讓 cygwin 花巨大精力去做 NO-CGYWIN 的東西,確實強人所難了,但遺憾的是,歷史遺留下來的大量依賴-mno-cygwin的編譯腳本也將被統統廢棄,可惜了。
言歸正題,雖然虛擬化技術在windows裡跑個linux是很容易的事,但我還是喜歡用cygwin,為了繼續andorid研究,在cygwin編譯套新的Android toolchain是必須的。網上搜索新的教程,很是郁悶,搜到基本都是我三年前的帖子和別人轉貼。算了,重新再來:
1.下載toolchain源碼
repo 安裝不多說了,但在cygwin下用 repo 需要裝 git 和 python 包,在64位win7下,python還出異常,需要關閉cygwin,運行bin目錄下的ash,並在ash提示符中運行 /bin/rebaseall 。(還可能出現windows的temp目錄不可寫的錯誤,chmod加寫入權限,不知道會不會給win自身的安全帶來隱患,不放心的話,rebaseall 結束後,再改回去吧)
# mkdir android-toolchain
# cd android-toolchain
# repo -u git://android.git.kernel.org/toolchain/manifest.git
# repo sync
大概需要下載280M左右的東西,但對我這下載平均不過5K的速度來說,太痛苦了...
2. 准備編譯toolchain
編譯前先仔細閱讀剛下載的目錄中 build 目錄下的 README,目前的toolchain允許編譯出4個目標toolchain,作為一般使用,我們只關心前兩個即適合NDK使用的 arm-linux-androideabi 和 用來編譯android內核的 arm-eabi 。看gcc部分也有4套版本的源碼可供選擇,印象中4.2.1不支持cortex-a8的指令集,所以如果要做ARMv7的代碼,需要選更高的版本,當然高版本的gcc也需要高版本的gmp和mpfr庫。檢查一下cygwin是否裝齊了各工具包,比如 gcc make flex bison gettext textinfo ,印象中 gettext-devel 一定要裝的。
# mkdir arm-eabi
# cd arm-eabi
# ../android-toolchain/build/configure --target=arm-eabi --prefix=/opt/arm-eabi --disable-libstdc__-v3
# make build
# make install
沒想到編譯過程出奇的順利,N個小時後,編譯腳本正常結束。得到編譯內核用的 arm-eabi,gcc版本4.2.1。這還不是目前真正需要的東西,把 /opt/arm-eabi 打包,備份,以後可能用的到。~/arm-eabi 目錄也沒什麼用了,可以直接刪除。我們其實需要是 gcc4.4.x 的arm-linux-androideabi 。這還需要 --with-sysroot=<path to sysroot> ,一個包含針對 android 指定版本的 sysroot 目錄,在 build 目錄裡有個腳本 build-sysroot.sh ,可以幫助從 android 源碼的編譯結果中提取需要的文件創建 android toolchain 的 sys-root ,但這這個腳本很邪惡,如果你用的root賬戶(cygwin裡基本就是root),如果你沒加任何參數指行了那個腳本,呵呵,你的系統基本需要重裝了,因為 /usr/lib 和 /usr/include 會被刪的一干二淨。務必注意!cygwin應該是不可能編譯android源碼的,所以只能找編譯好的,比如 prebuilt/ndk/android-ndk-r4/platforms/ 下的目錄。(該目錄在android的源碼中。也可以只 git platform/prebuilt,大概1.1G的下載量,有條件的不防把整個 platform 全部 repo 一份留之備用)。如果沒有下載 android 源碼,在 toolchain\benchmark\android_build\eclair 也可以找到,但只是預編譯結果,需要用 build-sysroot.sh 腳本從那個目錄裡選擇復制文件生成 sysroot。
# mkdir android-eabi
# cd android-eabi
# mkdir sys-root
把 toolchian/build/build-sysroot.sh 復制到 android-eabi 目錄下打開編輯
DYNAMIC_LIBS_DIR=$PRODUCT_DIR/symbols/system/lib 改成 DYNAMIC_LIBS_DIR=$PRODUCT_DIR/obj/lib
install $BIONIC_ROOT/libm/include/arm/fenv.h $INCLUDE_ROOT 改成 install $BIONIC_ROOT/libm/arm/fenv.h $INCLUDE_ROOT
執行腳本(切記參數別搞錯!!!)
# ./build-sysroot.sh ~/android-toolchain/benchmark/android_build/eclair/out/target/product/passion ~/android-eabi/sys-root
不明白為什麼一個簡單的文件復制腳本在 cygwin 下執行要花很常時間,總之執行完成,即可得到 eclair 的 sysroot 了。保險起見,這個build-sysroot.sh 還是刪除的好 (禍端啊,害我重裝N次cygwin)。
3. 開始編譯,cygwin的編譯器需要gcc4 (cygwin的gcc3和gcc4可以同時安裝,用set-gcc-default-?.sh可切換)
# ../android-toolchain/build/configure --target=arm-linux-androideabi --prefix=/opt/arm-linux-androideabi --with-gcc-version=4.4.3 --with-binutils-version=2.20.1 --with-gmp-version=4.2.4 --with-mpfr-version=2.4.1 --with-gdb-version=7.1.x --with-gold-version=20100303 --with-sysroot=~/android-eabi/sys-root --enable-gold=both/gold
#make build
#make install
編譯過程沒有什麼問題,但因為沒有編譯stdc++_v3 ,install 過程會出錯,gcc 目錄下 Makefile 中 install-target 節刪除 maybe-install-target-libstdc++-v3 maybe-install-target-libgcc maybe-install-target-libiberty 三行可解決。安裝後的編譯器基本功能都有了,但跟android源碼中prebuild下的toolchain似乎還有點差距