我試圖理解為什麼有些 Makefile 具有先決條件%.txt
,而其他 Makefile 則具有*.txt
.
我已經創建了這個資料夾佈局。
$ tree .
.
├── hi1.txt
├── hi2.txt
├── hi3.txt
└── Makefile
首先,我嘗試了這個。
foo.txt: *.txt
echo $^
它達到了我的預期。
$ make
echo hi1.txt hi2.txt hi3.txt
hi1.txt hi2.txt hi3.txt
但是,後來我看到一些 Makefile 用作%.txt
通配符。所以我接下來嘗試了。
foo.txt: %.txt
echo $^
但是,這會導致錯誤。
$ make
make: *** No rule to make target '%.txt', needed by 'foo.txt'. Stop.
有人可以解釋為什麼會發生這種情況嗎?
GNU Make 4.3
答案1
在 中make
,百分號用於模式匹配,它需要目標中的 1 以及(至少)先決條件中的 1:
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
透過這個 makefile,我們指定為了建立文件名稱以 結尾的文件.o
,您需要有一個具有相同前綴的文件,但以 結尾.c
而不是.o
為了能夠建立這些規則,您顯然需要能夠參考目標和先決條件;這就是$@
和$<
變數出現的$@
地方$<
。如果您需要建立一個使用的命令全部先決條件(例如,連結可執行檔),那麼您可以使用變數$^
:
%: %.o lib.o
$(CC) $(LDFLAGS) -o $@ $^
如果將上述兩個範例 makefile 片段合併到一個 makefile 中,並且有一個檔案“lib.c”,其中包含一些要在同一目錄中的多個 C 程式中使用的通用程式碼,那麼您可以新增任意隨機.c
文件,比如說foo.c
,並將其編譯成一個程序foo
,該程序也連結到 中的程式碼lib.c
,而不需要對 makefile 進行任何更改。
請注意,只要先決條件不同,也可以具有相同目標的模式;例如,以下內容將起作用:
%.o: %.c
$(CC).....
%.o: %.cpp
$(CXX).....
也就是說,只要此目錄中沒有任何與 C 原始檔同名(無副檔名)的 C++ 源文件,它就會按預期工作。如果確實是這種情況,C++ 版本將被忽略,而 C 原始碼將被編譯(因為 C 規則在 makefile 中首先列出)
欲了解更多信息,請參閱相關部分在 GNU make 手冊中。