BazelでC++ビルドするときの一般的な使用例

2020/03/07

BAZEL C/C++ Googleサービス Linux RandomGrid Ubuntu 技術

t f B! P L
さてさて、今日もお仕事です。

私が業務内容として、サーバ管理と開発と開発環境管理を並行してやっているので、他のメンバーが出勤しない土曜日を出勤、月曜を休みって感じで勤務スケジュールを設定しています。

決して会社がブラックなわけじゃないよ?

ところで、纏めていて思ったのですが、Bazel のドキュメントはとても実際的で的を絞った内容に纏められていて、非常に優れています。

その最たるものが本日また解説していく Common C++ Build Use Cases です。

 職業柄日常的に色々な技術マニュアルを読むのですが、IT系の技術マニュアルは、出来ることの羅列でどう使うかという部分が薄いものがほとんどです。

そういう中でBazelはどう使うか、という部分がしっかりと書かれており、ドキュメントの読み始めから実際に現場で使えるようになるまでが早いのです。

さて、そんなわけで今日も、Da★Boの独断と偏見と愛と誠と罪と罰のドキュメント翻訳書いていきますよ。

ご利用は計画的に

 C++ ビルドの一般的な使用例

複数のファイルを使用してターゲットをビルドする

 glob を使えうことで、単一のターゲットに複数のファイルを挿入することが出来ます。
cc_library(
    name = "build-all-the-files",
    srcs = glob(["*.cc"]),
    hdrs = glob(["*.h"]),
)
このターゲットは、同じディレクトリ内にある拡張子が .cc と .h のファイルを見つけ、ビルドの対象とします。
ただしサブディレクトリは検索しません。

 実際のところ実務で使う上ではこの使い方が一番多いかもしれない。
ビルド環境の構築に汎用性を持たせるため、とか Bazel に馴染みのない開発者に BUILD ファイルを触らせず、C++のコーディングに集中させるため、とか 理由(その大半が消極的な理由)は色々ありますが………

本来であれば対象のソース構成は十分に設計されているべきではあるんですけどね。 

推移的なインクルード 

ファイルがヘッダを使用している場合、ファイルのルールはそのライブラリのルールに依存します。
この依存関係が連鎖してしまう場合がありますが、この場合は直接的な依存関係だけを指定してやります。
例えば、 sandwich.h が bread.h をインクルードしていて、
bread.h は flour.h をインクルードしています。
しかし sandwich.h に flour.h は必要ありません。
(サンドイッチにパンは必要でも小麦粉は必要ないですよね) この例えいんのか?
cc_library(
    name = "sandwich",
    srcs = ["sandwich.cc"],
    hdrs = ["sandwich.h"],
    deps = [":bread"],
)

cc_library(
    name = "bread",
    srcs = ["bread.cc"],
    hdrs = ["bread.h"],
    deps = [":flour"],
)

cc_library(
    name = "flour",
    srcs = ["flour.cc"],
    hdrs = ["flour.h"],
)
Da★Boの場合は、自社標準の型定義とかしたライブラリをいろんなライブラリで使用するときに使っています。

インクルードパスを追加する

プロジェクトのルートディレクトリに、インクルードするファイルを置けなかったり置きたくなかったりすることはよくあることです。

 既にあるライブラリを使用する場合なども、ソースに書かれたインクルードディレクトリが既に存在していて、 それが自分のプロジェクトのワークスペースとディレクトリ構成と合わないこともあります。
例として以下のようなディレクトリ構成を扱わないといけない場合
└── my-project
    ├── legacy
    │   └── some_lib
    │       ├── BUILD
    │       ├── include
    │       │   └── some_lib.h
    │       └── some_lib.cc
    └── WORKSPACE
Bazel は some_lib.h を
#include "legacy/some_lib/include/some_lib.h"
と書かれているものとして探しますが、 実際にソースコードに書かれている構文は、
#include "some_lib.h"
このようになっています。
この場合、BUILDファイルにsome_lib/include をインクルードディレクトリとして指定してやる必要があります。
cc_library(
    name = "some_lib",
    srcs = ["some_lib.cc"],
    hdrs = ["include/some_lib.h"],
    copts = ["-Ilegacy/some_lib/include"],
)
これは特に便利な依存関係の定義です。
ヘッダにディレクトリ構成含んだincludeを書かなくてすみますから。

実際俺も既存のプロジェクトをBazelに置き換えてるので、これよく使う…… 

さて、元のドキュメントでは次に
Including external libraries
Writing and running C++ tests
という項目が来ますが、GoogleTestの使用方法と合わせて書かれていて今後色々な記事から参照したいので、 ここは別のページに分けます。

動的リンクライブラリを使用する

ソースを所持していない動的リンクライブラリを使用しなければならない場合(実際こういう事例よくあるんだよなぁ……)、 cc_library ルールで包んで記載することで、他のBUILDルールがdeps属性を使用して参照することが可能になります。
cc_library(
    name = "mylib",
    srcs = ["mylib.so"],
    hdrs = ["mylib.h"],
)

Translate

ページビューの合計

注意書き

基本的にごった煮ブログですので、カテゴリから記事を参照していただけると読みやすいかと存じます。

ADBlocker等を使用していると、Twitterやアクセスカウンタが表示されません。

記事を読むには差し支えませんが、情報を参照したい場合には一時例外にしていただけると全てご参照いただけます。

Featured Post

ボイドラDICEの攻略法

QooQ