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文件,这个看看编译后的信息就知道了.