轉載請註明出處!畢竟是我的心血啊!
原文連結:http://blog.csdn.net/zgyulongfei/article/details/7440254
寫這篇部落格的目的是希望可以協助到那些在將x264移植到Android過程中遭遇坎坷還沒有成功的朋友們,同時也算是對我這段時間學習的一個總結。
--------------------------------------------------------------------------------------
首先,先貼上我的編譯環境:
作業系統:ubuntu 11.10
jdk:jdk-6u31-linux-i586
eclipse:eclipse-SDK-3.7.2-linux-gtk
ndk:由於ndk版本不斷提高,但不同版本ndk的目錄結構和使用的gcc又不盡相同,本文將對兩個版本的ndk分別進行介紹(android-ndk-r4b-linux-x86 與 android-ndk-r6-linux-x86),你可以根據自己的ndk目錄進行配置。
x264源碼:last_x264
--------------------------------------------------------------------------------------
記得上課的時候王老師說過一句話:“忘了過去的苦難,就是未來的災難!”。
為了讓我的未來沒有災難,我將記錄下在編譯過程遭受的苦難 ^_^
(1)最開始的時候我是在windows 7 + cygwin環境下編譯的,但是一直沒有成功,可能是因為不太相信cygwin這樣的類比環境,我終於決定轉戰linux,於是在linux的世界裡從此就誕生了一名菜鳥,可正是如此,才有了下面的故事……
(2)因為初次接觸linux,我就像一個丈二的和尚努力地去摸我的頭腦,說實話,摸得可真夠累的,真是太習慣了windows傻瓜式的操作方法了!!!然後我就瞎搞胡搞,總算是有些熟悉linux環境了。
(3)剛開始編譯x264的時候,很happy的在google百度上找了一些編譯的方法,比如這篇《編譯x264》,什麼都不管就照著上面的做。直接 ./configure 之後就 make, 看到產生了libx264的庫,比見到鬼還高興,可是當用ndk編譯調用libx264的jni的時候,就亂七八糟的一大堆錯誤
= =.|| ,然後還一直找這些莫名其妙錯誤的解決方案。當然,最後沒有好結果 Orz.
(PS:我這裡要批評一下GFW,你妹的我用google剛剛穀了一會兒點擊結果彈出的頁面顯示的都是:無法訪問此網頁,DNS尋找失敗……!!!)
(4)在第3步糾結了很久,後來知道用./configure編譯使用的是預設的gcc編譯器集,而gcc編譯出來的檔案是在本地執行的,因為產生的是x86的二進位檔案。而我們移植的x264並不是在本地使用,因此需要交叉移植,交叉移植?神馬? 知道了在linux下交叉編譯需要用到arm-linux-gcc,果斷找用arm-linux-gcc編譯x264的文章《交叉編譯x264檔案》,原來在make之前得先將config.mak裡面的gcc全部改成arm-linux-gcc,還有其他一些也得修改為arm-linux-的編譯器集。改了之後,我還是編譯不過,因為我機器上沒有這個編譯器,於是下載arm-linux-gcc編譯器,配置後環境後,再make了一次。這下我開心了半死,編譯成功,勝利在望了有木有!!!
^_^
(5)將第4步編譯好的libx264放到android裡面調用,當用ndk編譯調用libx264的jni的時候,成功產生了.so檔案,這意味著我成功了嗎??
(6)當我很開心的拿我的HTC G3安裝運行產生的apk的時候,卻出現了錯誤java.lang.unSatifiedLinkerror: libx264 not found。 我暈,我甚至將產生的apk解包,發現裡面安安靜靜地躺著libx264啊,想起了《皇帝的新裝》這個故事,皇帝明明沒有穿衣服,人們硬要說他穿著漂亮的衣裳,尼瑪我的libx264就放在那裡,你硬要說它不在!??。這是腫麼一回事,又找了許久資料不見解決之道。心都涼了有木有!!!
(7)咳,煩死了去洗了個澡。回來決定再試一次,於是百度到了這篇文章《compile libx264 with android-ndk-r4b》,因為很早就試過這篇文章的配置,發現出錯了,於是放棄了。現在已經走投無路了,我就死馬當做活馬醫。用這個配置運行後,出現錯誤arm-eabi-gcc:沒有那個檔案或目錄。。。可是配置裡面明明就有那個gcc啊,由於在用arm-linux-gcc的時候也有出現類似的錯誤,是因為沒有這個庫,現在有這個庫了還說它不存在,這不是坑爹嗎?然後我抱著試一試的態度將arm-eabi-的路徑加入到PATH之後,然後再用這個設定檔編譯了一次,TT太感動了,成功編譯了,然後用編譯好的庫做測試回合成功了,運行成功了,成功了。。我高興得晚上都睡不著覺。
(8)原來用arm-linux-gcc是在x86機器上編譯可以在arm機器上啟動並執行二進位代碼,在android上運行不成功,是因為android不是arm平台吧?不知道我分析的對不對,如果有錯,歡迎指正。另:有更多關於gcc, arm-linux-gcc, arm-eabi-gcc的相關知識也希望你能告訴我,給我這個linux菜鳥上個課 ^_^
(9)總結:x264移植到Android下用的不是gcc,不是arm-linux-gcc,而是arm-eabi-gcc。
--------------------------------------------------------------------------------------
嘮叨了這麼久,終於要進入正題了 Orz
本文介紹的編譯方式最後產生的是靜態庫,如果需要編譯成動態庫的朋友可以點擊這裡,不過這篇文章只介紹了編譯的思路,並沒有提供確切地方法,需要的朋友還得自己去琢磨咯!
【一:使用ndk-r4b編譯x264】
步驟:
1,將x264壓縮包解壓,假設解壓後的目錄為libx264。
2,在libx264目錄下建立一個指令檔myconfig.sh,然後將《compile libx264 with android-ndk-r4b》裡面的代碼貼到myconfig.sh裡面。
3,將第一句配置 export ARM_ROOT=/home/frank/android-ndk-r4b 改成你ndk-r4b的路徑。
4,開啟終端,並將終端定位到libx264的目錄下,輸入 sudo sh ./myconfig.sh
5,當提示可以運行make的時候,輸入make
6,如果程式可以很正常的編譯,那麼恭喜你,你已經成功了,你可以不用看下面的內容了;如果輸入make之後,看到這些資訊:/bin/sh:arm-eabi-gcc:未找到命令,那麼你和我一樣遇到了這個問題,請繼續看第7步。
7,在終端輸入: sudo gedit /etc/profile ,在開啟的文本中定位到檔案末尾,輸入以下指令碼
#set arm-eabi-gcc environment
export ARM_EABI_GCC=/opt/java/ndk/android-ndk-r4b/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin
export PATH=$ARM_EABI_GCC:$PATH
注意:ARM_EABI_GCC中的/opt/java/ndk/android-ndk-r4b是我ndk-r4b的路徑,你要根據自己ndk路徑修改!
儲存後關閉文本。這一步的目的是為arm-eabi-gcc添加環境變數。
8,上一步修改的配置需要重啟電腦才會生效,為了能夠使其立即生效,需要在終端輸入:source /etc/profile,接著輸入:echo $PATH 查看ARM_EABI_GCC的路徑是否有在輸出的內容中,如果有,則看第9步,否則認真檢查,重新設定一下環境變數。
9,環境變數配置好了之後,輸入命令:make,如果不再提示說arm-eabi-gcc未找到命令而且看到程式正在編譯,那麼恭喜你,你將成功編譯libx264.
10,我編譯好的 libx264.a 檔案的大小為773.8k, 你的呢? ^_^
【二:使用ndk-r6編譯x264】
ndk-r6用到的不再是arm-embi-gcc,而是arm-linux-androideabi-gcc。具體編譯步驟還請查看【一:用ndk-r4b編譯】,只不過用的myconfig.sh不同,以及ARM_EABI_GCC不同。
這裡我貼上用ndk-r6編譯的myconfig.sh指令碼:
#------------------------------myconfig.sh------------------------------
export ARM_ROOT=/opt/java/ndk/android-ndk-r6
export ARM_INC=$ARM_ROOT/platforms/android-8/arch-arm/usr/include/
export ARM_LIB=$ARM_ROOT/platforms/android-8/arch-arm/usr/lib/
export ARM_TOOL=$ARM_ROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86
export ARM_LIBO=$ARM_TOOL/lib/gcc/arm-linux-androideabi/4.4.3
export PATH=$ARM_TOOL/bin:$PATH
export ARM_PRE=arm-linux-androideabi
./configure --disable-gpac --extra-cflags=" -I$ARM_INC -fPIC -DANDROID -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__
-Wno-psabi -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -DANDROID -Wa,--noexecstack -MMD -MP " --extra-ldflags="-nostdlib -Bdynamic -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,nocopyreloc
-Wl,-soname,/system/lib/libz.so -Wl,-rpath-link=$ARM_LIB,-dynamic-linker=/system/bin/linker -L$ARM_LIB -nostdlib $ARM_LIB/crtbegin_dynamic.o $ARM_LIB/crtend_android.o -lc -lm -ldl -lgcc" --cross-prefix=${ARM_PRE}- --disable-asm --host=arm-linux --disable-shared
#------------------------------myconfig.sh-----------------------------
注意:第一句ARM_ROOT還是得根據你ndk-r6的位置進行配置
另外,貼上/etc/profile中需要添加的配置:
#set arm-linux-androideabi-gcc
export ARM_LINUX_ANDROIDEABI_GCC=/opt/java/ndk/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin
export PATH=$ARM_LINUX_ANDROIDEABI_GCC:$PATH
我用ndk-r6編譯好的libx264.a大小為778.6k,你可以參考一下你編譯好的檔案大小。
--------------------------------------------------------------------------------------
本文算是結束了,如果你通過本文成功編譯好了libx264,那麼:“親,別忘了給個好評哦!^_^”