mac下编译android系统源代码以及编译指定模块

mac下编译android系统源代码以及编译指定模块:

  • 自行安装好xcode和jdk,配置好环境变量,这些做android开发的应该都会并已经配置好的了,这里不再细说。
  1. 磁盘分区

    1.1- 修改文件描述符限制

    ~/.bash_profile中添加以下内容

    #set the number of open files to be 1024 
    ulimit -S -n 1024
    

    1.2- 磁盘分区

    因为mac自带磁盘格式大小写不敏感,而下载的源代码里存在大小写不同同名文件,也就是要求有一个大小写敏感的环境,所以需要分区一个一块大小写敏感是磁盘区域出来。
    
    1.打开Disk Unility -> File -> New Image -> Blank Image
    2.起个名字比如aosp.dmg,size填写250 GB或者更大点,编译android10空间200GB不够。。。
    3.格式选择Mac OS Extended(Case-sensitive,Journaled),就是选择大小写敏感的日志式格式。
    4.其他不变,点击save保存即可。完成后对应挂载点为/Volumes/aosp/。
    
    如果下次开机/Volumes下找不到分区好的aosp.dmg分区,双击dmg即可自动挂载到/Volumes下了。
    
  2. 准备repo环境

    2.1- 下载repo文件,并给repo文件添加可执行权限

    mkdir ~/bin					#当前用户目录下创建bin目录
    PATH=~/bin:$PATH				#将bin目录添加到Path环境变量,当前窗口有效
    curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo		#下载repo
    chmod a+x ~/bin/repo		        #给repo文件添加可执行权限
    

    2.2 - 安装gnupg,我也不知道干嘛的,只是waring提示

    brew install gnupg
    

    2.3 - 初始化repo环境,指定仓库路径

    cd /Volumes/aosp/ 	                   #来到第一步的分区磁盘
    mkdir work_dir		                   #创建一个存放android系统源代码的工作目录
    cd work_dir				  #进来刚才创建的工作目录
    repo init -u git://mirrors.ustc.edu.cn/aosp/platform/manifest		#初始化仓库
    
    #这里使用的是清华源,并且是master主干分支。
    #google源是repo init -u https://android.googlesource.com/platform/manifest 需要翻墙
    #可以使用-b指定分支,比如:
    	repo init -u git://mirrors.ustc.edu.cn/aosp/platform/manifest -b android-10.0.0_r1
    #查看所有分支地址:https://android.googlesource.com/platform/manifest/+refs
    
  3. 下载android源代码
    repo sync #这句话实际下载路径就是上面repo init时指定的路径。
    
    #下载时间比较长,主要看网络给不给力了
    #最后看到repo sync has finished successfully.表示下载完成。
    #最新源代码android11大小约124G。。。
    
  4. 查看并切换到指定分支
    cd .repo/manifests	                 #来到这个目录
    git branch -a				#查看所有分支
    repo init -b android-10.0.0_r1	#回到工作目录,执行这句话切换到android-10.0.0_r1
    repo sync				        #切换完成再次执行同步操作
    
  5. 整体编译android系统源代码
    make clobber		                 #编译前删除缓存,这句一般不用执行,反正我没执行。。。
    source build/envsetup.sh		# 初始化编译环境
    lunch						#选择编译版本,我选择2编译64位的
    make -j16				        #开始编译,j后面的16一般是cpu核数的两倍
    
  6. 编译整个android系统源代码成功说明
    1. #### build completed successfully (02:47:40 (hh:mm:ss)) #### 使用make -j16的耗时
    2. 使用清华源,20m/s左右网速,1个多小时repo sync完成。
    3. 磁盘250GB编译最新版android11成功,最后只剩下20GB。所以磁盘最好大一点,300GB以上最好。
    4. 如果想将编译好的镜像烧入真机,还需要下载对应的手机驱动不然刷入后无法开机,然后再使用fastboot刷入,具体步骤自行搜索。
    5. 模拟器运行:
            方法1:source build/envsetup.sh -> lunch选择2 -> emulator	        #先执行环境,再执行emulator
            方法2:prebuilts/android-emulator/darwin-x86_64/emulator		#或者直接指定路径执行
    
  7. 编译android系统源代码特定模块
    m:  编译所有的模块
    mm: 编译当前目录下的模块,当前目录下要有Android.mk文件
    mmm:编译指定路径下的模块,指定路径下要有Android.mk文件
    
    使用这些命令前需要在android源码根目录执行source build/envsetup.sh脚本设置环境
    举例子,编译Camera2模块步骤:
    1.源代码目录下执行source build/envsetup.sh脚本设置环境
    2.直接执行mmm packages/apps/Camera2/
    或者等价于
    1.源代码目录下执行source build/envsetup.sh脚本设置环境
    2.先切换目录cd packages/apps/Camera2/
    3.执行mm
    最后使用make snod重新生成sysem.img步骤:
    1.source build/envsetup.sh
    2.lunch 然后选择2		#选择2是选择和编译整个系统时的选择一致。
    3.make snod		        #先执行lunch,不然make snod报错build_image.py - ERROR。
    
  8. 清理编译中间产物,以便重新开始编译
    1、在源码目录的根目录下,执行make clean;
    2、进到源码的linuxkernel目录下,执行make mrproper;
    3、再退回到根目录,执行source build/envsetup.sh, lunch, make -j16;
    
  9. androidstudio查看android系统源代码
    1.整个Android源码编译成功之后,使用mmm单独编译idegen模块,生成Android studio工程配置文件,编译成功之后生成idegen.jar:
    source build/envsetup.sh
    mmm development/tools/idegen/      #如果事先没有编译整个Android源代码而直接编译idegen模块也是可以的,只要将mmm命令改为mmma命令就可以。mmma命令会编译依赖项,mmm则不会。
    
    2.执行下面命令,源码根目录生成对应的android.ipr、android.iml IEDA工程配置文件:
    . development/tools/idegen/idegen.sh
    
    3.此时如果直接使用Android studio打开android.ipr,会特别慢,因为太多东西了,一直在索引。所以打开之前我们需要编辑一下android.iml配置文件。
    3-1.sudo chmod 777 android.iml	#先给编辑权限
    3-2.删除多余的orderEntry。全部excludeFolder或者多加一个frameworks的吧,都可以,后面可以改。
    		配置大概如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <module relativePaths="true" type="JAVA_MODULE" version="4">
    <component name="FacetManager">
     <facet type="android" name="Android">
       <configuration />
     </facet>
    </component>
    <component name="NewModuleRootManager" inherit-compiler-output="true">
     <exclude-output />
     <content url="file://$MODULE_DIR$">
       <sourceFolder url="file://$MODULE_DIR$/frameworks/base" isTestSource="false" />
       <excludeFolder url="file://$MODULE_DIR$/.repo" />
       <excludeFolder url="file://$MODULE_DIR$/BUILD" />
       <excludeFolder url="file://$MODULE_DIR$/art" />
       <excludeFolder url="file://$MODULE_DIR$/bionic" />
       <excludeFolder url="file://$MODULE_DIR$/bootable" />
       <excludeFolder url="file://$MODULE_DIR$/compatibility" />
       <excludeFolder url="file://$MODULE_DIR$/cts" />
       <excludeFolder url="file://$MODULE_DIR$/dalvik" />
       <excludeFolder url="file://$MODULE_DIR$/developers" />
       <excludeFolder url="file://$MODULE_DIR$/development" />
       <excludeFolder url="file://$MODULE_DIR$/device" />
       <excludeFolder url="file://$MODULE_DIR$/external" />
       <excludeFolder url="file://$MODULE_DIR$/frameworks/av" />
       <excludeFolder url="file://$MODULE_DIR$/frameworks/base/apct-tests" />
       <excludeFolder url="file://$MODULE_DIR$/frameworks/base/docs" />
       <excludeFolder url="file://$MODULE_DIR$/frameworks/compile" />
       <excludeFolder url="file://$MODULE_DIR$/frameworks/ex" />
       <excludeFolder url="file://$MODULE_DIR$/frameworks/hardware" />
       <excludeFolder url="file://$MODULE_DIR$/frameworks/layoutlib" />
       <excludeFolder url="file://$MODULE_DIR$/frameworks/libs" />
       <excludeFolder url="file://$MODULE_DIR$/frameworks/minikin" />
       <excludeFolder url="file://$MODULE_DIR$/frameworks/multidex" />
       <excludeFolder url="file://$MODULE_DIR$/frameworks/native" />
       <excludeFolder url="file://$MODULE_DIR$/frameworks/opt" />
       <excludeFolder url="file://$MODULE_DIR$/frameworks/proto_logging" />
       <excludeFolder url="file://$MODULE_DIR$/frameworks/rs" />
       <excludeFolder url="file://$MODULE_DIR$/frameworks/wilhelm" />
       <excludeFolder url="file://$MODULE_DIR$/hardware" />
       <excludeFolder url="file://$MODULE_DIR$/kernel" />
       <excludeFolder url="file://$MODULE_DIR$/libcore" />
       <excludeFolder url="file://$MODULE_DIR$/libnativehelper" />
       <excludeFolder url="file://$MODULE_DIR$/out" />
       <excludeFolder url="file://$MODULE_DIR$/packages" />
       <excludeFolder url="file://$MODULE_DIR$/pdk" />
       <excludeFolder url="file://$MODULE_DIR$/platform_testing" />
       <excludeFolder url="file://$MODULE_DIR$/prebuilt" />
       <excludeFolder url="file://$MODULE_DIR$/prebuilts" />
       <excludeFolder url="file://$MODULE_DIR$/sdk" />
       <excludeFolder url="file://$MODULE_DIR$/system" />
       <excludeFolder url="file://$MODULE_DIR$/test" />
       <excludeFolder url="file://$MODULE_DIR$/toolchain" />
       <excludeFolder url="file://$MODULE_DIR$/tools" />
     </content>
     <orderEntry type="sourceFolder" forTests="false" />
     <orderEntry type="inheritedJdk" />
    </component>
    </module>
    
    4.此时打开Android studio,点击File --> Open,选择生成的android.ipr打开即可。打开应该很快。
    
    5. 第三步不是几乎都excludeFolder了吗?这里说明一下如何设置sdk和更改excludeFolder状态。
      1.Project Structure -> Project -> 设置SDk为android api xxx platform对应sdk版本。
      2.Project Structure -> Modules -> android -> Sources下可以看到上面配置的excludeFolder。在Sources栏目下选择自己想看的模块比如framworks,右键->有Sources、Excluded等等,自己选择切换。
     如果是Excluded了再点击Excluded会取反。取消Excluded选择Sources,然后点击apply,androidstudio会更新索引。剩下的靠自己慢慢摸索了。
      3.AndroidStudio->Preferences->Editor->General->Editor Tabs->Mark Modified勾选上,文件有修改时,对应tabs窗口有*提示,避免有改动不知道。
    

