LoginSignup
20
17

More than 5 years have passed since last update.

Android Studio で Android Framework (AOSP) のソースコードを読む

Posted at

TL;DR

  • macOS上のAndroid StudioでAOSPのソースコードを読む環境を構築したので、方法をシェアします
    • AOSPに含まれる IDEGen というツールでIntelliJ IDEAプロジェクトファイル android.ipr を生成して、Android Studioで開く、というのが基本的な手順です
    • プロジェクトを開いた後、ソースコード間でクラスが適切に参照されるように、SDK構成の設定や、ソースパス・参照順序の調整が必要です

はじめに

Android Open Source Project (AOSP) のソースコードを読む場合、一般的には、Developer Collaboration Project が公開しているAndroidソースコード検索サービスを使うのが便利です。ソースコードをダウンロードする必要もないし、色々なOSバージョンのソースコードをすぐ読めます。OpenGlok というソースコード検索エンジンが使われていて、ソースコードの検索機能も充実しています。

ただ、Android Studioでソースコードを見られれば、クラスやメソッドの参照先・被参照元もさくさく探せて最高なはず。というわけで、Android StudioでAOSPを読む環境を構築しました。

筆者の環境

  • macOS (Sierra: 10.12.4)
  • Android Studio 2.3.1

AOSPソースコードをダウンロードする

まずは、AOSPのソースコードをダウンロードしてきます。

Case-sensitiveなファイルシステムについて

AOSPのビルドにはcase-sensitiveなファイルシステムが必要です。そのため、Establishing a Build Environment に書かれているように、macOSではcase-sensitiveなファイルシステムのディスクイメージを作成し、そこにAOSPのソースコードをダウンロードする必要があります。ただ、ソースコードを読むだけなら別に問題ないだろう、ということで、筆者はmacOSのファイルシステムに直接ソースコードをダウンロードしました (今のところ無問題です)。

repo コマンドのインストール

AOSPのソースコードは多くのGitレポジトリに分かれているので、それらをいい感じにまとめて扱ってくれる repo コマンド (中身はPythonスクリプト) をインストールします。

Downloading the Source で説明されているように、curl コマンドで repo スクリプトをダウンロードするのが定石ですが、Homebrew を使ってもインストールできます。

brew install repo

ソースコードのダウンロード

Downloading the Source の説明に従いつつ、repo コマンドを使ってソースコードをダウンロードします。

デフォルトだと master ブランチのソースコードがダウンロードされますが、タグを指定してダウンロードするのがよいと思います。OSバージョンとタグの関係は Codenames, Tags, and Build Numbers を見るとわかります。

私は、2017年4月14日現在で最新だった android-7.1.2_r6 をダウンロードしました。

# ソースコードを格納するディレクトリを作成し、その中に移動する
mkdir android-7.1.2_r6
cd android-7.1.2_r6

# ブランチ android-7.1.2_r6 を指定して、repo クライアントを初期化する
repo init -u https://android.googlesource.com/platform/manifest -b android-7.1.2_r6

# ソースコードをダウンロードする
repo sync

通信環境にもよりますが、ソースコードのダウンロードには数時間かかります。気長に待ちましょう。

IntelliJ IDEAプロジェクトファイルを生成する

ソースコードがダウンロードできたら、ダウンロードしたソースコードがまるっと含まれる、IntelliJ IDEAプロジェクトファイル (.ipr) ファイルを生成します。IPRファイルの生成には、AOSPに含まれるIDEGenというツールを使います。

基本的には、IDEGenの README に書かれているように、AOSPソースツリーのルートで以下のコマンドを実行するだけです。

make idegen
development/tools/idegen/idegen.sh

が、コマンドを実行する前に、ちょっとだけMakefileを修正します。

ファイルシステムのcase-sensitiveness検査をスキップする

AOSPのソースコードをcase-insensitiveなファイルシステムにダウンロードした場合、そのままだと、Make中に行われる検査にひっかかりエラーとなります。

build/core/main.mk:159: ************************************************************
build/core/main.mk:160: You are building on a case-insensitive filesystem.
build/core/main.mk:161: Please move your source tree to a case-sensitive filesystem.
build/core/main.mk:162: ************************************************************
build/core/main.mk:163: *** Case-insensitive filesystems not supported.

