Mac AOSP 源码下载、编译、踩坑记录

根据官方文档重要提示: 从 2021 年 6 月 22 日起,MacOS 已经不被支持了,建议用 Linux 编译。

  • 环境准备
  • 下载源码
  • 编译
  • 踩坑记录

环境准备

由于 Mac OS 的默认文件系统是保留大小写但不区分大小写的,而 Git 不支持此类文件系统,并且此类系统会导致某些 Git 命令的行为出现异常。所以要先创建一个区分大小写的磁盘映像,以便后面对 AOSP 源文件进行操作。

创建磁盘映像的方式有两种:

第一种:使用系统自带的【磁盘工具】创建,注意要选择 “Case sensitive, Journaled”(区分大小写,日志式)的存储卷格式。

第二种:使用 shell 命令创建:

hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 150g ~/android.dmg

上面的命令将创建一个 150G 大小的磁盘映像,如果以后需要扩容,可以使用下面的命令:

hdiutil resize -size <new-size-you-want>g ~/android.dmg.sparseimage

无论使用哪种方式都将创建一个 .dmg(也可能是 .dmg.sparseimage)文件,该文件在装载后可用作具有 Android 开发所需格式的存储卷。

下载源码

  • 安装 Repo
  • 下载代码

安装 Repo

mkdir ~/bin
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
// 如果上面的请求失败可以换清华的镜像
//curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -o repo
chmod a+x ~/bin/repo

下载源码

首先要挂载上面创建的区分大小写的磁盘映像,并在终端种进入该目录。

创建工作目录:

mkdir WORKING_DIRECTORY
cd WORKING_DIRECTORY

初始化 Repo:

运行 repo init 以获取最新版本的 Repo 及其最近的所有错误更正内容。同时指定一个网址,该网址用于指定 Android 源代码中包含的各个代码库将位于工作目录中的什么位置。

repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest

上面的命令默认使用的是 “master” 分支,如果需要某个特定的 Android 版本,可以使用下面的命令(以android-11.0.0_r40 为例)。

repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-11.0.0_r40

初始化成功后,系统将显示一条消息,告诉您 Repo 已在工作目录中完成初始化。客户端目录中现在应包含一个 .repo 目录,清单等文件将保存在该目录下。

接下来就可以开始下载 Android 源代码了,运行如下命令:

repo sync

以后更新代码同样也是使用上面的命令进行更新。

编译

初始化环境:

在 WORKING_DIRECTORY 目录下,执行 `envsetup.sh` 脚本初始化环境(每次重新打开终端都要初始化环境)。

source build/envsetup.sh

清理之前编译的输出文件:

make clobber

选择编译目标:

lunch

执行上面的命令后,终端会输出如下提示信息:

You're building on Darwin

Lunch menu... pick a combo:
     1. aosp_arm-eng
     2. aosp_arm64-eng
     3. aosp_blueline-userdebug
     4. aosp_blueline_car-userdebug
     5. aosp_bonito-userdebug
     6. aosp_bonito_car-userdebug
     7. aosp_bramble-userdebug
     8. aosp_car_arm-userdebug
     9. aosp_car_arm64-userdebug
     10. aosp_car_x86-userdebug
     11. aosp_car_x86_64-userdebug
     12. aosp_cf_arm64_auto-userdebug
     13. aosp_cf_arm64_phone-userdebug
     14. aosp_cf_x86_64_phone-userdebug
     15. aosp_cf_x86_auto-userdebug
     16. aosp_cf_x86_phone-userdebug
     17. aosp_cf_x86_tv-userdebug
     18. aosp_coral-userdebug
     19. aosp_coral_car-userdebug
     20. aosp_crosshatch-userdebug
     21. aosp_crosshatch_car-userdebug
     22. aosp_flame-userdebug
     23. aosp_flame_car-userdebug
     24. aosp_redfin-userdebug
     25. aosp_sargo-userdebug
     26. aosp_sunfish-userdebug
     27. aosp_trout_arm64-userdebug
     28. aosp_trout_x86-userdebug
     29. aosp_x86-eng
     30. aosp_x86_64-eng
     31. arm_krait-eng
     32. arm_v7_v8-eng
     33. armv8-eng
     34. armv8_kryo385-eng
     35. beagle_x15-userdebug
     36. beagle_x15_auto-userdebug
     37. car_x86_64-userdebug
     38. db845c-userdebug
     39. fuchsia_arm64-eng
     40. fuchsia_x86_64-eng
     41. hikey-userdebug
     42. hikey64_only-userdebug
     43. hikey960-userdebug
     44. hikey960_tv-userdebug
     45. hikey_tv-userdebug
     46. pixel3_mainline-userdebug
     47. poplar-eng
     48. poplar-user
     49. poplar-userdebug
     50. qemu_trusty_arm64-userdebug
     51. silvermont-eng
     52. uml-userdebug
     53. yukawa-userdebug
     54. yukawa_sei510-userdebug

