Bazel チュートリアル: Android アプリを作成する

注: Android アプリのビルドに Bazel を使用する場合、既知の制限事項があります。 既知の問題の一覧については、Github チームの Android ホットリストをご覧ください。Bazel チームとオープンソース ソフトウェア(OSS)のコントリビューターは、既知の問題の解決に積極的に取り組んでいますが、Android Studio は公式には Bazel プロジェクトをサポートしていません。

このチュートリアルでは、Bazel を使用して簡単な Android アプリをビルドする方法について説明します。

Bazel は、 Android ルールを使用して Android アプリのビルドをサポートしています。

このチュートリアルは、Windows、macOS、Linux ユーザーを対象としており、Bazel や Android アプリ開発の経験は 必要ありません。このチュートリアルでは、Android コードを 記述する必要はありません。

学習内容

このチュートリアルでは、次の方法について説明します。

  • Bazel と Android Studio をインストールし、 サンプル プロジェクトをダウンロードして環境を設定します。
  • アプリのソースコード と、ワークスペース ディレクトリの最上位レベルを識別する MODULE.bazel ファイルを含む Bazel ワークスペースを設定します。
  • MODULE.bazel ファイルを更新して、Android SDK など、必要な 外部依存関係への参照を含めます。
  • BUILD ファイルを作成します。
  • Bazel でアプリをビルドします。
  • Android エミュレータまたは実機にアプリをデプロイして実行します。

始める前に

Bazel をインストールする

チュートリアルを開始する前に、次のソフトウェアをインストールします。

サンプル プロジェクトを取得する

サンプル プロジェクトには、 Bazel の examples リポジトリにある基本的な Android アプリ プロジェクトを使用します。

このアプリには、クリックするとあいさつを表示するボタンが 1 つあります。

ボタンの挨拶

図 1.Android アプリのボタンのあいさつ。

git でリポジトリのクローンを作成します(または ZIP ファイルを 直接ダウンロードします)。

git clone https://github.com/bazelbuild/examples

このチュートリアルのサンプル プロジェクトは examples/android/tutorial にあります。チュートリアルの残りの部分では、このディレクトリでコマンドを実行します。

ソースファイルを確認する

アプリのソースファイルを確認します。

.
├── README.md
└── src
    └── main
        ├── AndroidManifest.xml
        └── java
            └── com
                └── example
                    └── bazel
                        ├── AndroidManifest.xml
                        ├── Greeter.java
                        ├── MainActivity.java
                        └── res
                            ├── layout
                            │   └── activity_main.xml
                            └── values
                                ├── colors.xml
                                └── strings.xml

主なファイルとディレクトリは次のとおりです。

名前 場所
Android マニフェスト ファイル src/main/AndroidManifest.xmlsrc/main/java/com/example/bazel/AndroidManifest.xml
Android ソースファイル src/main/java/com/example/bazel/MainActivity.javaGreeter.java
リソース ファイル ディレクトリ src/main/java/com/example/bazel/res/

Bazel を使用したビルド

ワークスペースを設定する

ワークスペースは、1 つ以上のソフトウェア プロジェクトの ソースファイルを含むディレクトリで、ルートに MODULE.bazel ファイルがあります。

MODULE.bazel ファイルは空の場合もあれば、プロジェクトのビルドに必要な 外部 依存関係 への参照が含まれている場合もあります。

まず、次のコマンドを実行して空の MODULE.bazel ファイルを作成します。

OS コマンド
Linux、macOS touch MODULE.bazel
Windows(コマンド プロンプト) type nul > MODULE.bazel
Windows(PowerShell) New-Item MODULE.bazel -ItemType file

Bazel を実行する

次のコマンドで、Bazel が正しく実行されているかどうかを確認できます。

bazel info workspace

Bazel が現在のディレクトリのパスを出力したら、準備完了です。 MODULE.bazel ファイルが存在しない場合は、次のようなエラー メッセージが表示されることがあります。

ERROR: The 'info' command is only supported from within a workspace.

Android SDK と統合する

Bazel でアプリをビルドするには、Android SDK ビルドツール を実行する必要があります。つまり、Bazel がビルドツールを見つけられるように、 MODULE.bazel ファイルに情報を追加する必要があります。

MODULE.bazel ファイルに次の行を追加します。

bazel_dep(name = "rules_android", version = "0.5.1")

これにより、ANDROID_HOME 環境変数で参照されるパスにある Android SDK が使用され、その場所にインストールされているビルドツールの最新バージョンと最も高い API レベルが自動的に検出されます。