検査にひっかかったとしてもMakeの実行が継続されるように、build/core/main.mk で、Case-insensitive filesystems not supported というエラーメッセージを出力している行をコメントアウトします。

diff --git a/core/main.mk b/core/main.mk
index a612f835d..035788200 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -160,7 +160,7 @@ $(warning ************************************************************)
 $(warning You are building on a case-insensitive filesystem.)
 $(warning Please move your source tree to a case-sensitive filesystem.)
 $(warning ************************************************************)
-$(error Case-insensitive filesystems not supported)
+# $(error Case-insensitive filesystems not supported)
 endif

 # Make sure that there are no spaces in the absolute path; the

android.ipr を生成する

あとは、AOSPソースツリーのルートディレクトリで以下のコマンドを実行してください。実行に成功した場合、同じディレクトリに android.ipr というファイルが生成されます。

make idegen
development/tools/idegen/idegen.sh

筆者は make idegen の実行で何箇所かつまづきました。次の節で、筆者が遭遇した問題とその解決方法を説明しているので、もし同じ問題にぶち当たったら参考にしてください。

make idegen のトラブルシューティング

xcode-select: error と言われる場合

make idegen の実行時に以下のようなエラーメッセージが出る場合

xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance
build/core/combo/mac_version.mk:26: none of the installed SDKs (ac_sdk_versions_installed) match supported versions (10.8 10.9 10.10 10.11), trying 10.8
build/core/combo/mac_version.mk:36: no SDK 10.8 at /Library/Developer/CommandLineTools/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk, trying legacy dir
build/core/combo/mac_version.mk:40: *****************************************************
build/core/combo/mac_version.mk:41: * Can not find SDK 10.8 at /Developer/SDKs/MacOSX10.8.sdk
build/core/combo/mac_version.mk:42: *****************************************************
build/core/combo/mac_version.mk:43: *** Stop..  Stop.

アクティブなデベロッパーディレクトリが、コマンドラインツールのものになっていることが原因です。xcode-select コマンドを使って、デベロッパーディレクトリの場所を Xcode.app 内のディレクトリに変更してください。

sudo xcode-select -s /Applications/Xcode.app/Contents/Developer

インストールされているSDKがない、と言われる場合

make idegen の実行時に以下のようなエラーメッセージが出る場合

build/core/combo/mac_version.mk:26: none of the installed SDKs (ac_sdk_versions_installed) match supported versions (10.8 10.9 10.10 10.11), trying 10.8
build/core/combo/mac_version.mk:36: no SDK 10.8 at /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk, trying legacy dir
build/core/combo/mac_version.mk:40: *****************************************************
build/core/combo/mac_version.mk:41: * Can not find SDK 10.8 at /Developer/SDKs/MacOSX10.8.sdk
build/core/combo/mac_version.mk:42: *****************************************************
build/core/combo/mac_version.mk:43: *** Stop..  Stop.

AOSPのMakefileが前提にしているmacOS SDKのバージョンと、マシンにインストールされているSDKのバージョンが一致していないことが原因です。まず、インストールされているmacOS SDKのバージョンを確認してください。筆者の場合は、10.12のみでした。

$ ls /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
MacOSX.sdk      MacOSX10.12.sdk

このバージョン番号を、build/core/combo/mac_version.mk で定義されている変数 mac_sdk_versions_supported に追加すれば、上記のエラーが発生しなくなります。

diff --git a/core/combo/mac_version.mk b/core/combo/mac_version.mk
index 51394c64b..8fa08c6e6 100644
--- a/core/combo/mac_version.mk
+++ b/core/combo/mac_version.mk
@@ -9,7 +9,7 @@ ifndef build_mac_version

 build_mac_version := $(shell sw_vers -productVersion)

-mac_sdk_versions_supported :=  10.8 10.9 10.10 10.11
+mac_sdk_versions_supported :=  10.8 10.9 10.10 10.11 10.12
 ifneq ($(strip $(MAC_SDK_VERSION)),)
 mac_sdk_version := $(MAC_SDK_VERSION)
 ifeq ($(filter $(mac_sdk_version),$(mac_sdk_versions_supported)),)

could not find jdk tools.jar と言われる場合

