こんにちは、田渕です。
いつもは、技術は後追いスタンスなんですが(汗)、今回は少しでも新しい技術に触れてみようと思い、
Bazelを触ってみました。今回はBazelの入門編について紹介しようと思います。
今、私の周辺では何をするにもgradleが全盛です。やっとGradleになれてきたところです(笑)。
Bazelとは、Googleが社内で使用していたビルドツールで、オープンソースとして公開されています。
Bazelの発音ですが、FAQによると、「ベイゼル」が近いようです。
2016年3月現在は、β版での提供となっています。ロードマップがこちらに示されていますが、
安定版は、2016年12月リリースの予定です。安定版では、Windowsもサポートされるようです。
Bazelのドキュメントを見てみると、AndroidやiOSなどのルール(定義)がたくさんあります。
プラットフォーム単位での対応が柔軟に進んでいるようです。
この辺は、マルチプラットフォームを意識したビルドツールを目指しているような感じですね。
また、公式サイトの404ページ、ビルドエラー風メッセージでオシャレ!ですね。
環境の構築
まずは、環境の構築から。
OSのサポートは、今のところMac OS X とLinux(ubuntu)のみ。
ubuntu環境を持っていないので、AWS上にインスタンスを作成しました。
Bazelのインストールマニュアルに沿って、インストールを進めます。
java実行環境のインストール
Bazelは、javaの実行環境1.8以上(1.7はまだサポートされてますが、非推奨)が必要なので、javaをインストールします。
1 2 3 |
sudo add-apt-repository ppa:webupd8team/java sudo apt-get update sudo apt-get install oracle-java8-installer |
インストールに必要なコマンドのインストール
1 |
sudo apt-get install pkg-config zip g++ zlib1g-dev unzip |
Bazelモジュールをダウンロード
今回は、0.2.0を使用します。
1 |
wget https://github.com/bazelbuild/bazel/releases/download/0.2.0/bazel-0.2.0-installer-linux-x86_64.sh |
実行権限をつけます。
1 |
chmod +x bazel-0.2.0-installer-linux-x86_64.sh |
インストール
1 |
./bazel-version-installer-os.sh --user |
インストールが完了すると、このようなメッセージが表示されます。
1 2 3 4 5 6 7 |
Bazel is now installed! Make sure you have "/home/ubuntu/bin" in your path. You can also activate bash completion by adding the following line to your ~/.bashrc: source /home/ubuntu/.bazel/bin/bazel-complete.bash See http://bazel.io/docs/getting-started.html to start a new project! |
作業フォルダに、binフォルダが作成されます。中身はこのようになっています。
1 2 3 |
ls -l bin/ total 0 lrwxrwxrwx 1 ubuntu ubuntu 29 Mar 9 10:46 bazel -> /home/ubuntu/.bazel/bin/bazel |
パスに~/binを追加します。
1 2 3 |
export PATH="$PATH:$HOME/bin" echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/ubuntu/bin |
これで、環境構築は完了です。
動かしてみる
実際に動かしてみるために、簡単なプロジェクトを作成します。
Bazelの実行に必要なファイルは、以下の2ファイルです。
・BUILD
・WORKSPACE
BUILDには、コンパイルの詳細設定や、プロジェクト間の依存関係などを記載します。
WORKSPACEには、依存関係や外部ソースの参照などを記載します。
サンプルプロジェクトの構成です。
1 2 3 4 5 6 7 8 9 |
sample +---WORKSPACE +---BUILD +---src +---main +---java +---com +---example +---SampleRunner.java |
SampleRunner.java
1 2 3 4 5 6 7 |
package com.example; public class SampleRunner { public static void main(String args[]) { System.out.println("Hello!!"); } } |
BUILD
1 2 3 4 5 |
java_binary( name = "sample", srcs = glob(["**/*.java"]), main_class = "com.example.SampleRunner", ) |
javaビルドのルール定義を記述しています。
nameはプロジェクト名
srcsはターゲットのソースファイルです。glob関数を使って、ワイルドカードを使用できます。
main_classには、メインクラスを指定します。
ルール定義の詳細はこちら。
WORKSPACEは、今回は依存や外部ソースの参照が必要ないので、空ファイルで問題ありません。
ビルドするには、下記コマンドを実行します。
1 |
bazel build :sample |
実行すると、結果がこのように出力されます。
1 2 3 4 5 |
INFO: Found 1 target... Target //:sample up-to-date: bazel-bin/sample.jar bazel-bin/sample INFO: Elapsed time: 10.432s, Critical Path: 2.61s |
実行後のディレクトリ構成を見てみると、このようになっています。
1 2 3 4 5 6 7 8 9 10 11 12 |
ls -al total 40 drwxrwxr-x 3 ubuntu ubuntu 4096 Mar 16 03:46 . drwxr-xr-x 10 ubuntu ubuntu 4096 Mar 16 03:46 .. lrwxrwxrwx 1 ubuntu ubuntu 115 Mar 16 03:46 bazel-bin -> /home/ubuntu/.cache/bazel/_bazel_ubuntu/ff8c0dd6bc08ac0c46b3dad0afe9d998/sample/bazel-out/local_linux-fastbuild/bin lrwxrwxrwx 1 ubuntu ubuntu 120 Mar 16 03:46 bazel-genfiles -> /home/ubuntu/.cache/bazel/_bazel_ubuntu/ff8c0dd6bc08ac0c46b3dad0afe9d998/sample/bazel-out/local_linux-fastbuild/genfiles lrwxrwxrwx 1 ubuntu ubuntu 89 Mar 16 03:46 bazel-out -> /home/ubuntu/.cache/bazel/_bazel_ubuntu/ff8c0dd6bc08ac0c46b3dad0afe9d998/sample/bazel-out lrwxrwxrwx 1 ubuntu ubuntu 79 Mar 16 03:46 bazel-sample -> /home/ubuntu/.cache/bazel/_bazel_ubuntu/ff8c0dd6bc08ac0c46b3dad0afe9d998/sample lrwxrwxrwx 1 ubuntu ubuntu 120 Mar 16 03:46 bazel-testlogs -> /home/ubuntu/.cache/bazel/_bazel_ubuntu/ff8c0dd6bc08ac0c46b3dad0afe9d998/sample/bazel-out/local_linux-fastbuild/testlogs -rw-rw-r-- 1 ubuntu ubuntu 223 Mar 16 03:46 BUILD drwxrwxr-x 3 ubuntu ubuntu 4096 Mar 14 10:44 src -rw-rw-r-- 1 ubuntu ubuntu 84 Mar 14 12:56 WORKSPACE |
生成物を実行してみます。
1 2 |
bazel-bin/sample Hello!! |
生成物をクリアするには、cleanタスクを実行します。
1 |
bazel clean |
Mavenリポジトリの依存関係を追加してみる
次に、Mavenリポジトリのライブラリの依存関係を設定してみます。
SampleRunner.javaを以下のように修正します。
1 2 3 4 5 6 7 8 9 10 |
package com.example; import org.apache.commons.lang3.StringUtils; public class SampleRunner { public static void main(String args[]) { System.out.println("Hello!!"); System.out.println(StringUtils.upperCase("bazel")); } } |
commons-langのStringUtilsを使用して、bazelを大文字に変換する処理を追加します。
WORKSPACE
1 2 3 4 |
maven_jar( name = "commons_lang", artifact = "org.apache.commons:commons-lang3:3.4" ) |
nameには、Bazelの内部で使用する名称を指定します。
注意が必要なのは、ここではハイフンは使用できません。ライブラリ名と同じcommons-lang を指定するとこのようなエラーになります。
1 2 3 4 |
ERROR: /home/ubuntu/sample/WORKSPACE:1:1: maven_jar rule //external:commons-lang's name field must be a legal workspace name. ERROR: Error evaluating WORKSPACE file. ERROR: no such package 'external': Package 'external' contains errors. INFO: Elapsed time: 0.270s |
BUILD
1 2 3 4 5 6 7 8 9 10 11 12 13 |
java_binary( name = "sample", srcs = glob(["**/*.java"]), main_class = "com.example.SampleRunner", deps = ["commons_lang"], ) java_library( name="commons_lang", exports = [ "@commons_lang//jar", ], ) |
ここで、依存関係を追加します。
java_binaryルールで、depsにcommons_langを指定しています。
commons_langは、java_libraryルールで定義しています。
ここでは、ハイフンは使用できるようです。
ここまでできたら、ビルド、実行してみます。
1 2 3 |
bazel build :sample Hello!! BAZEL |
無事動作しました。
最後に
はじめて触ってみた感触ですが、30分もあれば簡単な確認はできると思います。
ただ、Bazelの特色である、高速・柔軟性などを体感するには至っていません。
次回は巨大なプロジェクトをビルドして、Gradleとの比較をしてみたいと思います。