ANDROID_HOME 変数を Android SDK の場所に設定できます。インストールされている SDK のパスは、Android Studio の SDK Manager で確認できます。SDK がデフォルトの場所にインストールされている場合は、次の コマンドを使用して ANDROID_HOME 変数を設定できます。

OS コマンド
Linux export ANDROID_HOME=$HOME/Android/Sdk/
macOS export ANDROID_HOME=$HOME/Library/Android/sdk
Windows(コマンド プロンプト) set ANDROID_HOME=%LOCALAPPDATA%\Android\Sdk
Windows(PowerShell) $env:ANDROID_HOME="$env:LOCALAPPDATA\Android\Sdk"

上記のコマンドでは、現在のシェル セッションでのみ変数が設定されます。永続的に設定するには、次のコマンドを実行します。

OS コマンド
Linux echo "export ANDROID_HOME=$HOME/Android/Sdk/" >> ~/.bashrc
macOS echo "export ANDROID_HOME=$HOME/Library/Android/Sdk/" >> ~/.bashrc
Windows(コマンド プロンプト) setx ANDROID_HOME "%LOCALAPPDATA%\Android\Sdk"
Windows(PowerShell) [System.Environment]::SetEnvironmentVariable('ANDROID_HOME', "$env:LOCALAPPDATA\Android\Sdk", [System.EnvironmentVariableTarget]::User)

省略可: ネイティブ コードを Android アプリにコンパイルする場合は、 Android NDK をダウンロードし、rules_android_ndk を使用するには、MODULE.bazel ファイルに次の行を追加する必要があります。

bazel_dep(name = "rules_android_ndk", version = "0.1.2")

詳細については、Bazel で Android Native Development Kit を使用する をご覧ください

SDK と NDK の API レベルを同じ値に設定する必要はありません。 このページ には、Android リリースから NDK でサポートされている API レベルへのマッピングが記載されています。

BUILD ファイルを作成する

A BUILD ファイルには、一連のビルド出力とその依存関係の関係が記述されています。たとえば、aapt からコンパイルされた Android リソースや javac からのクラスファイルなどです。これらの依存関係は、 ワークスペース内のソースファイル(Java、C++)または他のビルド出力である可能性があります。BUILD ファイル は、Starlark という言語で記述されます。

BUILD ファイルは、Bazel の パッケージ階層という概念の一部です。 パッケージ階層は、ワークスペースのディレクトリ 構造に重ね合わされた論理構造です。各パッケージは、関連する一連のソースファイル と BUILD ファイルを含む ディレクトリ(とそのサブディレクトリ)です。パッケージには、独自の BUILD ファイルを含むサブディレクトリを除く 、すべてのサブディレクトリが含まれます。パッケージ名は、 BUILD ファイルに対する MODULE.bazel ファイルのパスです。

Bazel のパッケージ階層は、`BUILD` ファイルが配置されている Android アプリ ディレクトリの Java パッケージ階層とは概念的に異なりますが、ディレクトリは同じように整理できます。BUILD

このチュートリアルの簡単な Android アプリの場合、ソースファイルは src/main/ 1 つの Bazel パッケージで構成されています。より複雑なプロジェクトでは、多くのネストされた パッケージが存在する可能性があります。

android_library ルールを追加する

BUILD ファイルには、Bazel のさまざまな種類の宣言が含まれています。最も重要なタイプは ビルドルールです。これは、一連のソース ファイルまたはその他の依存関係から中間または最終的なソフトウェア出力をビルドする方法を Bazel に指示します。Bazel には、Android アプリの ビルドに使用できる android_libraryandroid_binary の 2 つのビルドルールが用意されています。

このチュートリアルでは、まず android_library ルールを使用して、アプリのソースコードとリソース ファイルから Android ライブラリ モジュール をビルドするように Bazel に指示します。次に、 android_binary ルールを使用して、Android アプリ パッケージをビルドする方法を Bazel に指示します。

新しい BUILD ファイルを src/main/java/com/example/bazel ディレクトリに作成し、 新しい android_library ターゲットを宣言します。

src/main/java/com/example/bazel/BUILD:

package(
    default_visibility = ["//src:__subpackages__"],
)

android_library(
    name = "greeter_activity",
    srcs = [
        "Greeter.java",
        "MainActivity.java",
    ],
    manifest = "AndroidManifest.xml",
    resource_files = glob(["res/**"]),
)

