Makefile 可以處理 Task 之間的 Dependency,讓編譯過程自動化
重要觀念: make
預設會把所有 target 都當成檔案,新增/刪除檔案會造成 目錄 的修改時間被更新
RULE1 = gcc RULE2 = value1 value2 value3 target: dependency >---command1 >---command2 && command3 >---command4 ;\ >--->---command5
- 這裡
>---
表示一個tab
字元,不能使用空格 - 在指令前加上
@
可以避免 make 把指令也輸出到畫面上 command4
和command5
透過\
連接在一起,會被解讀成連續的一行
make target
前會自動把所有 dependency 都 make
完成
[GNU make only] target: dependency | order-only-dependency
可以加上目錄 dependency
Assign
=
- 把舊的值直接覆蓋
A += B
- 把
B
接在A
上
- 把
A ?= B
- 若
A
未曾定義過,給予B
做為變數值,否則不動作
- 若
A != B
- 把
B
做為指令執行,stdout
做為A
的值 - [GNU make only] GNU make 沒有這個 operator,改用
$(shell B)
- 把
變數使用
${variable}
或$(variable)
存取- 若用在 target,則
$(variable)
中的每個值 (以空白分隔) 都被視為 target - Dependency 亦同
- 若用在 target,則
$@
代表目前的 target$<
代表第一個 dependency[GNU make only]
%
為通用字元,類似 shell 的*
用
$*
存取 match 的部份範例
.--------------------. | %: | | >---gcc -o $* $*.c | '--------------------' $ make test gcc -o test test.c
[2015/06/11] 如果 target 是
main.out
,dependency 最好是main.o
而不要是main.cpp
今日遭遇:
target=main $(target).out: $(target).cpp msgpack.hpp >---clang++36 -std=c++14 -Wall -Wextra -pedantic -O2 $(target).cpp -○$(target).out
Makefile
裡面寫的明明是clang++36
,下了make
指令後卻執行了c++ -O2 -pipe -c main.cpp
,-std=c++14
flag 消失了- 推測是 FreeBSD
make
自動去尋找系統內的c++
compiler 去編譯main.cpp
c++
和clang++
是 link,但我需要的是/usr/local/bin/clang++36
而不是/usr/bin/clang++