Which would you like? [aosp_arm-eng]

选择一个目标,或直接回车默认选项 aosp_arm-eng,输出如下:

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=11
TARGET_PRODUCT=aosp_arm
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
TARGET_CPU_VARIANT=generic
HOST_ARCH=x86_64
HOST_OS=darwin
HOST_OS_EXTRA=Darwin-20.6.0-x86_64-11.5.2
HOST_BUILD_TYPE=release
BUILD_ID=RQ3A.210805.001.A1
OUT_DIR=out
PRODUCT_SOONG_NAMESPACES=device/generic/goldfish device/generic/goldfish-opengl hardware/google/camera hardware/google/camera/devices/EmulatedCamera device/generic/goldfish device/generic/goldfish-opengl
============================================

编译代码:

使用 make 编译代码,GNU Make 可以借助 -jN 参数处理并行任务,通常使用的任务数 N 介于编译时所用计算机上硬件线程数的 1-2 倍之间。

make -j8

执行上面的命令后,开始编译,输出

17:18:59 ************************************************************
17:18:59 You are building on a machine with 16GB of RAM
17:18:59
17:18:59 The minimum required amount of free memory is around 16GB,
17:18:59 and even with that, some configurations may not work.
17:18:59
17:18:59 If you run into segfaults or other errors, try reducing your
17:18:59 -j value.
17:18:59 ************************************************************
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=11
TARGET_PRODUCT=aosp_arm
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
TARGET_CPU_VARIANT=generic
HOST_ARCH=x86_64
HOST_OS=darwin
HOST_OS_EXTRA=Darwin-20.6.0-x86_64-11.5.2
HOST_BUILD_TYPE=release
BUILD_ID=RQ3A.210805.001.A1
OUT_DIR=out
PRODUCT_SOONG_NAMESPACES=device/generic/goldfish device/generic/goldfish-opengl hardware/google/camera hardware/google/camera/devices/EmulatedCamera device/generic/goldfish device/generic/goldfish-opengl
============================================

编译idegen模块倒入 Android Studio

使用

如下命令编译idegen模块:

mmm development/tools/idegen/

运行完以后如果看到如下信息:

make completed successfully (21 seconds) ####

接着执行如下脚本:

development/tools/idegen/idegen.sh

这行命令的意思是在根目录生成对应的 android.ipr、android.iml IEDA工程配置文件。等待片刻得到类似如下信息说明OK:

Read excludes: 27ms
Traversed tree: 308243ms

接下来就可以打开 Android Studio,打开 android.iml 文件就 OK了。

踩坑记录

问题一:Could not find a supported mac sdk

错误日志如下:

[ 94% 171/181] test android/soong/cc
FAILED: out/soong/.bootstrap/soong-cc/test/test.passed
out/soong/.bootstrap/bin/gotestrunner -p ./build/soong/cc -f out/soong/.bootstrap/soong-cc/test/test.passed -- out/soong/.bootstrap/soong-cc/test/test -test.short
--- FAIL: TestDefaults (10.86s)
    cc_test.go:3075: "Could not find a supported mac sdk: [\"10.10\" \"10.11\" \"10.12\" \"10.13\" \"10.14\" \"10.15\"]"
    cc_test.go:3075: "Could not find a supported mac sdk: [\"10.10\" \"10.11\" \"10.12\" \"10.13\" \"10.14\" \"10.15\"]"
    cc_test.go:3075: "Could not find a supported mac sdk: [\"10.10\" \"10.11\" \"10.12\" \"10.13\" \"10.14\" \"10.15\"]"
    cc_test.go:3075: "Could not find a supported mac sdk: [\"10.10\" \"10.11\" \"10.12\" \"10.13\" \"10.14\" \"10.15\"]"
    cc_test.go:3075: "Could not find a supported mac sdk: [\"10.10\" \"10.11\" \"10.12\" \"10.13\" \"10.14\" \"10.15\"]"
    cc_test.go:3075: "Could not find a supported mac sdk: [\"10.10\" \"10.11\" \"10.12\" \"10.13\" \"10.14\" \"10.15\"]"
--- FAIL: TestDoubleLoadbleDep (0.05s)
    cc_test.go:733: "Could not find a supported mac sdk: [\"10.10\" \"10.11\" \"10.12\" \"10.13\" \"10.14\" \"10.15\"]"
..... 省略 ....
FAIL
17:19:34 soong bootstrap failed with: exit status 1
ninja: build stopped: subcommand failed.

#### failed to build some targets (36 seconds) ####

问题原因是:找不到制定的 mac sdk。

解决办法:首先按照下面的方法查看自己电脑上的 mac sdk:

