百分比與星號(星號)makefile 先決條件有何不同

百分比與星號(星號)makefile 先決條件有何不同

我試圖理解為什麼有些 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 手冊中。

相關內容