2015-02-10 57 views
1

在處理C++項目時,我注意到我正在修改主代碼中鏈接的頭文件之一,但make實用程序沒有註冊它。如果使用「make-B」進行更改,我必須強制它進行不同的編譯。瞭解Makefile的相關性(C++)

我想知道爲什麼會這樣;是因爲我的makefile是如何寫入的,我的文件如何依賴於彼此,兩者還是兩者都不相同?

這裏是我的makefile:

CXXFLAGS = -Wall -Werror -std=c++11 -pedantic -Wvla -g 
//CXXFLAGS = -std=c++11 

all: main.o game.o zombie.o 
     g++ $(FLAGS) game.o main.o zombie.o -o main $(CXXFLAGS) 

game: game.cpp 
     g++ $(FLAGS) -c game.cpp $(CXXFLAGS) 

zombie: zombie.cpp 
     g++ $(FLAGS) -c zombie.cpp $(CXXFLAGS) 

main: main.cpp 
     g++ $(FLAGS) -c main.cpp pairing_heap.h $(CXXFLAGS) 

我做了更改pairing_heap.h
這是在我的主文件包含(#include)。

爲什麼沒有注意到它應該再次編譯?因爲我覺得這是一個概念誤解,所以我覺得沒有必要包括我做的改變或者當我做「make-B」時的輸出差異。他們是簡單的東西,如新的pairing_heap.h中包含的cout和cerr,直到被強制時纔會被拾取。

讓我知道是否需要提供更多信息。

謝謝。

回答

0

Make並沒有真正瞭解任何特定的編程語言或工具,所以它不理解C/C++文件依賴於頭文件和源文件。它只是形式的規則

target: dependencies 
     actions 

所有從這個知道的是,該文件target取決於dependencies列出的文件,而如果這些文件是新的,在actions命令應運行更新target。這就是它 - 所做的一切都來自這個簡單的目標文件,依賴關係和操作的想法。

現在更多的是 - 對於你經常想要做的事情以及指定「模式」規則的方法,make有一堆內置的規則 - 目標包含一個規則通配符,因此可用於許多不同的目標,這些目標依賴於具有相關名稱的其他文件。

現在你的情況,你有規則:

all: main.o game.o zombie.o 
     g++ $(FLAGS) game.o main.o zombie.o -o main $(CXXFLAGS) 

它說重拍文件all,如果不是文件main.ogame.ozombie.o它應該運行的命令舊。這是該文件中的第一條規則,因此當您鍵入make時,默認情況下會生成該規則。現在

,你可能不會有一個名爲all(如果你沒有make可能不會做任何事情)的文件,但是這通常很好,就好像它不存在,它顯然不是最新的,所以該命令需要運行。 當命令需要運行時,它還會檢查任何依賴關係,以查看它們是否具有較舊的依賴關係(因此需要重建)。由於這些文件都以.o結尾,因此它們匹配內置規則,該規則知道如何從具有相同名稱的文件構建它們,除非以.cpp結尾,所以如果(且僅當).cpp文件更新時才運行這些操作。

現在,你說,「我的其他規則怎麼樣 - 他們做什麼?「事實證明他們什麼都不做,他們是建立文件game,zombiemain的規則,因爲你從不要求建立這些文件,而且沒有別的東西依賴於它們,它們什麼都不做。刪除它們

你還會問:「如果頭文件改變,我該如何重建它?」如果你添加一個沒有動作的規則(只是目標和依賴),它只會將這些依賴添加到另一個規則內置在這種情況下),其確實有一個動作所以,如果你喜歡添加一行:

main.o: pairing_heap.h 

(無動作),make將增加這種依賴於知道如何從main.cpp建立main.o,並且將運行該規則(重新編譯main.cpp)如果要麼main.cpppairing_hep.h較新,main.o內置的規則 - 這正是你想要的。

+0

感謝您解釋大圖,然後深入細節。很教學;我可以挖掘它。我預見到我和makefile之間的關係會更好。 – 2015-02-10 20:17:34

1

您在配方main,這並不能使它的main依賴上市pairing_heap.h(此外,你永遠不應該通過標題來編譯這樣),對於你需要編寫規則如下:

main: main.cpp pairing_heap.h 
     g++ $(FLAGS) -c main.cpp $(CXXFLAGS) 

還有一些其他的事情,在你的文件不正確,如事實,你的目標是不實際的文件(main:應該main.o:等),和你沒有利用自動變量或圖案規則,但可能更容易以下列方式替換所有內容:

CPPFLAGS := -MMD -MP 
CXXFLAGS := -Wall -Werror -std=c++11 -pedantic -Wvla -g 
SOURCES := $(wildcard *.cpp) 

main: $(SOURCES:.cpp=.o) 

-include $(SOURCES:.cpp=.d) 

它利用化妝的implicit rules和gcc的/鐺汽車依存產生,使一個可執行稱爲main