1. 程式人生 > >Gnu make學習筆記

Gnu make學習筆記

目標 efi 通配符 mon 其中 推導 完整 讓其 car


# 單行註釋
# 多行註釋:腳本語言大多是行註釋;若想多行註釋,建議每行首用#號。可替代方法是行尾續行符,但這樣不太好

# Makefile規則結構
# target:[prerequisites]
#  command
# 或者
# target:[prerequisites]; command
# 其中每條command需要以Tab開始,遵從shell語法。如果用“;”隔開的話,就不用Tab了
# 註意不要輕易以Tab開頭,以Tab開頭的命令都被交給系統shell去接手了
# make後執行的默認是第一條規則,即第一個target
# 路徑上所依賴的target則是采用深度優先的遞歸策略逐個生成
# 不被默認target依賴的target將不會被執行,除非顯式調用,比如make clean

#例子1: 最簡單的Makefile
hello: main.o utils.o
  cc -o hello main.o utils.o

main.o: main.c common.h
  cc -c main.c

utils.o: utils.c common.h
  cc -c utils.c

clean:
  rm -rf hello main.o utils.o

#例子2: 用變量簡化,加自動推導,Makefile默認支持cc -c main.c -o main.o自動推導出main.o,因此可省略
objects = main.o utils.o
hello: $(objects)
  cc -o hello $(objects)
clean:
  rm -rf hello $(objects)

# 默認Makefile:執行make時,依次找makefile -> Makefile,如果找不到就Stop;也可以利用自動推導,make xxx.o來編譯單個文件

# 引用其他文件:其中“-”表示忽略錯誤
-include xxx/Makefile *.mk

# 變量定義:區別?
varA = xxx
VarB := xxx

# 變量定義中的通配符不會被通配處理,因此直接寫*.o會被當做字符串,必須用wildcard函數
objects = *.o
objects = $(wildcard *.o)


# 多行變量的定義:define與endef之間包起來,會像宏一樣完整展開到使用該多行變量的地方

# 條件分支:ifdef/ifndef/ifeq/ifneq

#P33

# 文件搜索路徑:大型工程*.c和*.o不在同一目錄時使用。如下第一種是固定寫法,第二種是分類型通配,最後單個vpath是清除搜索路徑
VPATH = src:inc:../headers
vpath %.c src
vpath %.h inc:../headers
vpath

# 自動化變量:
# “$^”代表所有通過目錄搜索得到的依賴文件的完整路徑名(目錄 + 一般文件名)列表。
# “[email protected]”代表規則的目標
# “$<”代表規則中通過目錄搜索得到的依賴文件列表的第一個依賴文件。

# 偽目標:避免當前目錄下正好存在clean目標時出現困惑,另一個原因是考慮編譯效率讓其不生成依賴關系。方法是將其聲明為.PHONY的依賴項
# 若不聲明為偽目標,執行make clean時會先查找clean這個目標及其依賴關系,導致效率下降;聲明為偽目標就是明確告訴它沒有這個實體
# .PHONY聲明後面的所有目標都是偽目標
.PHONY: clean

# 並發執行的依賴順序,如下沒有規則的target,只是指定依賴順序,即dirA目錄需要等待dirB目錄先執行完make動作
dirA: dirB

#例子3: 全部通配的Makefile。此處使用了“:=”,原因?
objects := $(patsubst %.c,%.o, $(wildcard *.c))
hello: $(objects)
  cc -o [email protected] $^
.PHONY: clean
clean:
  rm -rf hello $(objects)

#P63

---- 《GNUMake.pdf》

Gnu make學習筆記