android_library ビルドルールには、ソースファイルからライブラリ モジュールをビルドするために Bazel が必要とする 情報を指定する一連の属性が含まれています。 ルールの名前は greeter_activity です。この名前を使用して、android_binary ルールの依存関係として ルールを参照します。

android_binary ルールを追加する

android_binary ルールは、アプリの Android アプリ パッケージ(.apk ファイル)をビルドします。

src/main/ ディレクトリに新しい BUILD ファイルを作成し、 新しい android_binary ターゲットを宣言します。

src/main/BUILD:

android_binary(
    name = "app",
    manifest = "AndroidManifest.xml",
    deps = ["//src/main/java/com/example/bazel:greeter_activity"],
)

ここで、deps 属性は、上記の BUILD ファイルに追加した greeter_activity ルール の出力を参照します。つまり、Bazel はこのルールの 出力をビルドするときに、まず greeter_activity ライブラリ ルールの出力がビルド済みで最新の状態であるかどうかを確認します。そうでない場合、Bazel はそれをビルドし、その出力を使用してアプリ パッケージ ファイルをビルドします。

これで、ファイルを保存して閉じます。

アプリをビルドする

アプリをビルドしてみましょう。次のコマンドを実行して android_binary ターゲットをビルドします。

bazel build //src/main:app

build サブコマンドは、Bazel に続く ターゲットをビルドするように指示します。ターゲットは、 a BUILD ファイル内のビルドルールの名前として指定します。ワークスペース ディレクトリからの相対パッケージ パスを指定します。この例では、ターゲットは app で、パッケージ パスは //src/main/ です。

コマンドラインの現在の作業ディレクトリとターゲットの名前によっては、パッケージ パスまたはターゲット名を省略できる場合があります。 ターゲット ラベルとパスの詳細については、ラベルをご覧ください。

Bazel はサンプルアプリのビルドを開始します。ビルド プロセス中、出力 は次のようになります。

INFO: Analysed target //src/main:app (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //src/main:app up-to-date:
  bazel-bin/src/main/app_deploy.jar
  bazel-bin/src/main/app_unsigned.apk
  bazel-bin/src/main/app.apk

ビルド出力を特定する

Bazel は、中間ビルド オペレーションと最終ビルド オペレーションの両方の出力を、 ユーザーごと、ワークスペースごとの出力ディレクトリに配置します。これらのディレクトリは、プロジェクト ディレクトリの最上位にある次の場所からシンボリック リンクされています。ここで、MODULE.bazel ファイルは次の場所にあります。

  • bazel-bin には、バイナリ実行可能ファイルとその他の実行可能なビルド出力が保存されます。
  • bazel-genfiles には、 Bazel ルールによって生成された中間ソースファイルが保存されます。
  • bazel-out には、他の種類のビルド出力が保存されます。

Bazel は、Android .apk ファイルを android_binary ルール を使用して生成し、bazel-bin/src/main ディレクトリに保存します。サブディレクトリ名 src/main は、Bazel パッケージの名前から 派生しています。

コマンド プロンプトで、このディレクトリの内容を一覧表示し、app.apk ファイルを見つけます。

OS コマンド
Linux、macOS ls bazel-bin/src/main
Windows(コマンド プロンプト) dir bazel-bin\src\main
Windows(PowerShell) ls bazel-bin\src\main

アプリを実行する

`bazel mobile-install` コマンドを使用すると、 コマンドラインから接続された Android デバイスまたはエミュレータにアプリをデプロイできます。このコマンドは Android Debug Bridge(adb)を使用してデバイスと通信します。デプロイする前に、Android Debug Bridge の手順に沿って adb を使用するように デバイスを設定する必要があります。Android Studio に含まれている Android エミュレータにアプリをインストールすることもできます。次のコマンドを実行する前に、エミュレータが実行されていることを確認してください。

次の情報を入力します。

bazel mobile-install //src/main:app

次に、「Bazel Tutorial App」を見つけて起動します。

Bazel チュートリアル アプリ

図 2.Bazel チュートリアル アプリ。

おめでとうございます。これで、Bazel でビルドされた最初の Android アプリがインストールされました。

mobile-install サブコマンドは、 --incremental フラグもサポートしています。このフラグを使用すると、 前回のデプロイ以降に変更されたアプリの部分のみをデプロイできます。

また、--start_app フラグもサポートしています。このフラグを使用すると、アプリをインストールするとすぐに 起動できます。

関連情報

詳細については、次のページをご覧ください。

ビルドをお楽しみください。