cd /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
ls

会打印出当前 XCode 提供的 SDK 版本号,如下:

DriverKit20.4.sdk MacOSX.sdk        MacOSX11.3.sdk

然后在 /build/soong/cc/config/x86_darwin_host.go 文件中找到 “darwinSupportedSdkVersions“ 添加 MacOSX11.3.sdk 对应的版本号——11.3。

darwinSupportedSdkVersions = []string{
		"10.10",
		"10.11",
		"10.12",
		"10.13",
		"10.14",
		"10.15",
		"11.3",
}

问题二:too many open files

错误日志如下:

FAILED: out/soong/build.ninja
out/soong/.bootstrap/bin/soong_build -t -l out/.module_paths/Android.bp.list -b out/soong -n out -d out/soong/build.ninja.d -globFile out/soong/.bootstrap/build-globs.ninja -o out/soong/build.ninja Android.bp
error: prebuilts/sdk/Android.bp:25:1: module "metalava-sdk-android-jars": glob: fcntl: too many open files
error: external/v8/Android.bp:181:16: module "v8_bytecode_builtins_list_generator" variant "darwin_x86_64": host_ldlibs: Host library `-lrt` not available
error: system/timezone/distro/tools/Android.bp:16:1: module "create_time_zone_distro" variant "darwin_common": glob: open /Volumes/AOSP/WORKING_DIRECTORY/system/timezone/distro/tools/src/main/com/android/timezone: too many open files
error: cts/tools/vm-tests-tf/Android.bp:58:1: module "vmtests-dfh-dex-generated" variant "darwin_common": glob: fcntl: too many open files
.......

主要原因是打开了太多文件,这个问题和当前系统的配置有关,可以先用命令查看当前的限制:

launchctl limit

结果如下:

        名称         软件限制         硬件限制
	cpu         unlimited      unlimited
	filesize    unlimited      unlimited
	data        unlimited      unlimited
	stack       8388608        67104768
	core        0              unlimited
	rss         unlimited      unlimited
	memlock     unlimited      unlimited
	maxproc     2784           4176
	maxfiles    256            10240

其中 maxfiles 就是同时可以打开文件的最大数,解决办法,把这个值改大点:

在 /Library/LaunchDaemos 目录下,新建两个文件:limit.maxfiles.plist 和 limit.maxproc.plist,并且修改两个文件的用户为 root,内容如下,添加完后重启电脑生效:

limit.maxfiles.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
    <dict>
      <key>Label</key>
        <string>limit.maxfiles</string>
      <key>ProgramArguments</key>
        <array>
          <string>launchctl</string>
          <string>limit</string>
          <string>maxfiles</string>
          <string>65536</string>
          <string>65536</string>
        </array>
      <key>RunAtLoad</key>
        <true/>
      <key>ServiceIPC</key>
        <false/>
    </dict>
</plist>

limit.maxproc.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple/DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
    <dict>
      <key>Label</key>
        <string>limit.maxproc</string>
      <key>ProgramArguments</key>
        <array>
          <string>launchctl</string>
          <string>limit</string>
          <string>maxproc</string>
          <string>2048</string>
          <string>2048</string>
        </array>
      <key>RunAtLoad</key>
        <true />
      <key>ServiceIPC</key>
        <false />
    </dict>
</plist>

问题三:host_ldlibs: Host library `-lrt` not available

[100% 181/181] out/soong/.bootstrap/bin/soong_build out/soong/build.ninja
FAILED: out/soong/build.ninja
out/soong/.bootstrap/bin/soong_build -t -l out/.module_paths/Android.bp.list -b out/soong -n out -d out/soong/build.ninja.d -globFile out/soong/.bootstrap/build-globs.ninja -o out/soong/build.ninja Android.bp
error: external/v8/Android.bp:181:16: module "v8_bytecode_builtins_list_generator" variant "darwin_x86_64": host_ldlibs: Host library `-lrt` not available
error: external/v8/Android.bp:209:16: module "v8_torque" variant "darwin_x86_64": host_ldlibs: Host library `-lrt` not available
19:17:37 soong bootstrap failed with: exit status 1

#### failed to build some targets (01:55 (mm:ss)) ####

问题原因:https://stackoverflow.com/questions/47703239/ld-library-not-found-for-lrt

在旧的 Linux 系统中有 -lrt 供 GNU libc 使用,但是在新的 glibc(after 2.17 from 2013) 之后就没有这个了。所以,把 -lrt 从 Makefile 中删除即可。

问题四:undeclared identifier ‘PAGE_SIZE’

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

想不明白,为什么这么明显的 BUG 官方居然还放出来,解决办法是在 system/core/base/cmsg.cpp 文件开头添加 PAGE_SIZE 的声明:

