这个Makefile构建了三个程序。它们遵循相同的模式,但在运行时会生成不同的构建命令。具体来说,我需要使用c++11
进行编译,但只能在其中一个构建命令上实现。这是为什么?
生成文件:
CXX=g++
RM=rm -f
CFLAGS=-std=c++11 -g -Wall $(shell root-config --cflags)
LDFLAGS=-g $(shell root-config --ldflags)
LDLIBS=$(shell root-config --libs)
SOURCES=generic_queue.cpp map_compare.cpp vector_search.cpp
OBJS=$(SOURCES:.cpp=.o)
all: $(SOURCES) generic_queue_test list_of_lists map_compare_test vector_search_test
# Note that $(CFLAGS) is used in the $(CXX) ... command
# each time that a .o file is built.
vector_search_test: $(OBJS) vector_search_test.o
$(CXX) $(LDFLAGS) -o vector_search_test vector_search_test.o $(LDLIBS)
vector_search_test.o: vector_search.cpp vector_search.h
$(CXX) $(CFLAGS) -c vector_search.cpp -o vector_search_test.o
generic_queue_test: $(OBJS) generic_queue_test.o
$(CXX) $(LDFLAGS) -o generic_queue_test generic_queue_test.o $(LDLIBS)
generic_queue_test.o: generic_queue.cpp generic_queue.h fixed_priority_queue.h
$(CXX) $(CFLAGS) -c generic_queue.cpp -o generic_queue_test.o
list_of_lists: $(OBJS) list_of_lists.o
$(CXX) $(LDFLAGS) -o list_of_lists list_of_lists.o $(LDLIBS)
list_of_lists.o: list_of_lists.cpp list_of_lists.h
$(CXX) $(CFLAGS) -c list_of_lists.cpp -o list_of_lists.o
map_compare_test: $(OBJS) map_compare.o
$(CXX) $(LDFLAGS) -o map_compare map_compare.o $(LDLIBS)
map_compare.o: map_compare.cpp map_compare.h
$(CXX) $(CFLAGS) -c map_compare.cpp -o map_compare.o
clean:
$(RM) $(OBJS) generic_queue_test.o list_of_lists.o map_compare.o
dist-clean: clean
$(RM) generic_queue_test list_of_lists map_compare
输出:
g++ -c -o generic_queue.o generic_queue.cpp
g++ -std=c++11 -g -Wall -pthread -m64 -I/usr/include/root -c map_compare.cpp -o map_compare.o
g++ -c -o vector_search.o vector_search.cpp
我们看到只有第二个g++
命令完全使用CFLAGS
变量。为什么?是否与$(shell ...)
变量的CFLAGS
部分有关?
编辑:
能够通过将目标文件vector_search_test.o
的名称更改为vector_search.o
来解决我的问题,为什么会这样做?
答案 0 :(得分:2)
你的makefile中有几个bug,加起来就是这种行为。
首先考虑OBJS
,其中包含
generic_queue.o map_compare.o vector_search.o
这些文件是其他目标的先决条件,但您实际上从未使用generic_queue.o
或vector_search.o
。 错误#1:您错误地有额外的先决条件。
这些文件是其他目标的先决条件,因此Make必须构建它们。但是怎么样?您已为三个目标文件提供了规则:
vector_search_test.o: vector_search.cpp vector_search.h
...
generic_queue_test.o: generic_queue.cpp generic_queue.h fixed_priority_queue.h
...
list_of_lists.o: list_of_lists.cpp list_of_lists.h
...
map_compare.o: map_compare.cpp map_compare.h
...
最后一个会对map_compare.o
有效,但是你没有给出generic_queue.o
或vector_search.o
的规则(而且你真的没有理由,因为你永远不会使用它们)。但是Make知道如何执行某些标准构建,例如foo.cpp => foo.o
。如果您不提供规则,Make将使用其隐式规则,其规则如下:
generic_queue.o: generic_queue.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c generic_queue.cpp -o generic_queue.o
这与您编写的规则非常相似。事实上,你可能不会注意到差异 - 你可能已经省略了你的规则并让Make依赖于这个,但是 Bug#2,你将你的旗帜-std=c++11 -g -Wall whatever
添加到了错误的变量使用CXXFLAGS
来保存C ++编译器的标志;你添加了CFLAGS
,这是为C编译器。
(我已经遗漏了pattern rules和automatic variables,因为你似乎并不了解它们 - 我敦促你们学习它们,它们非常有用,但那是另一天。)