在处理C ++项目时,我注意到我正在对我的主代码中链接的一个头文件进行更改,但make实用程序没有注册它。我不得不强迫它使用" make-B"进行不同的编译。
我想知道为什么会这样;是因为我的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进行了更改,这是我主文件中的#included。
为什么不注意它应该再次编译?因为我觉得这是一个概念上的误解,我觉得没有必要包括我做的改变或输出差异,当我做" make - B"。他们是简单的事情,比如新的pairing_heap.h中包含的cout和cerr,直到被强制才被提取。
如果我需要提供更多信息,请与我们联系。
谢谢。
答案 0 :(得分:1)
您在pairing_heap.h
的配方中列出main
,这不会使它成为main
的依赖项(此外,您不应该像这样将标题传递给编译器),因为您需要按如下方式编写规则:
main: main.cpp pairing_heap.h
g++ $(FLAGS) -c main.cpp $(CXXFLAGS)
您的文件中还有许多其他不正确的内容,例如您的目标不是实际文件(main:
应该是main.o:
等),而且您不是&#39 ; t使用自动变量或模式规则,但用以下内容替换所有内容可能更容易
CPPFLAGS := -MMD -MP
CXXFLAGS := -Wall -Werror -std=c++11 -pedantic -Wvla -g
SOURCES := $(wildcard *.cpp)
main: $(SOURCES:.cpp=.o)
-include $(SOURCES:.cpp=.d)
利用make implicit rules和gcc' s / clang的自动依赖关系生成来生成名为main
的可执行文件。
答案 1 :(得分:0)
让我们对任何特定的编程语言或工具都一无所知,因此它并不了解C / C ++文件依赖于头文件和源文件。它只有形式的规则
target: dependencies
actions
所有它都知道文件target
取决于dependencies
中列出的文件,如果这些文件中的任何一个更新,actions
中的命令应该运行到更新target
。真的是这样 - 所做的一切都来自于目标文件,依赖关系和操作这个简单的想法。
现在 更多 - 对于您经常要做的常见事情,make有一堆内置规则,以及指定'模式' rules - 目标包含通配符的规则,因此可用于依赖于具有相关名称的其他文件的许多不同目标。
现在,在您的情况下,您有以下规则:
all: main.o game.o zombie.o
g++ $(FLAGS) game.o main.o zombie.o -o main $(CXXFLAGS)
表示重新生成文件all
,如果文件main.o
,game.o
或zombie.o
早于文件运行命令。这是该文件中的第一条规则,因此当您键入make
时,默认情况下会生成该规则。
现在,您可能没有名为all
的文件(如果您make
可能无法做任何事情),但这通常很好,因为如果它不存在,它显然不是最新的,所以命令需要运行。
当命令需要运行时,它还会检查任何依赖项,以查看它们是否具有较旧的依赖项(因此需要重建)。由于这些文件都以.o
结尾,因此它们匹配一个内置规则,该规则知道如何从具有相同名称的文件构建它们,除了以.cpp
结尾,因此它会运行这些操作(如果)仅当.cpp
文件较新时才会使用。
现在,你说,"我的其他规则是什么 - 他们做了什么?"事实证明他们什么也做不了。它们是构建名为game
,zombie
和main
的文件的规则,因为您永远不会要求构建这些文件而其他任何文件都不依赖于它们,所以它们什么都不做。你也可以删除它们。
您还要问"如果头文件发生变化,如何重建?"好吧,如果你添加一个没有动作的规则(只是目标和依赖),它只会将这些依赖项添加到另一个规则(在这种情况下是内置的) 有一个动作。因此,如果您添加如下行:
main.o: pairing_heap.h
(没有操作),make
会将此依赖项添加到内置规则中,该规则知道如何从main.o
构建main.cpp
并运行该规则(重新编译{{1} }})如果 main.cpp
或main.cpp
比pairing_hep.h
更新 - 这正是您想要的。