0

这个 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.ovector_search.o为什么可以解决我的问题?

4

1 回答 1

2

您的 makefile 中有几个错误,这些错误加起来就是这种行为。

首先考虑OBJS,其中包含

generic_queue.o map_compare.o vector_search.o

这些文件是其他目标的先决条件,但您从不实际使用generic_queue.oor 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
    ...

最后一个可以 for map_compare.o,但是您没有为or给出任何规则generic_queue.ovector_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 依赖这个规则,但是错误 #2,您将标志添加-std=c++11 -g -Wall whatever到了错误的变量中。Make 用于CXXFLAGS保存 C++ 编译器的标志;您将您的添加到CFLAGS,这是用于 C 编译器的。

(我省略了模式规则自动变量,因为您似乎不了解它们——我敦促您学习它们,它们非常有用,但那是另一天的事了。)

于 2017-05-12T01:11:16.577 回答