#ifndef PAGE_SIZE
#define PAGE_SIZE (size_t)(sysconf(_SC_PAGESIZE))
#endif

https://stackoverflow.com/questions/65540625/failed-to-build-targets-for-aosip-use-of-undeclared-identifier-page-size-insy

问题五:incompatible pointer types passing ‘unsigned long *’ to parameter of type ‘uint32_t *‘

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)

把 external/python/cpython2/Modules/getpath.c 中:

#ifdef __APPLE__
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
    uint32_t nsexeclength = MAXPATHLEN;
#else
    unsigned long nsexeclength = MAXPATHLEN;
#endif
#endif

改成

#ifdef __APPLE__
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
    unsigned long nsexeclength = MAXPATHLEN;
#endif

同时把 external/python/cpython3/Modules/getpath.c 中修改:

#ifdef __APPLE__
    char execpath[MAXPATHLEN + 1];
    uint32_t nsexeclength = Py_ARRAY_LENGTH(execpath) - 1;
#endif

https://stackoverflow.com/questions/65540625/failed-to-build-targets-for-aosip-use-of-undeclared-identifier-page-size-insy

问题六:’sys/prctl.h’ file not found

external/v8/src/base/platform/platform-linux.cc:13:10: fatal error: 'sys/prctl.h' file not found
#include <sys/prctl.h>

工程目录下全局搜索 “platform-linux”,并把 “platform-linux.cc” 改为 “platform-macos.cc”。涉及到的文件有:

  • external/v8/Android.libbase.bp
  • external/v8/BUILG.gn
  • external/v8/genmakefiles.py

问题七:’mach/mach_init.h’ file not found

external/v8/src/base/platform/platform-macos.cc:9:10: fatal error: 'mach/mach_init.h' file not found
#include <mach/mach_init.h>
         ^~~~~~~~~~~~~~~~~~
1 error generated.
09:30:21 ninja failed with: exit status 1

这个问题有点坑,Mac 系统的头文件是有 XCode 提供的,需要安装 XCode,具体路径为:/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include。

我的解决方式是:把 include 目录下的文件复制到 /Library/Developer/CommandLineTools/usr/include 目录下

export C_INCLUDE_PATH=/Users/xxx/Develop/mac_include/include

参考文章

13条评论

  1. 问题七:

    export C_INCLUDE_PATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include

    还是

    export C_INCLUDE_PATH=/Library/Developer/CommandLineTools/usr/include

    我两个都尝试了,但是’mach/mach_init.h’ file not found

    1. 恭喜你命中了新的问题😂https://source.android.com/setup/build/initializing,切换到英文版(这又是个坑,只有英文版的文档有提示)。
      “Important: Platform development on MacOS isn’t supported as of June 22, 2021.” 所以说,放弃挣扎,用 Linux 吧。

      1. 如果Mac平台不再支持, make sdk 编译不出 mac 平台的 sdk啊, linux只能编译出linux和win的, 我找遍全网都找不到在linux系统中编译出mac平台的sdk

    1. 感谢你分享的解决方案,希望可以帮助到有缘人~~

      当然可以转载,既然都是热爱创作和记录,注明一下转载来源吧,顺便帮忙推荐一下本站哈~~

  2. 问题3,问题6,问题7 这几个错误都是 external/v8 这个项目报错的, 而且我按照楼主的解决方法并没有编译成功, 而且要这样修改文件对源码破坏性也大, 我在这卡了好几天, 最终发现这个项目的2021年提交记录中有一条”Upgrade V8 to 8.8.278.14″ , 所以只要把v8项目还原到前一个提交就可以编译成功, 和v8相关的错误都没有了, 我猜测可能是谷歌在21年放弃了mac编译, 导致后续的更新都没有再兼容mac, 而我又必须在mac下编译出产品. 所以评论记录一下, 给后来的小伙伴一个思路. 楼主的这篇文章太有价值了,对我帮助很大.
    我编译的是魔趣 mkq-mr1, 不同的源码提交记录应该不一样, 使用git log命令查看即可,还原版本命令:
    cd external/v8
    git checkout 507001d1

    macos10.15 和 11 测试编译成功, 最新的12系统我没有测试, 但是问题也应该不大, 另外再忠告一下, 长期做系统开发, 一定要搭建自己的repo源码仓库,给所有仓库建立开发分支, 否则执行一次 repo sync 就更新一次代码, 说不定就编译不了了

  3. ’mach/mach_init.h’ file not found

    尝试了各种链接到 include都不行,最后直接把:/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/mach 目录链接到:android-11.0.0_r46/external/v8/src/base/platform 正在编译中再有问题再说吧,一步一个坑。fuck。

  4. wow… what a great blog, this writter who wrote this article it’s realy a great blogger, this article so inspiring me to be a better person

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注