sky’s 雑記

主にAndroidとサーバーサイドの技術について記事を書きます

Android SDK platform toolsを手元でビルドするときの覚書

droidkaigiのissueにあがってたSHA256withDSAでapkに署名できない問題を調査したときの派生ネタ。

replace SHA256withRSA debug.keystore by sdsd08013 · Pull Request #536 · DroidKaigi/conference-app-2020 · GitHub

Android SDK platform Tools

android.googlesource.com Android StudioSDK Managerでインストールできるemulatorやsignerなど周辺ツール群のこと。

GitHub - google/bundletool: Bundletool is a command-line tool to manipulate Android App Bundles

今回手元で挙動の調査をしたbundletoolはこのplatform toolsに依存しているのだが、 platform tools自体の挙動を知る必要があったためmaven repoではなくローカルに落としたplatform toolsで bundletoolをビルドする必要があった。

基本的にはgradleのマルチプロジェクトビルドとやることは変わらないが、 別途いくつか気にする点があったのでメモしておく。

手順

依存するplatform toolsプロジェクトをcloneしておく

今回はapkzlib,apksig,baseをビルドに含める必要があったのでgoogle gitのrepoから対象のものをcloneした。 注意する点は各platform toolsのブランチを統一する必要がある点。 これをやらないと依存する側でクラスが見つからなかったりする。 submoduleにしておくとdiffを各プロジェクトごとに管理できて便利。

今回の場合だとbundletoolがapkzlib:3.4.0-beta01に依存するので、 apkzlib,apksig,base全てルートプロジェクトがビルド可能な gradle_3.4.0 ブランチにチェックアウトした。

.
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── apksig -> gradle_3.4.0
├── apkzlib -> gradle_3.4.0
├── base -> gradle_3.4.0
├── build -> gradle_3.4.0
├── build.gradle
├── buildSrc -> gradle_3.4.0
├── bundletool.iml
├── gradle
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
├── settings.gradle
└── src

settings.gradleにcloneしたプロジェクトを宣言する

build.gradleにあるdependenciesをローカルプロジェクトに向ける。 compile "com.android.tools.build:apkzlib:3.4.0-beta01" -> compile project(":apkzlib") といった具合。

platform tools間の依存であれば以下のように元々マルチプロジェクト前提でルートプロジェクトのsettings.gradleにcloneしたプロジェクトの記載があれば自動的にローカルに向くので特に気にすることはない。settings.gradleに定義するプロジェクト名だけ差がないようにする。

build.gradle - platform/tools/apkzlib - Git at Google

include ':apkzlib'
project(':apkzlib').projectDir = new File('./apkzlib')

include ':apksig'
project(':apksig').projectDir = new File('./apksig')

include ':base:testutils'
project(':base:testutils').projectDir = new File('./base/testutils')

include ':base:common'
project(':base:common').projectDir = new File('./base/common')

include ':base:annotations'
project(':base:annotations').projectDir = new File('./base/annotations')

buildSrcをcloneしておいたほうが良い

platform toolsのルートディレクトリにあるbuildSrcに各platform toolsのgradleが依存してる場合が多いのでcloneしておく。

platform/tools/buildSrc - Git at Google

ビルドする

gradleプロジェクトを実行可能なjarファイルにする。 通常は以下のコマンドでjarファイルが生成される。 ./gradlew build

が、bundletoolにおいては上記は失敗した。 build.gradleにビルドタスクが定義されていたのでそちらを実行して無事jarファイルが生成できた。

./gradlew executableJar

大規模なプロジェクトだとビルドは秘伝のタレ化しているのか、 上手くビルドできないときはgit repoやbuild.gradleにビルドコマンド的なものがないか探すと良いかも知れない。

以上。