概要
Makefileでout-of-sourceしてるプロジェクトがあったので、cmakeに以降したらどれだけ楽になるのか試してみました。
CMakeの出力先の指定がまだわかってないので、わかり次第修正します。
Github : maruwo/make
構成
- wsl ubuntu 4.4.0-17134-Microsoft
- cmake version 3.10.2
- GNU Make 4.1
- gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
各ディレクトリの概要
-
lib
- 独自ライブラリ
-
app1
- ソースファイルを指定してのビルドする
- 独自ライブラリを使用する
-
app2
- ディレクトリ配下すべてをビルドする
- 独自ライブラリを使用する
Makefile
-
出力ディレクトリ
- dir/build
-
コマンド実行ディレクトリ
- dir/
実行手順
make
ツリー
dir
├ Makefile
├ common.mk
│
├ app1
│ ├ Makefile
│ └ app1.c
│
├ app2
│ ├ Makefile
│ └ app2.c
│
└ lib
├ Makefile
├ mylib.c
└ mylib.h
呼び出し順
- dir/Makefile
- dir/lib/Makefile
- dir/common.mk
- dir/app1/Makefile
- dir/common.mk
- dir/app2/Makefile
- dir/common.mk
dir/Makefile
では各ディレクトリを指定しています。
指定されたディレクトリ配下のMakefileでビルドを行うよう、-Cオプションディレクトリを指定してmakeします。
次に、各ディレクトリに入り、その中のMakefileが実行されます。
各ディレクトリのMakefileは基本的な部分に関しては同じものとなっていますが、フラグ関連を独立して持てるように分けています。
各ディレクトリのMakefileでは./common.mk
をincludeして実行します。
./common.mk
は実際のビルド処理を記載してあります。
out-of-sourceのやり方
./common.mk
に記載されてあるビルド手順で、ファイル名だけではなく、ディレクトリ名も含めてビルドしています。
OBJS := $(SRCS:%.c=$(OBJDIR)/%.o)
DEPS := $(OBJS:%.o=$(OBJDIR)/%.d)
TARGET := $(TAGDIR)/$(TAGNAME)
$(OBJDIR)/%.o: %.c
@mkdir -p $(dir $@)
@$(CC) $(CFLAGS) -c $< -o $@
$(TARGET): $(OBJS)
@mkdir -p $(dir $@)
@$(CC) $(OBJS) -o $@ $(LDFLAGS)
CMake
-
出力ディレクトリ
- dir/build
-
コマンド実行ディレクトリ
- dir/
- dir/build
実行手順
mkdir build
cd build
cmake ..
make
ツリー
dir
├ CMakeLists.txt
│
├ app1
│ ├ CMakeLists.txt
│ └ app1.c
│
├ app2
│ ├ CMakeLists.txt
│ └ app2.c
│
└ lib
├ CMakeLists.txt
├ mylib.c
└ mylib.h
out-of-sourceのやり方
参考
CMake : out-of-sourceビルドで幸せになる
cmakeを実行するディレクトリをトップから移動することで対応している。
まとめ
Makefileは記述が難しいが、トップディレクトリでmake一発でビルドできるので、運用が始まればあまり問題でもない?
小規模プロジェクトを短期間でやるにはMakefile作るのがめんどそう。
Makefile独自の変数($@など)が分かりづらい。
CMakeではトップディレクトリから1段下でmakeを実行するため、やる人によっては煩わしい?
(その辺はCIやらスクリプトで対応可能なのでなんとも言えないが。)
ビルドの進捗なども%表示され、出力もカラーとなるので、結果が見やすい。
個人的にはカラー表示や記述のしやすさでcmakeの方が良かった。
課題
- CMakeの出力がMakefileと同じにならない。
- 最終出力のバイナリがbuildの各ディレクトリの配下にできてしまう。
- autotoolsとの比較