android64位編譯
用最新的Ubuntu 16.04,請首先確保自己已經安裝了Git.沒安裝的同學可以通過以下命令進行安裝:
sudo apt-get install git git config –global user.email 「[email protected]」 git config –global user.name 「test」
其中[email protected]為你自己的郵箱.
簡要說明
android源碼編譯的四個流程:1.源碼下載;2.構建編譯環境;3.編譯源碼;4運行.下文也將按照該流程講述.
源碼下載
由於某牆的原因,這里我們採用國內的鏡像源進行下載.
目前,可用的鏡像源一般是科大和清華的,具體使用差不多,這里我選擇清華大學鏡像進行說明.(參考:科大源,清華源)
repo工具下載及安裝
通過執行以下命令實現repo工具的下載和安裝
mkdir ~/binPATH=~/bin:$PATHcurl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repochmod a+x ~/bin/repo
補充說明
這里,我來簡單的介紹下repo工具,我們知道AOSP項目由不同的子項目組成,為了方便進行管理,Google採用Git對AOSP項目進行多倉庫管理.在聊repo工具之前,我先帶你來聊聊多倉庫項目:
我們有個非常龐大的項目Pre,該項目由很多個子項目R1,R2,...Rn等組成,為了方便管理和協同開發,我們為每個子項目創立自己的倉庫,整個項目的結構如下:
這里寫圖片描述
執行完該命令後,再使用make命令繼續編譯.某些情況下,當你執行jack-admin kill-server時可能提示你命令不存在,此時去你去out/host/linux-x86/bin/目錄下會發現不存在jack-admin文件.如果我是你,我就會重新repo sync下,然後從頭來過.
錯誤三:使用emulator時,虛擬機停在黑屏界面,點擊無任何響應.此時,可能是kerner內核問題,解決方法如下:
執行如下命令:
通過使用kernel-qemu-armv7內核 解決模擬器等待黑屏問題.而-partition-size 1024 則是解決警告: system partion siez adjusted to match image file (163 MB >66 MB)
如果你一開始編譯的版本是aosp_arm-eng,使用上述命令仍然不能解決等待黑屏問題時,不妨編譯aosp_arm64-eng試試.
結束吧
到現在為止,你已經了解了整個android編譯的流程.除此之外,我也簡單的說明android源碼的多倉庫管理機制.下面,不妨自己動手嘗試一下.
2. Android手機64位和32位的軟體存在兼容問題嗎
Android手機64位和32位的軟體存在兼容。
關於Android 64位系統兼容32位應用的實現的簡單分析:
Android 的zygote進程的實現不同於之前的版本,除了有zygote進程之外還有zygote64進程。
在init.zygote32_64.rc中有明確指出:
service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
...
service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
...
其中app_process32 和app_process64 就是zygote進程的可執行程序,啟動後會改名成zygote。
顧名思義,zygote32即app_process32是一個運行在32位的進程,它所連接的庫也都是32位的。而zygote64就是運行在64位的進程,它所連接的庫都是64位的。
在不考慮有32/64兼容庫的情況下,一個進程如果要正確運行,就必須從可執行程序入口開始到所有使用的庫都保持32/64位的一致性。
因為zygote進程是所有第三方應用程序的父進程,所以可以認為,如果應用程序是32位的,那沒他的父進程也肯定是32位,換句話說,如果需要啟動某個32位的應用,那麼肯定是通過32位的zygote進程fork出來的。
這個一點可以在ActivityManagerService上得到驗證。
ActivityManagerService中startProcessLocked方法實現啟動應用,主要通過Process中的startViaZygote方法
這個方法最終是向相應的zygote進程發出fork的請求 zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
其中openZygoteSocketIfNeeded(abi)會根據abi的類型,選擇不同的zygote的socket監聽的埠
在之前的init文件中可以看到zygote32位監聽的埠就是–socket-name=zygote另外一個就是–socket-name=zygote_secondary
因此可以證實,之前的猜測,即32應用進由32位zygote進程fork出來,64位應用進程由64zygote進程fork出來。那麼之前說的abi參數就是決定應用是32還是64位的關鍵所在,跟蹤這個參數,發現這個參數在ApplicationInfo的primaryCpuAbi中決定
這個值由PackageManagerService在做scanPackageLI的時候決定,具體這個值的得出有一個公式化的過程,主要就是判斷這個apk有沒有使用native的庫
如果使用了,那就看使用了的是32位的還是64位的,另外還要看系統支持的是32位還是64位的。
在64位設備上,如果app的 lib 目錄下 存在armeabi,則以32位兼容方式運行。
如果存在arm64-v8a 則已64位運行。如果沒有任何 so,則 primaryCpuAbi 為空,按照系統的默認配置決定,也就是64位運行。
根據這些因素就可以決定這個apk是應該是32位的還是64位的。以上就是Android L 64位系統兼容32位應用的基本實現過程。另外記錄一點,在源碼環境下如果要PREBUILT第三方的so
如果是32位的需要專門標注 LOCAL_MULTILIB := 32以此告訴編譯系統so位32位,防止編譯到64位下去。
(2)android64位編譯擴展閱讀:
64位和32位晶元的區別
其實手機處理器和PC處理器對於位數的概念是相同的,這里我就用PC的處理器來說明了。對CPU有些了解的人大概都知道Pentium 3和Pentium 4,了解更深的,還會知道是i386處理器在20幾年前把處理器從16位帶入32位時代。
處理器經過了近30多年的考驗後,到現在已經躍升到64位,這可不同1GHz到3GHz的頻率提升。如果說頻率的提升是把一條4車道高速公路的時速限制從120公里提升到了360公里的話
那麼從32位到64位的提升就是將這條提升了3倍時速限制的高速公路從4車道拓寬到了8車道,也就是說,這條公路的運力提升了一倍,這可是質的飛躍。
3. android源碼用64位系統編譯了 怎麼運行在32位的手機上
android源碼編譯64位改成32位的辦法(轉載)
You are attempting to build on a 32-bit system.Only 64-bit build environments are supported beyond froyo/2.2.
需要進行如下修改即可,
將
./external/clearsilver/cgi/Android.mk
./external/clearsilver/java-jni/Android.mk
./external/clearsilver/util/Android.mk
./external/clearsilver/cs/Android.mk
四個文件中的
LOCAL_CFLAGS += -m64
LOCAL_LDFLAGS += -m64
注釋掉,或者將「64」換成「32」
LOCAL_CFLAGS += -m32
LOCAL_LDFLAGS += -m32
然後,將
./build/core/main.mk 中的
ifneq (64,$(findstring 64,$(build_arch)))
改為:
ifneq (i686,$(findstring i686,$(build_arch)))
4. 新人求教,編譯一個最簡單的Android程序,提示下面的錯誤咋解決
1、32位系統下的編譯
如果需要在32位系統中編譯android系統,在編譯前需要對部分makefile進行修改
首先修改build/core/main.mk,修改的內容如下所示:
-ifneq (64,$(findstring 64,$(build_arch)))
+ifneq
(i686,$(findstring i686,$(build_arch)))
$(warning
************************************************************) $(warning You are attempting to build on a 32-bit system.)
$(warning Only 64-bit build environments are supported beyond froyo/2.2.)
其次修改如下四個文件:
external/clearsilver/cgi/Android.mk
external/clearsilver/java-jni/Android.mk
external/clearsilver/util/Android.mk
external/clearsilver/cs/Android.mk # This forces a 64-bit build for Java6
-LOCAL_CFLAGS += -m64
-LOCAL_LDFLAGS += -m64
+LOCAL_CFLAGS += -m32
+LOCAL_LDFLAGS += -m32即將LOCAL_CFLAGS和LOCAL_LDFLAGS由-m64改為-m32,從而指定使用32位系統進行編譯如果使用 64bit 的操作系統編譯,這些就都不用修改,但記得需要安裝:For 64-bit servers the following extra packages may be needed:
"sudo apt-get install libc6-dev-i386" (libc6-dev-amd64 if AMD CPU)
"sudo apt-get install g++-multilib lib32ncurses5-dev lib32z1-dev"
還有 jdk64bit 的版本編譯2 、build/core/base_rules.mk:128:*** frameworks/opt/emoji/jni:
.... libgl2jni already defined by framwworks/base/opengl/tests/gl2_jni/jni 停止
從編譯規則上看:
# Make sure that this IS_HOST/CLASS/MODULE combination is unique.
mole_id := MODULE.$(if \
$(LOCAL_IS_HOST_MODULE),HOST,TARGET).$(LOCAL_MODULE_CLASS).$(LOCAL_MODULE)
ifdef $(mole_id)
$(error $(LOCAL_PATH): $(mole_id) already defined by $($(mole_id)))
endif
在framwworks/base/opengl/tests/gl2_jni/下面定義的android.mk定義了:
LOCAL_MODULE := libgl2jni
include $(BUILD_SHARED_LIBRARY)
導致生成的動態庫重復,這是不對的,修改tests這個目錄不參與編譯即可,最直接的辦法刪除掉framwworks/base/opengl/tests/gl2_jni這個文件夾
3、AIDL 編譯報couldn't find import for class原因
「AIDL服務只支持有限的數據類型,因此,如果用AIDL服 務傳遞一些復雜的數據就需要做更一步處理。AIDL服務支持的數據類型如下:
Java的簡單類 型(int、char、boolean等)。不需要導入(import)。String和 CharSequence。不需要導入(import)。
List和 Map。但要注意,List和Map對象的元素類型必須是AIDL服務支持的數據類型。不需要導入(import)。AIDL自動生成 的介面。需要導入(import)。
實現 android.os.Parcelable介面的類。需要導入(import)。
其中後兩種數據類 型需要使用import進行導入,傳遞不需要 import的數據類型的值的方式相同。傳遞一個需要import的數據類型的值(例如,實現android.os.Parcelable 介面的類)的步 驟略顯復雜。除了要建立一個實現android.os.Parcelable介面的類外,還需要為這個類單獨建立一個aidl文件,並使用parcelable關鍵字進行定義。」
沒有加LOCAL_AIDL_INCLUDES += xxx ,所以找不到我的parcelable aidl文件。
修改android源碼根目錄下的build/core/pathmap.mk把你的目錄加進去,此時再make update-api
4、老是提示 @Override錯誤 方法未覆蓋其父類的方法
使 用JDK1.6編譯沒有問題,使用JDK1.5編譯,會報@Override方法未覆蓋其父類的方法。實際上這個方法是類實現的介面中方法,
但是,這個語 法的jdk1.6的下面是可以通過的,也就是說jdk1.6認為類覆蓋父類方法與實現介面方法都叫override,而jdk1.5不
是這樣認為的,不知 道這是當初jdk1.5的bug,還是當初就是認為覆蓋父類方法與實現介面方法是不一樣的,不得而知。但是從
OO角度來看,覆蓋父類方法與實現介面方法都 可以認為override,因為他們目的都是一樣的,都是為了重用,都是多態的一種
表現方式。
更改jdk版本為1.6即可
5、編譯alsa-lib庫錯誤
android系統開發移植alsa-lib庫的過程中編譯的時候出現了如下的錯誤
/tmp/cckyaR40.s: Assembler messages:
/tmp/cckyaR40.s:2763: Error: selected processor does not support `mrs ip,cpsr'
/tmp/cckyaR40.s:2764: Error: unshifted register required -- `orr r2,ip,#128'
/tmp/cckyaR40.s:2765: Error: selected processor does not support `msr cpsr_c,r2
字面的意思報的是匯編錯誤,選擇的處理器不支持mrs和msr指令。
原來的ARM指令有32位和16位兩種指令模式,16位為thumb指令集,thumb指令集編譯出的代碼佔用空間小,
而且效率也高,所以android的arm編譯器默認用的是thumb模式編譯,問題在於alsa的代碼中有部分的內容
5. so庫如何適配安卓32bit\64bit 的cpu 怎麼編譯
JAVA編譯不分32bit和64bit(APK,JAR)
可執行文件,默認編譯64位
動態庫和靜態庫,默認同時編譯32bit和64bit版本
通過LOCAL_MULTILIB可以指定特定模塊編譯32bit或64bit或都編譯
JAVA載入JNI庫(so文件)的規則:
如果APP需要載入的所有so都是32bit,則使用32bit方式載入so庫;如果APP需要載入的so庫中只要有一個so是64bit的,則必須以64bit方式載入so庫;不能同時載入32bit和64bit的so庫。
實際工程中,我們通常會遇到下面這樣的場景:
A. APK有源碼,SO庫有源碼 - 應用及so庫我們都能自己編譯出來
B. APK有源碼,SO庫沒有源碼 - 我們開發的應用使用了第三方的so庫,如ScanService
C. APK和SO庫都沒有源碼 - 預置第三方的應用(應用中包括so庫)
對於場景A:
只要我們編譯默認對應的APP和SO庫(32bit+64bit)即可。
此種場景最為普通,本文不做詳細講解。
對於場景B:
如果APK需要載入的庫裡面有64bit的,則需要全部的庫都使用64bit。
如果APK調用的第三方so庫中有32bit的,則:要麼讓第三方提供64bit版本的so庫,要麼強制使所以的so庫都使用32bit版本。
對於場景C:
使用特定的預置規則即可。
6. 安卓ppsspp怎麼開啟64位編譯器
1.windows下需要安裝Git工具,推薦Git Bash(點我),eclipse(個人在用3.7),Android NDK(點我)。
2.配置eclipse android sdk,並解壓Android NDK。
3.安裝git工具然後輸入如下操作:
git clone git://github.com/hrydgard/ppsspp.git
cd ppsspp
git submole update--init
4.進入剛剛clong下來的ppsspp->android,編輯ab.cmd,修改第五行的SET NDK的路徑到你解壓的NDK路徑,如下圖:
5.雙擊ab.cmd開始編譯.so文件6.eclipse導入ppsspp/android,復制到工作目錄
7.導入ppsspp/naive/android到工程中。
8.run
7. I.MX6 ubuntu 12.04 64位 android 編譯環境安裝 求助
ocean@ubuntu:/opt$ ls
android_jb4.3_1.1.0-ga_source.tar.gz freescale
ocean@ubuntu:/opt$ sudo tar xzvf android_jb4.3_1.1.0-ga_source.tar.gz `
> ^C
ocean@ubuntu:/opt$ sudo tar xzvf android_jb4.3_1.1.0-ga_source.tar.gz
android_jb4.3_1.1.0-ga_source.tar.gz
android_jb4.3_1.1.0-ga_tool.tar.gz
ocean@ubuntu:/opt$ ls
android_jb4.3_1.1.0-ga_source.tar.gz android_jb4.3_1.1.0-ga_tool.tar.gz freescale
ocean@ubuntu:/opt$ ls
android_jb4.3_1.1.0-ga_source.tar.gz android_jb4.3_1.1.0-ga_tool.tar.gz freescale
ocean@ubuntu:/opt$ ls -al
total 274616
drwxr-xr-x 3 root root 4096 Mar 25 19:58 .
drwxr-xr-x 25 root root 4096 Mar 20 10:15 ..
-rwxrwxrwx 1 root root 86686647 Dec 6 11:05 android_jb4.3_1.1.0-ga_source.tar.gz
-rwxrwxrwx 1 root root 194503330 Dec 6 11:07 android_jb4.3_1.1.0-ga_tool.tar.gz
drwxr-xr-x 5 root root 4096 Mar 21 07:42 freescale
ocean@ubuntu:/opt$ sudo tar zxvf android_jb4.3_1.1.0-ga_tool.tar.gz
android_jb4.3_1.1.0-ga_tool/
android_jb4.3_1.1.0-ga_tool/Mfgtools-Rel-13.01.00_ER_MX6SL_UPDATER.tar.gz
android_jb4.3_1.1.0-ga_tool/tetherxp.inf
android_jb4.3_1.1.0-ga_tool/Mfgtools-Rel-13.01.00_ER_MX6DL_UPDATER.tar.gz
android_jb4.3_1.1.0-ga_tool/Mfgtools-Rel-13.01.00_ER_MX6Q_UPDATER.tar.gz
ocean@ubuntu:/opt$ ls
android_jb4.3_1.1.0-ga_source.tar.gz android_jb4.3_1.1.0-ga_tool android_jb4.3_1.1.0-ga_tool.tar.gz freescale
ocean@ubuntu:/opt$ sudo ls -al
total 274620
drwxr-xr-x 4 root root 4096 Mar 25 19:59 .
drwxr-xr-x 25 root root 4096 Mar 20 10:15 ..
-rwxrwxrwx 1 root root 86686647 Dec 6 11:05 android_jb4.3_1.1.0-ga_source.tar.gz
drwxr-xr-x 2 ocean ocean 4096 Dec 6 02:19 android_jb4.3_1.1.0-ga_tool
-rwxrwxrwx 1 root root 194503330 Dec 6 11:07 android_jb4.3_1.1.0-ga_tool.tar.gz
drwxr-xr-x 5 root root 4096 Mar 21 07:42 freescale
ocean@ubuntu:/opt$ rm android_jb4.3_1.1.0-ga_tool
rm: cannot remove `android_jb4.3_1.1.0-ga_tool': Is a directory
ocean@ubuntu:/opt$ sudo rm android_jb4.3_1.1.0-ga_tool
rm: cannot remove `android_jb4.3_1.1.0-ga_tool': Is a directory
ocean@ubuntu:/opt$ sudo rm -rf android_jb4.3_1.1.0-ga_tool
ocean@ubuntu:/opt$ ls
android_jb4.3_1.1.0-ga_source.tar.gz android_jb4.3_1.1.0-ga_tool.tar.gz freescale
ocean@ubuntu:/opt$ sudo rm android_jb4.3_1.1.0-ga_tool.tar.gz
ocean@ubuntu:/opt$ ls
android_jb4.3_1.1.0-ga_source.tar.gz freescale
ocean@ubuntu:/opt$ sudo tar xzvf android_jb4.3_1.1.0-ga_source.tar.gz
android_jb4.3_1.1.0-ga_source/
android_jb4.3_1.1.0-ga_source/EULA
android_jb4.3_1.1.0-ga_source/code/
android_jb4.3_1.1.0-ga_source/code/jb4.3_1.1.0-ga.tar.gz
android_jb4.3_1.1.0-ga_source/package_manifest.txt
8. 64位android studio一定要64位jdk嗎
因為64位與32位的JDK編譯代碼時對位元組所劃分的內存不同,所以必須對應,否則有時候會彈出一下莫名其妙的錯誤,最常見的就是找不到jvm
不過在studio.bat文件中可以設置jdk是32位還是64位
SET JRE=%JDK%
IF EXIST "%JRE%\jre" SET JRE=%JDK%\jre
SET BITS=
IF EXIST "%JRE%\lib\amd64" SET BITS=64
把最後BITS=64修改為BITS=32就行了
9. 如何在64位安卓系統中使用32位SO庫
關鍵點:
JAVA編譯不分32bit和64bit(APK,JAR)
可執行文件,默認編譯64位
動態庫和靜態庫,默認同時編譯32bit和64bit版本
通過LOCAL_MULTILIB可以指定特定模塊編譯32bit或64bit或都編譯
JAVA載入JNI庫(so文件)的規則:
如果APP需要載入的所有so都是32bit,則使用32bit方式載入so庫;如果APP需要載入的so庫中只要有一個so是64bit的,則必須以64bit方式載入so庫;不能同時載入32bit和64bit的so庫。
實際工程中,我們通常會遇到下面這樣的場景:
A. APK有源碼,SO庫有源碼 - 應用及so庫我們都能自己編譯出來
B. APK有源碼,SO庫沒有源碼 - 我們開發的應用使用了第三方的so庫,如ScanService
C. APK和SO庫都沒有源碼 - 預置第三方的應用(應用中包括so庫)
對於場景A:
只要我們編譯默認對應的APP和SO庫(32bit+64bit)即可。
此種場景最為普通,本文不做詳細講解。
對於場景B:
如果APK需要載入的庫裡面有64bit的,則需要全部的庫都使用64bit。
如果APK調用的第三方so庫中有32bit的,則:要麼讓第三方提供64bit版本的so庫,要麼強制使所以的so庫都使用32bit版本。
對於場景C:
使用特定的預置規則即可。
10. android中如何編譯出64位so文件
如果是在Linux下編譯Android源碼,有可能是兩個原因:
1. lunch命令有32位和64位的區別,注意選能夠編譯64位so的命令
2. mk文件中有LOCAL_MODULE_PATH的值比如為$(TARGET_OUT_SHARED_LIBRARIES)/hw的改為LOCAL_MODULE_RELATIVE_PATH := hw,後一種可以分別在lib和lib64下分別生成32位和64位的so文件,這個看看編譯後的信息就知道了.