![見出し画像](https://assets.st-note.com/production/uploads/images/15342755/rectangle_large_type_2_90fe394e61aea781249c10ad77fd56b3.png?width=1200)
Bazel 入門 (2) ターゲットとパッケージ
「Bazel」のターゲットとパッケージについてまとめました。
前回
「Bazel」は、小さなプロジェクトの場合は単一のターゲットで十分ですが、大きなプロジェクトの場合は複数の「ターゲット」と「パッケージ」に分割することで、高速インクリメンタルビルド(変更されたもののみをリビルド)を可能にし、ビルドを高速化することができます。
(情報源)
1. ターゲットとパッケージ
今回は、次の3つのサンプルを作成します。
(1)単一のパッケージの単一のターゲットをビルド
(2)プロジェクトを複数のターゲットに分割してビルド
(3)プロジェクトを複数のパッケージに分割してビルド
2. 単一のパッケージの単一のターゲットをビルド
(1)フォルダ構成
今回のプロジェクトは、以下のようなフォルダ構成になります。
└──stage1
├── main
│ ├── BUILD
│ └── helloworld.cpp
└── WORKSPACE
(2) WORKSPACEファイルを作成
「WORKSPACE」ファイルの中身は今回は必要ないので空とします。
(3)BUILDファイルを作成
単一のターゲットのビルド設定を行います。
【BUILD】
cc_binary(
name = "helloworld",
srcs = ["helloworld.cpp"],
)
(4)ソースコードの作成
ソースコードの中身は次のように記述します。
「Hello world」と「時間」を表示するコードになります。
【helloworld.cpp】
#include <ctime>
#include <string>
#include <iostream>
std::string get_greet(const std::string& who) {
return "Hello " + who;
}
void print_localtime() {
std::time_t result = std::time(nullptr);
std::cout << std::asctime(std::localtime(&result));
}
int main(int argc, char** argv) {
std::string who = "world";
if (argc > 1) {
who = argv[1];
}
std::cout << get_greet(who) << std::endl;
print_localtime();
return 0;
}
(5)ビルド
ビルドのコマンドは次の通りです。
「/.bazel-bin/main/」にビルド結果が出力されます。
$ bazel build //main:helloworld
(6)実行
以下のコマンドで実行できます。
$ bazel run //main:helloworld
Hello world
Tue Oct 22 08:33:19 2019
3. プロジェクトを複数のターゲットに分割してビルド
プロジェクトを2つの「ターゲット」に分割してビルドします。
(1)フォルダ構成
今回のプロジェクトは、以下のようなフォルダ構成になります。
└──stage2
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
└── WORKSPACE
(2) WORKSPACEファイルを作成
「WORKSPACE」ファイルの中身は今回は必要ないので空とします。
(3)BUILDファイルを作成
複数のターゲットのビルド設定を行います。属性「name」はターゲット名、「srcs」はソースコード、「hdrs」はヘッダファイル、「deps」は依存関係になります。「helloworld」ターゲットのビルドには「greet」ターゲットが必要なため、depsに[":greet"]を指定しています。ターゲットは「//<パッケージのパス>:<ターゲット名>」で指定しますが、同一パッケージのターゲットでは「//<パッケージのパス>」を省略できます。
【BUILD】
cc_library(
name = "greet",
srcs = ["greet.cpp"],
hdrs = ["greet.h"],
)
cc_binary(
name = "helloworld",
srcs = ["helloworld.cpp"],
deps = [
":greet",
],
)
(4)ソースコードの作成
ソースコードの中身は次のように記述します。
【greet.h】
#ifndef LIB_GREET_H_
#define LIB_GREET_H_
#include <string>
std::string get_greet(const std::string &thing);
#endif
【greet.cpp】
#include "greet.h"
#include <string>
std::string get_greet(const std::string& who) {
return "Hello " + who;
}
【helloworld.cpp】
#include "greet.h"
#include <ctime>
#include <iostream>
#include <string>
void print_localtime() {
std::time_t result = std::time(nullptr);
std::cout << std::asctime(std::localtime(&result));
}
int main(int argc, char** argv) {
std::string who = "world";
if (argc > 1) {
who = argv[1];
}
std::cout << get_greet(who) << std::endl;
print_localtime();
return 0;
}
(5)ビルド
ビルドのコマンドは次の通りです。「/.bazel-bin/main/」にビルド結果が出力されます。
$ bazel build //main:helloworld
(6)実行
以下のコマンドで実行できます。
$ bazel run //main:helloworld
Hello world
Tue Oct 22 08:33:19 2019
4. プロジェクトを複数のパッケージに分割してビルド
プロジェクトを複数のパッケージに分割してビルドします。
(1)フォルダ構成
今回のプロジェクトは、以下のようなフォルダ構成になります。
└──stage3
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
│ └── hello-time.h
└── WORKSPACE
(2) WORKSPACEファイルを作成
「WORKSPACE」ファイルの中身は今回は必要ないので空とします。
(3)BUILDファイルを作成
複数のパッケージのビルド設定を行います。属性「visibility」は可視化属性で、「main」ターゲットからアクセスできるようにしています。「helloworld」ターゲットのビルドには「greet」ターゲットと別パッケージの「time」ターゲットが必要なため、depsに[":greet", "//lib:time",]を指定しています。
【lib/BUILD】
cc_library(
name = "time",
srcs = ["time.cpp"],
hdrs = ["time.h"],
visibility = ["//main:__pkg__"],
)
【main/BUILD】
cc_library(
name = "greet",
srcs = ["greet.cpp"],
hdrs = ["greet.h"],
)
cc_binary(
name = "helloworld",
srcs = ["helloworld.cpp"],
deps = [
":greet",
"//lib:time",
],
)
(4)ソースコードの作成
ソースコードの中身は次のように記述します。「Hello world」と時間を表示するコードになります。
【lib/time.h】
#ifndef LIB_TIME_H_
#define LIB_TIME_H_
void print_localtime();
#endif
【lib/time.cpp】
#include "lib/time.h"
#include <ctime>
#include <iostream>
void print_localtime() {
std::time_t result = std::time(nullptr);
std::cout << std::asctime(std::localtime(&result));
}
【main/greet.h】
#ifndef MAIN_GREET_H_
#define MAIN_GREET_H_
#include <string>
std::string get_greet(const std::string &thing);
#endif
【main/greet.cpp】
#include "main/greet.h"
#include <string>
std::string get_greet(const std::string& who) {
return "Hello " + who;
}
【main/helloworld.cpp】
#include "lib/time.h"
#include "main/greet.h"
#include <iostream>
#include <string>
int main(int argc, char** argv) {
std::string who = "world";
if (argc > 1) {
who = argv[1];
}
std::cout << get_greet(who) << std::endl;
print_localtime();
return 0;
}
(5)ビルド
ビルドのコマンドは次の通りです。パッケージが2つなので、「/.bazel-bin/main/」と「/.bazel-bin/main/lib/」にビルド結果が出力されます。
$ bazel build //main:helloworld
(6)実行
以下のコマンドで実行できます。
$ bazel run //main:helloworld
Hello world
Tue Oct 22 08:33:19 2019