Help us understand the problem. What is going on with this article?

MakefileとCMakeでout-of-sourceをしてみる。

More than 1 year has passed since last update.

概要

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

呼び出し順

  1. dir/Makefile
  2. dir/lib/Makefile
  3. dir/common.mk
  4. dir/app1/Makefile
  5. dir/common.mk
  6. dir/app2/Makefile
  7. dir/common.mk

dir/Makefileでは各ディレクトリを指定しています。
指定されたディレクトリ配下のMakefileでビルドを行うよう、-Cオプションディレクトリを指定してmakeします。

次に、各ディレクトリに入り、その中のMakefileが実行されます。
各ディレクトリのMakefileは基本的な部分に関しては同じものとなっていますが、フラグ関連を独立して持てるように分けています。

各ディレクトリのMakefileでは./common.mkをincludeして実行します。
./common.mkは実際のビルド処理を記載してあります。

out-of-sourceのやり方

./common.mkに記載されてあるビルド手順で、ファイル名だけではなく、ディレクトリ名も含めてビルドしています。

Makefile.一部抜粋
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との比較
maruwo
組み込みソフト開発してます。 RTOSとかOSなしが主。たまに組み込みLinux使います。 Cがほとんど。趣味レベルでC#のWindowsデスクトップアプリ。 最近はGOを学習中。 Jenkinsやらvagrantやらdockerやらで楽に開発できないか検討中。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away