2013-12-23 54 views
2

我是Makefiles的新手;因此,我遇到了一個問題,我無法想出一個好的谷歌搜索來幫助解答。默認的`make`行爲從哪裏來?

我正在運行一個虛擬操作系統,其中有一個由其他人設置的Fedora發行版。如果我在目錄中構建我自己的Makefile,我可以設置我的.c文件進行編譯,但我喜歡。然而,如果我只是運行make test,在我的目錄中存在test.c,我會得到以下內容:clang -ggdb3 -std=c99 -Wall -Werror test.c -lcs50 -lm -o test

下面這個觀察我的問題是,這種默認的,看似普遍,make行爲從哪裏來的?換句話說,如果這個Makefile在我的文件系統上,它在哪裏?

+2

如果我不是非常錯誤,它會被硬連線到'make'中。該實用程序有許多用於編譯各種源類型的默認規則,其中最受歡迎的規則是編譯C(以及最終的C++)程序。 – 2013-12-23 22:52:51

回答

4

makeseveral predefined implicit rules。其中兩個是:

編譯C程序 n.o自動地從與N.C的形式「$(CC)$(CPPFLAGS)$(CFLAGS)-c」的配方製備。

鏈接一個對象文件 n被自動從n.o通過運行經由C編譯器接頭(通常稱爲LD)製成。使用的精確配方是'$(CC)$(LDFLAGS)n.o $(LOADLIBES)$(LDLIBS)'。

注意,make是足夠聰明,有效地串聯上述兩成一個規則,當它是有道理的:

...可以通過使用「的.o」目標文件作爲中間體來完成,但它一步完成編譯和鏈接的速度更快,所以就是這樣做的。

您可以使用make -pn轉儲預定義的規則。例如:

 
$ make -pn -f /dev/null | grep -A3 '^%: %.c$' 
make: *** No targets. Stop. 
%: %.c 
# commands to execute (built-in): 
    $(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o [email protected] 

$ 
+0

感謝有用答案@DigitalTrauma和@nos。 「make -pn」命令對我來說非常有用,可以找出所有這些來自「默認」的地方。它向我展示了我所困惑的所有環境變化。 – ironicaldiction

2

這適用於GNU make,通常是在Linux上實現的默認make

包含默認規則的文件系統上沒有默認的Makefile。 然而,無論您是否提供makefile文件,make都會有一些隱含的規則,make在調用 時會記錄here

這些規則知道例如如何從.c源文件構建可執行文件。通過經C編譯器鏈接(通常稱爲 LD)

n爲不自動進行:你可以瞭解這些潛規則here

例如使建立一個可執行文件時有這個默認規則。所使用的精確配方是 '$(CC)$(LDFLAGS) 沒有$(LOADLIBES)$(LDLIBS)'

含義,如果你運行make test它會嘗試從文件test.o創建一個可執行test ,並且您可以設置相應的CC/LDFLAGS /等。鏈接時將使用的變量。

而作爲另一隱含規則就可以建立從.c文件.o文件,因此以上會尋找test.o,並試圖重建使用規則:

沒有從自動進行NC的形式爲'$(CC) $(CPPFLAGS)$(CFLAGS)-c'。

I.e.運行make test時的隱式規則將首先編譯test.c,然後使用您使用CC環境變量(或默認編譯器cc)指定的編譯器和各種編譯器/鏈接器標誌鏈接test.o,然後將其設置爲環境變量。