Win10下编译Android Gradle Plugin + D8

1,077 阅读1分钟

背景

因为要支持Android4.4, 并且要求开启D8编译.

由于D8与dx不同, d8生成dex时, 不会过滤注解方法,

所以maindex的方法数会超. 导致当 minSdkVersion<21 时编译失败.

所以为了同时支持Android4.4 和D8. 就需要改动d8的源码,

编译生成可以过滤注解方法的d8编译工具.

准备

Win10下安装 WSL. WSL里安装Ubutu

AOSP的AGP编译说明: The Android Gradle Plugin

本篇只是编译Android Gradle Plugin (AGP). 和 D8 & R8

AGP

下载好AGP源码后.

$ cd path/of/gradle_src

链接bazel到bin下, 方便使用

$ ln -s path/of/gradle_src/tools/base/bazel/bazel ~/bin/bazel

下载预编译文件

AGP的源码需要依赖系统下载android sdk. 避免不必要的编译.
相关的编译方法在gradle_root/tools/base/bazel/sdk/README.md中. 或者在 这里 查看

  1. 修改tools/base/bazel/toplevel.WORKSPACE 删除blaze相关内容 上传成功 如果不删除会提示
    ERROR: error loading package '': Encountered error while reading extension file 'binds.bzl': no such package '@blaze//':

  2. 修改tools/base/bazel/sdk/dev-sdk-packages, 注释掉docs那一行 上传成功 如果不注释会提示Warning: Failed to find package docs 然后停止下载

  3. prebuilts/studio/sdk下新建三个文件夹

    $ mkdir darwin
    $ mkdir linux
    $ mkdir windows
    

    如果不注释会提示错误: doesn't contain expected subdir: darwin

    • 补充:
      这三个文件夹里分别放对应平台的sdk预编译文件.
      但是其实并没有必要mac/linux/win三个平台的sdk都下载, 只要下载当前OS的即可.
      虽然是win10的机器, 但是实际跑在WSL里的Ubuntu, 所以只要新建'linux'文件即可,
      然后对tools/base/bazel/sdk/src/com/android/tools/utils/DevSdkUpdater.java做如下修改:
      downloadSdkPackages(sdkDest, packageLines, "linux");//platform => "linux"
      
      之后再执行第4步骤:
  4. 下载预编译文件:

    $ bazel run tools/base/bazel/sdk:dev-sdk-updater
    
    • 补充
      应该也可以通过bazel run来指定--platform linux, 避免改动java源码, 但是我没有找到怎么传参.

编译AGP

预编译下载完成后就可以编译了 详细编译命令:

$ cd tools
$ ./gradlew :publishAndroidGradleLocal

Android Gradle Plugin with the data binding runtime libraries:

$ ./gradlew :publishLocal

编译成功:
编译输出在out\repo目录下


----

R8 & D8

R8 & D8 虽然是两个模块, 但是都在同一个源码里.所以是一起编译的
R8 & D8 和GAP的源码是分开的, 所以如果要改动R8或者D8, 需要先独立编译出R8&D8, 然后更新到GAP的prebuilts/r8/下, 再编译GAP

下载R8源码:

$ cd /your/workspace/
$ git clone https://r8.googlesource.com/r8

或者

$ git clone https://android.googlesource.com/platform/external/r8

或者清华的镜像(但是后来发现, 清华的源很旧了, 一两年不更新那种)

$ git clone https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/external/r8

下载depot_tools

r8 使用 depot_tools编译.需要代理, 没找到国内镜像

$ cd /your/workspace/
$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

添加环境变量:

export PATH=path/of/depot_tools:$PATH

下载编译依赖:

$ cd path/of/r8/

下载gradle

查看需要下载的gradle 的 hash值

$ cat third_party/gradle/gradle.tar.gz.sha1

下载

$ wget -O third_party/gradle/gradle.tar.gz https://storage.googleapis.com/r8-deps/<刚才cat出的内容>

解压gradle.tar.gz, 检查文件树应当如下

gradle
└─gradle.tar.gz   <--下载的压缩包
└─gradle.tar.gz.sha1   <--存放hash的原始文件
└─gradle   <--被解压出来的目录
    ├─bin
    ├─init.d
    ├─lib
    └─media
    └─getting-started.html
    └─LICENSE
    └─NOTICE

更新gradle.tar.gz文件的修改时间

$ touch third_party/gradle/gradle.tar.gz

下载jdk

查看 jdk 的 hash值

$ cat third_party/openjdk/openjdk-9.0.4/linux.tar.gz.sha1

下载

$ wget -O third_party/openjdk/openjdk-9.0.4/linux.tar.gz https://storage.googleapis.com/r8-deps/<刚才cat出的内容>

解压linux.tar.gz, 检查文件树应当如下

openjdk-9.0.4
    └─linux.tar.gz.sha1
    └─linux.tar.gz
    └─linux
        ├─bin
        ├─conf
        ...

更新gradle.tar.gz文件的修改时间

$ touch third_party/openjdk/openjdk-9.0.4/linux.tar.gz

补充: 如果有其他文件下载, 可以通过修改tools/utils.pyEnsureDepFromGoogleCloudStorage()方法, 来确认需要下载哪些文件.
修改后, 执行命令

$ tools/gradle.py d8 r8

通过输出确认需要下载的文件hash 和下载链接.

编译

$ tools/gradle.py d8 r8

编译成功

编译输出在build\libs目录下