在操作UNIX系統時,常常會用到make指令來自動build服務,make會去執行該目錄裡的Makefile,按照裡面的設定完成許多事情

例如FreeBSD利用port-tree安裝軟體時就是用make

不過Linux和FreeBSD的Makefile又有些不同

FreeBSD的make版本是Berkeley make

Linux則是GNU make

所以在寫Makefile時需要注意一下OS

FreeBSD版本Makefile
1.Makefile Layout
在command line中,輸入make指令預設是執行該目錄的Makefile,但也可以透過 -f 參數指向其他檔案

make -f <Other_Makefile>

2.Target 語法
在使用make時,通常都會加上例如install、config、clean等的target語法

all:
    @echo 123;
deploy:
    @echo 456;
help: all

當直接下make時,會執行all以下的語法,輸出123
若是make deploy則會輸出456
因為echo那段是Shell語法,如果要把那段語法當成Shell執行,都需要在前面加上Tab縮排,不然會錯誤
另外輸入make help時,會執行all區塊的語法

3.特別字元
@:不要顯示執行的指令。
-:表示即使該行指令出錯,也不會中斷執行。

all:
    -rm test;echo 123;

4.變數
在慣例上,Makefile內部使用的變數名稱使用小寫;而使用者從命令列自行指定數值的變數,則是使用大寫
在Makefile中,可利用 $(name) 或 ${name} 來存取已定義的變數

#command Line:make KERNEL=FreeBSD
kernel = Linux
all:
    @echo ${KERNEL}
    @echo ${kernel}

5.=語法
?=:若變數未定義,則替它指定新的值。否則,採用原有的值

x = 123
x ?= foo
all:
    @echo $(x)
#輸出 123

+=:字串串接(會自動以空白隔開)

!=:將shell語法結果傳回變數裡

#顯示OS資訊
x != uname -a;
all:
    @echo $(x)

6.條件判斷式(.if,.elif,.else)及相關函式

x = 123
all:
.if $(x) > 123
    echo "big"
.elif $(x) == 123
    echo "equal"
.else
    echo "small"
.endif

注意:條件判斷式為Makefile裡的語法,並不是shell語法,所以不需要用Tab鍵縮排

empty:判斷Makefile變數是否為空值

#empty裡面傳入變數名稱VAR而不是$(VAR)
all:
.if empty(x)
    echo "yes"
.endif

defined:判斷Makefile變數是否被定義

#defined裡面傳入變數名稱VAR而不是$(VAR)
all:
.if defined(x)
    echo "yes"
.endif

也可以寫成

#.ifdef 等同 .if defined()
#.ifndef 等同 .if !defined()
#.elifdef 等同 .elif defined()
#.elifndef 等同 .elif !defined()
all:
.ifdef x
    echo "yes"
.else
    echo "no"
.endif

exists:判斷是否有該檔案或目錄

path = /home/johnson4932/code/test
all:
.if exists($(path))
    echo "yes"
.else
    echo "no"
.endif

7.include
Otherfile:

all:
    @echo 123;

Makefile

.include "Otherfile"
Categories: FreeBSDUnix