android 系统映射文件说明

img名称 作用
boot.img 内核引导启动有关镜像
ramdisk.img 文件系统有关镜像,包含android系统文件根目录等
system.img android系统核心镜像,包含framework、系统app等,挂载在/system下
userdata.img 应用程序数据镜像,挂载在/data下
cache.img 临时数据存放镜像

遇到的问题

  1. 错误1 - LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection

    输入以下命令,移除代理,再执行命令
    git config --global --unset http.proxy
    
  2. 错误2 - 找不到高通芯片有关的符号连接

    internal error: could not open symlink hardware/qcom/sm8150p/Android.bp; its target (gps/os_pickup.bp) cannot be opened
    internal error: could not open symlink hardware/qcom/sm7250/Android.bp; its target (gps/os_pickup.bp) cannot be opened
    internal error: could not open symlink hardware/qcom/sm7150/Android.bp; its target (gps/os_pickup.bp) cannot be opened
    internal error: could not open symlink hardware/qcom/sm8150/Android.bp; its target (data/ipacfg-mgr/os_pickup.bp) cannot be opened
    

    解决方法:

    实际是空的文件,使用rm直接删除上面几个Android.bp文件
    比如rm hardware/qcom/sm8150p/Android.bp
    
  3. 错误3 - 没有对应支持的sdk版本

    internal error: Could not find a supported mac sdk: ["10.10" "10.11" "10.12" "10.13" "10.14"]
    

    解决方法:

    #来到sdk目录下
    cd /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
    #ls 查看所有可用的sdk
    DriverKit20.2.sdk	MacOSX.sdk		MacOSX11.1.sdk		#发现只有11.1的,没有支持的sdk,那就添加
    
    vim build/soong/cc/config/x86_darwin_host.go 编辑host文件,添加11.1,如下:
    		darwinSupportedSdkVersions = []string{
    			"10.10",
    			"10.11",
    			"10.12",
    			"10.13",
    			"10.14",
    			"11.1",
    		}
    
  4. 错误4 - 找不到高通芯片有关的文件或目录

    FAILED: 
    hardware/qcom/sdm845/Android.mk:1: error: hardware/qcom/sm7150/Android.mk: No such file or directory
    

    解决方法:

     实际是空的目录,直接删除该目录:rm -rf hardware/qcom/sm7150
    
  5. 错误5 - 出现这个原因可能和sdk版本有关

    system/core/base/cmsg.cpp:78:21: error: use of undeclared identifier 'PAGE_SIZE'
    if (cmsg_space >= PAGE_SIZE) {
    

    解决方法:

    vim system/core/base/cmsg.cpp 编辑cmsg.cpp文件,添加PAGE_SIZE宏定义。
    #define PAGE_SIZE 4096
    
  6. 错误6 - python2旧版本兼容mac的问题

    external/python/cpython2/Modules/getpath.c:414:50: error: incompatible pointer types passing 'unsigned long *' to parameter of type 'uint32_t *' (aka 'unsigned int *') [-Werror,-Wincompatible-pointer-types]
    else if(0 == _NSGetExecutablePath(progpath, &nsexeclength) && progpath[0] == SEP)
                                            ^~~~~~~~~~~~~
    /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/usr/include/mach-o/dyld.h:98:54: note: passing argument to parameter 'bufsize' here
    extern int _NSGetExecutablePath(char* buf, uint32_t* bufsize)                 __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_2_0);
    

    解决方法:

    vim external/python/cpython2/Modules/getpath.c 编辑getpath.c文件,添加头文件引入。
    #include <AvailabilityMacros.h>
    
  7. 错误7 - etc测试文件兼容问题,直接设置为忽略

    Segmentation fault: 11  ( out/host/darwin-x86/bin/sepolicy_tests -l out/host/darwin-x86/lib64/libsepolwrap.dylib -f out/target/product/generic_arm64/obj/ETC/plat_file_contexts_intermediates/plat_file_contexts -f out/target/product/generic_arm64/obj/ETC/vendor_file_contexts_intermediates/vendor_file_contexts -p out/target/product/generic_arm64/obj/ETC/sepolicy_intermediates/sepolicy )
    

    解决方法:

    make SELINUX_IGNORE_NEVERALLOWS=true
    
原文地址:https://www.cnblogs.com/yongfengnice/p/14255357.html