Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GNU Makeの使い方 / How to use GNU Make

GNU Makeの使い方 / How to use GNU Make

研究室ハンズオン資料

kaityo256

May 09, 2024
Tweet

More Decks by kaityo256

Other Decks in Programming

Transcript

  1. 10 37 C++の分割コンパイル 以下の3つのファイルを考える #include "param.hpp" #include <cstdio> void show(void);

    int main(void) { printf("main: N is %d¥n", N); show(); } const int N = 10; #include "param.hpp" #include <cstdio> void show(void){ printf("sub: N is %d¥n",N); } param.hpp main.cpp sub.cpp
  2. 11 37 C++の分割コンパイル ビルド方法 g++ -c main.cpp g++ -c sub.cpp

    g++ main.o sub.o 依存関係 param.hpp main.cpp sub.cpp main.o sub.o a.out インクルード コンパイル コンパイル リンク
  3. 12 37 C++の分割コンパイル まずは手順をそのままMakefileに書く all: a.out a.out: main.o sub.o g++

    main.o sub.o main.o: main.cpp g++ -c main.cpp sub.o: sub.cpp g++ -c sub.cpp Makefile
  4. 13 37 C++の分割コンパイル カレントディレクトリにMakefile/makefileがある状態で makeを実行 $ make g++ -c main.cpp

    g++ -c sub.cpp g++ main.o sub.o ビルドが実行される makeは、ファイルを指定しないと Makefileもしくはmakefileを探しに行く
  5. 15 37 C++の分割コンパイル a.out: main.o sub.o g++ main.o sub.o ターゲット

    前提条件 コマンド a.outを作りたい そのためには main.oとsub.oが要る main.oとsub.oが用意できたら リンクしてa.outを作る
  6. 16 37 C++の分割コンパイル main.o: main.cpp g++ -c main.cpp ターゲット 前提条件

    コマンド main.oを作りたい main.oが無いか、main.cppより 古ければ作り直す main.cppからmain.oを作る方法
  7. 17 37 C++の分割コンパイル ビルドをきれいにするルール「クリーン」を作る clean: rm -f a.out *.o ターゲット

    ビルドをきれいにしたい(clean) コマンド 中間ファイルや最終ターゲットを削除 前提条件 なし make clean make これでクリーンビルドできる
  8. 18 37 C++の分割コンパイル all: a.out a.out: main.o sub.o g++ main.o

    sub.o main.o: main.cpp g++ -c main.cpp sub.o: sub.cpp g++ -c sub.cpp clean: rm -f a.out *.o cleanも追加したMakefile 似たような記述が繰り返されている
  9. 20 37 パターンルール all: a.out a.out: main.o sub.o g++ main.o

    sub.o main.o: main.cpp g++ -c main.cpp sub.o: sub.cpp g++ -c sub.cpp clean: rm -f a.out *.o all: a.out a.out: main.o sub.o g++ main.o sub.o %.o: %.cpp g++ -c $< clean: rm -f a.out *.o まとめる
  10. 22 37 自動変数(マクロ) main.o: main.cpp g++ -c $< 依存関係の一番左に展開される main.cpp

    他には・・・ $@ ターゲット名に展開 (main.o) $* パターンがマッチした部分 (main) 等多数 ※ 気になったら「make 自動変数」で検索してください
  11. 25 37 変数 CXX=g++ all: a.out a.out: main.o sub.o $(CXX)

    main.o sub.o %.o: %.cpp $(CXX) -c $< clean: rm -f a.out *.o all: a.out a.out: main.o sub.o g++ main.o sub.o %.o: %.cpp g++ -c $< clean: rm -f a.out *.o CXXという変数を定義し、g++という値を代入 コンパイラを変更する場合は、一か所だけ修正すればよくなった 使う時は$(変数名)とする
  12. 26 37 依存関係 all: a.out CXX=g++ a.out: main.o sub.o $(CXX)

    main.o sub.o %.o: %.cpp $(CXX) -c $< clean: rm -f a.out *.o このMakefileには、param.hppの依存関係が正しく入っていない 依存関係をmakeにどうやって教えるか?
  13. 28 37 依存関係 g++はMake用の依存関係を出力できる $ g++ -MM *.cpp main.o: main.cpp

    param.hpp sub.o: sub.cpp param.hpp $ g++ -MM *.cpp > makefile.dep ファイルにリダイレクトして Makefileにインクルードする -include makefile.dep
  14. 29 37 完成 all: a.out CXX=g++ a.out: main.o sub.o $(CXX)

    main.o sub.o %.o: %.cpp $(CXX) -c $< clean: rm -f a.out *.o -include makefile.dep ※ 依存関係を自動で作ったり、ソースファイルを自動で取得したり、 まだ自動化できる部分はいろいろある
  15. 30 37 makeの応用例:データ処理 大量のデータをスクリプトで変換したい input0.dat input1.dat input2.dat input3.dat … input9.dat

    output0.dat output1.dat output2.dat output3.dat … output9.dat convert.py python convert.py < input0.dat > output0.dat python convert.py < input1.dat > output1.dat python convert.py < input2.dat > output2.dat …
  16. 31 37 makeの応用例:データ処理 INPUTS=$(shell ls input*.dat) OUTPUTS=$(INPUTS:input%=output%) all: $(OUTPUTS) output%:

    input% python convert.py < $< > $@ clean: rm -f $(OUTPUTS) こんなMakefileを書けばmake一発で変換できる
  17. 34 37 パターンルール all: output0.dat output1.dat … output%: input% python

    convert.py < $< > $@ マッチ output0.dat: input0.dat python convert.py < $< > $@ % = 0.dat input0.dat output0.dat
  18. 36 37 Makeによる論文ビルド PDF TeX データファイル データファイル gnuplot python 画像ファイル

    画像ファイル コンパイル 最初に精度の低いデータで図を作っておいて、後から 本番の図に差し替える時等に便利 依存関係と処理をMakefileに記述しておけば、データの 更新から論文PDFまでmake一発で行く