AOSP 项目是如何构建的?

问题描述

AOSP 的所有 git 项目都由 repo 工具克隆,该工具读取此 xml:https://android.googlesource.com/platform/manifest/+/refs/heads/master/default.xml

AOSP guide 表示为了构建,我们应该在 repo 克隆所有存储库的文件夹上运行 source build/envsetup.sh。因此,让我们看看清单存储库中 default.xml 上的 platform/build。我们得到

  <project path="build/make" name="platform/build" groups="pdk" >
    <copyfile src="core/root.mk" dest="Makefile" />
    <linkfile src="CleanSpec.mk" dest="build/CleanSpec.mk" />
    <linkfile src="buildspec.mk.default" dest="build/buildspec.mk.default" />
    <linkfile src="core" dest="build/core" />
    <linkfile src="envsetup.sh" dest="build/envsetup.sh" />
    <linkfile src="target" dest="build/target" />
    <linkfile src="tools" dest="build/tools" />
  </project>

我们确认哪里envsetup.sh is located.,它在platform/build。它定义了函数 m,根据 AOSP 指南,该函数构建了整个 AOSP 项目:

function _trigger_build()
(
    local -r bc="$1"; shift
    if T="$(gettop)"; then
      _wrap_build "$T/build/soong/soong_ui.bash" --build-mode --${bc} --dir="$(pwd)" "$@"
    else
      echo "Couldn't locate the top of the tree. Try setting TOP."
    fi
)
function m()
(
    _trigger_build "all-modules" "$@"
)

好的,看起来 build/soong/soong_ui.bash 是我们运行 m 函数调用的地方,所以这个脚本应该构建一切。

这是soong_ui.bash。它获取 source ${TOP}/build/soong/scripts/microfactory.bash 然后调用 soong_build_go soong_ui android/soong/cmd/soong_ui

这里是 microfactory.bash,我们在这里找到函数 soong_build_go

soong_build_go
{
    BUILDDIR=$(getoutdir) \
      SRCDIR=${TOP} \
      BLUEPRINTDIR=${TOP}/build/blueprint \
      EXTRA_ARGS="-pkg-path android/soong=${TOP}/build/soong -pkg-path github.com/golang/protobuf=${TOP}/external/golang-protobuf" \
      build_go $@
}

我们在 microfactory.bash from build/blueprint 中找到 build_go

看起来所有这些都是为了构建 microfactory.go 项目。我认为这与 soong 构建系统有关。

我现在迷路了。构建 microfactory.go 后,会发生什么?实际的 Android 代码是在哪里构建的?

microfactory.sh 说 build_go 这样做:Bootstrap microfactory from source if necessary and use it to build the requested binary. 请求的二进制文件android/soong/cmd/soong_ui

我试图找到 android/soong/cmd/soong_ui,但我不知道它是什么/在哪里,但我猜是很快的构建系统,而不是 AOSP 项目。

更新:

soong_ui.bash,我注意到它以

结尾
cd ${TOP}
exec "$(getoutdir)/soong_ui" "$@"

请记住,这称为表单 envsetup.sh。好吧,我想,${TOP} 是 repo 克隆一切的地方。看起来它正在尝试使用来自 soong_ui 的参数执行 envsetup.sh,它们是 --build-mode --${bc} --dir="$(pwd)" "$@",我猜这个 $@ "all-modules" "$@"

我假设 song_ui 是 soong 可执行文件。它应该在 Android.bp 上寻找 ${TOP},但我认为 repo 克隆所有内容的地方没有。

解决方法

您已经发现了很多东西,从 msoong_ui.bash 然后开始 microfactory 的链接是正确的。

从我对代码的阅读来看,soong_build_go 的目的是构建包 android/soong/cmd/soong_ui,二进制名称为 soong_ui。正如 Yong 在另一个答案中所说,这会在目录 $(getoutdir) 下创建二进制文件 soong_ui,该二进制文件的源位于 build/soong/cmd/soong_ui/main.go

至于您更新的有关 Android.bp 文件的问题,当运行 repo sync 时,它是 symlinked 中的 build/soong/root.bp,但如您所见,该文件是空的。

相反,在 m 中,它告诉 Soong 构建 all_modules,后者最终运行另一个名为 kati 的工具。根据 https://github.com/google/kati 中的描述,Kati 处理 GNU makefile 并将它们转换为 Ninja 构建文件。

此时我们可以(大部分)假设常规 Make 语义,即使底层构建系统实际上是 Kati、Ninja 和 Soong 等。由于工作目录是 $TOP,因此 Makefile 在使用从 build/make/core/root.mk 符号链接的根目录。其中包括 main.mk,然后包括 build/make/core/Makefile。在该 makefile 中,您可以看到不同的 .img 文件是如何构建的(例如 system.img)。

,

我们以make systemimage为例:

调用顺序为:

  1. prebuilts/build-tools/linux-x86/bin/makeparallel --ninja build/soong/soong_ui.bash --make-mode "systemimage"。 $(getoutdir)/soong_ui 是由“build_go soong_ui android/soong/cmd/soong_ui”构建的
  2. build/soong/cmd/soong_ui/main.go#main()
  3. soong/ui/build/build.go#Build()