前回にBazelの勉強をちょっとだけして、そういえば中途半端に終わらせてしまっていた。
前回のBazel初期評価では、比較的小さめのプロジェクトではビルド開始に必要な時間が長くなってしまうこと、高速ビルドの利点を生かせないことが分かった。 また、Rubyに対応していないことや、そもそもBazelの文法がやや複雑で理解に時間がかかってしまうこともあった。
では、腰を据えてBazelの文法をしっかりと勉強してみると、これらの問題は改善されるのだろうか。とりあえず、まずはBazelの最も基本的なドキュメントを眺めながら、Bazelの考え方について勉強していく。
ちなみに、上記の文章の一部翻訳を以下に作った。ただしBazelを今後しっかり勉強するかどうかに依存するので、更新するかどうかは未確定。
Bazelの構文について
Bazelで最初に悩むのは、ラベルの記法だった。これなに?
//my/app/main:app_binary
これはラベルの中に、パッケージと、ターゲットの両方が記載されているパターンだ。Bazelの例では、例えば以下のようなファイル群があったときに、
src/my/app/BUILD src/my/app/app.cc src/my/app/data/input.txt src/my/app/tests/BUILD src/my/app/tests/test.cc
- BUILDファイルのあるディレクトリまでがパッケージだと考える。ここでは
src/my/app
とsrc/my/app/tests
の2つのパッケージが存在する。 - パッケージの後に付属するのがターゲットとなる。ターゲットはファイル名自身の事もあるし、そうでない抽象的な名前がつくこともある。
また、ラベルにおいてターゲットが省略された場合は、パッケージの最後尾の名前がターゲットと同じであると見なされる。つまり、下記は一緒の意味。
//my/app //my/app:app
ここで注意しなければならないのは、ターゲットには上位のディレクトリを参照するための識別子../
、./
などを含むことが許されない。例外として.
だけはオッケーのようだ。
これはいまいち理由がよくわからないのだが、たぶん上位のディレクトリを参照できてしまうとビルドの構造がバラバラになってしまうため、自分のディレクトリとそれ以下の階層しか参照できないようにしているのではないだろうか。
そもそもパッケージは何故存在するのか
パッケージは、ビルドにおける関連するファイルの一群をまとめたもの。CMakeなどであれば、それが一つのルールになり、パッケージの単位でライブラリを作成したりするものだと思う。
基本的にパッケージ内では、上記に示したように他のパッケージを直接参照することはできない。すなわち、ディレクトリをまたいで別のファイルにアクセスするというのは結構難しいわけだ。
これは予想だがこのようにディレクトリ階層でパッケージを区切ることにより、厳密性を上げてプロジェクトディレクトリがカオスになるのを防いでいるのではないか?ただし制御するのはかなり難しいけれども。