make idegen の実行時に以下のようなエラーメッセージが出る場合

build/core/config.mk:601: *** Error: could not find jdk tools.jar at /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/../lib/tools.jar, please check if your JDK was installed correctly.  Stop.

JAVA_HOME に相当するディレクトリのパスを、ANDROID_JAVA_HOME 環境変数として定義してください。

# 設定例
export ANDROID_JAVA_HOME=`/usr/libexec/java_home -v 1.8`

Android StudioでAOSPソースツリーを開く

android.ipr ファイルを指定してプロジェクトを開く

android.ipr ファイルが生成できたら、Android Studioで android.ipr ファイルを開きます。AOSPのルートディレクトリを開くのではなく、そこに配置されている android.ipr ファイルを開くように注意してください。

プロジェクトを開くと、ファイルのインデックスなどでしばらくビジーになるので、処理が終わるのを待ちます。

プロジェクト設定を変更する

開いたプロジェクトはこのままだといくつか問題があるので、メニュー "File" - "Project Structure..." からプロジェクト設定を変更します。

JDKを設定する

"Project Structure" ウィンドウ左部分にある "SDKs" を選択して、このプロジェクトに設定するためのSDK構成を作成します。SDKの種類は "JDK" で、JDK home pathにはマシンにインストールされているJDKのHomeディレクトリを指定してください (/usr/libexec/java_home コマンドで確認できます)。また、AOSPのソースコードからJDKのクラスが参照されないよう、"Classpath" を全て削除します。

Screen Shot 2017-04-16 at 1.08.11.png

新しいSDK構成が作成できたら、それをプロジェクトのSDKとして設定します。ウィンドウ左部分から再度 "Project" を選択して、作成したSDK構成を選択します。

Screen Shot 2017-04-16 at 1.11.07.png

"Android" モジュールを削除する

"Android" という名前のモジュールが自動的に作成されてしまっていますが、不要なので、"Modules" にて削除します。

Screen Shot 2017-04-16 at 1.26.53.png

external/libgdx 内にある emu ディレクトリをソースパスから除外する

external/libgdx 内の emu ディレクトリに格納されているJavaクラスが、libcore-luni が提供するJava標準クラスと衝突しているため、emu ディレクトリをソースパスから除外します。

"Modules" で "android" モジュールを選択した後、"Sources" タブで該当ディレクトリを選択して、 "Excluded" マークをONに変更します。

Screen Shot 2017-04-16 at 1.45.51.png

変更が必要なディレクトリは (筆者がダウンロードした android-7.1.2_r6 ブランチのソースツリーでは) 以下の3つでした。

  • external/libgdx/backends/gdx-backends-gwt/src/com/badlogic/gdx/backends/gwt/emu
  • external/libgdx/extensions/gdx-box2d/gdx-box2d-gwt/src/com/badlogic/gdx/physics/box2d/gwt/emu
  • external/libgdx/extensions/gdx-controllers/gdx-controllers-gwt/src/com/badlogic/gdx/controllers/gwt/emu

ソースコードをJarファイルよりも優先して参照するようにする

AOSPのソースツリーにはJarファイルが多数含まれており、デフォルトでは、それらのJarファイルがソースファイルよりも優先して参照されるようになっています。

このままだと、コードリーディングしているときにソースファイル間を上手くジャンプできないので、ソースファイルが最優先で参照されるように依存順序を変更します。"Modules" で "android" モジュールを選択した後、"Dependencies" タブで依存の順序を変更し、"<Module source>" が最初に参照されるようにします。

Screen Shot 2017-04-16 at 1.52.30.png

気が遠くなるくらい大変なので、Alt+上カーソルキー のショートカットを使うことをお勧めします。

Happy Code Reading!!

これで、一通りのAOSPのソースコードがAndroid Studioで読めるようになります。例えば、Android Studioのナビゲーション機能を使えば、あるクラスを継承しているクラスの一覧、なども簡単に調べられるようになります。

Screen Shot 2017-04-16 at 2.11.28.png

残課題

今回はAOSPソースツリーをビルドしていないので、AIDLファイルから生成されるインターフェースなど、ビルドにより生成されるものが存在しておらず、それらの参照ができない状態なのが残念なところです。

20
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
17