Diverse Advent Calendar 2020、6日目の記事になります。
先月、Android Open Source Project(AOSP)がBazelに置き換わったニュースが発表されました。
Welcome Android Open Source Project (AOSP) to the Bazel ecosystem
すごいですね!
このニュースを受け、Bazelって何? 何ができるの? この先どうなるの? って期待と不安を交えてザワザワしてしまった方もいらっしゃるのではないでしょうか?
そこで本記事では、Bazelと仲良くなるための第一歩として、Bazelのチュートリアルを触れてみました!
Bazelとは
Bazel は、Googleが社内開発に使用していた独自のビルドツールをオープンソース化したプロダクトです。
特徴として以下のとおりです。
・高度なローカルおよび分散キャッシング、最適化された依存関係分析、および並列実行により、高速でインクリメンタルなビルドが可能
・多くのプログラミング言語に対応
・複数のリポジトリまたは巨大なサイズのコードにも対応できるスケーラビリティ
・対応言語やプラットフォームを簡単に追加できる拡張性
環境
・macOS 10.15.7
・Xcode 12.2
・Java 10.0.1
・Python 2.7.17
・Homebrew 2.6.0
・(Bazel 3.7.1-homebrew)
・Tulsi 0.20200930.88
インストール
macなので Homebrewでさくっといれれます。
$ brew install bazel
$ bazel --version # bazel 3.7.1-homebrew
公式ドキュメントは、こちら です。
以下、チュートリアルのリポジトリ内の README に沿って進めます。
公式ドキュメントにもチュートリアルの記載がありますが、リポジトリの内容と大きく内容が異なるのため注意です。
ビルド
1. ソースもってくる
$ git clone git@github.com:bazelbuild/examples.git
$ cd example/tutorial
チュートリアルには、Android/iOSアプリが含まれており、さらにAndroidアプリの機能でローカルサーバとやりとりする用のサーバ側のコードが含まれています。1
サーバ側のコードはビルドしなくてもアプリ自体は起動することができます。
2. ローカルサーバを起動させる
$ bazel build //backend
$ bazel-bin/backend/backend
以下のエラーが出る場合があります。
java.lang.IllegalArgumentException: the Java7 runtime is not supported anymore.
at com.google.appengine.tools.development.SharedMain.configureRuntime(SharedMain.java:258)
at com.google.appengine.tools.development.DevAppServerMain$StartAction.apply(DevAppServerMain.java:374)
at com.google.appengine.tools.util.Parser$ParseResult.applyArgs(Parser.java:45)
at com.google.appengine.tools.development.DevAppServerMain.run(DevAppServerMain.java:257)
at com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:248)
Google App Engineを使用してビルドする際に、デフォルトのJava 7(古い!)でビルドしようとして起こってるもので、以下のように修正します。
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>some-app</application>
<version>1</version>
<threadsafe>true</threadsafe>
<runtime>java10</runtime><!-- 追加 -->
</appengine-web-app>
Javaのバージョンに関しては7以上であれば問題ないので、使用してるversionに合わせてください。
3-1. Androidのビルド
$ bazel build //android
上記コマンドが成功すると、以下の場所にapkファイルが生成されます。
bazel-bin/android/android_unsigned.apk
bazel-bin/android/android.apk
さらに、Androidはコマンドが充実していて、以下のコマンドで、ビルド + 端末にインストール + アプリ起動してくれます。
$ bazel mobile-install //android --start_app
ビルドの際に、以下のエラーが出る場合があります。
ERROR: /path/to/examples/tutorial/android/BUILD:8:15: Installing //android:android failed (Exit 1): incremental_install failed: error executing command bazel-out/darwin-py2-opt-exec-2B5CBBC6/bin/external/bazel_tools/tools/android/incremental_install --output_marker bazel-out/darwin-fastbuild/bin/android/android_files/full_deploy_marker --dexmanifest ... (remaining 11 argument(s) skipped)
Traceback (most recent call last):
File "/private/var/tmp/_bazel_hoge/774bebc909ac897800e5e234203df705/execroot/__main__/bazel-out/darwin-py2-opt-exec-2B5CBBC6/bin/external/bazel_tools/tools/android/incremental_install.runfiles/bazel_tools/tools/android/incremental_install.py", line 25, in <module>
from concurrent import futures
ImportError: No module named concurrent
Target //android:android failed to build
Use --verbose_failures to see the command lines of failed build steps.
生成されるPython スクリプト内で concurrent.futures
モジュールが使われているようで、このモジュールはPython3.2から搭載されてますが、それ以前のversionを使っている場合は手動でいれる必要があります。
$ pip install futures
Androidスクリーンショット
起動後 | OptionMenu押下後 |
---|---|
アプリの実装がIP固定でローカルホストにリクエストするようになっていて、エミュレータ上での起動かつ 2 でローカルサーバを起動させていると、右側のようにリクエストした際のパスが表示されるようになります。2
3-2. iOSのビルド
$ bazel build //ios-app
上記コマンドが成功すると、以下の場所にipaファイルが生成されます。
bazel-out/applebin_ios-ios_x86_64-fastbuild-ST-c4cf2ec641b4/bin/ios-app/ios-app.ipa
ipaファイルができるものの、動かしての確認することができません。
さらに、 README に書かれている、
Bazel will generate some output files, most notably bazel-bin/ios-app/ios-app.xcodeproj
この ios-app.xcodeproj
も生成されませんでした
そこで、 Tulsi というツールをつかってxcodeprojファイルを生成し、Xcodeを起動させてSimuratorで実行します。3
iOSスクリーンショット
起動後 | ボタン押下後 |
---|---|
iOS側のサンプルはAndroidのサンプルとは異なり、TextFieldに自由入力してサーバのレスポンスを表示させるようになってます。
2 でローカルサーバを起動させている場合、 127.0.0.1
でアクセスすると、右側のように表示されます。
最後に
いかがでしたでしょうか。
プラットフォームごとに用意されてるものを使うことが多いと思いますが、いかなるソフトウェアもBazelで安全にかつ高速でビルドできるようになったらすごいですね!
さて明日は、 @mu-suke08 のお話です!