Makefile目标:%。o和$(OBJ)之间的差异

时间:2014-04-29 10:10:45

标签: c++ linux makefile

这两个目标之间有什么区别:

%.o : %.cpp $(CXX) -c $(CXXFLAGS) $< -o $@

$(OBJ) : $(SRC) $(CXX) -c $(CXXFLAGS) $< -o $@

如果我们假设SRC包含目录中存在的所有.cpp文件并且OBJ = $(SRC:.cpp=.o)

2 个答案:

答案 0 :(得分:1)

第一个指定每个目标文件依赖于其对应的源文件,并定义一个合理合理的规则来从源文件($@创建目标文件($^,第一个目标),所有依赖项)。它应该使用$<,只是第一个依赖项,因为通常会有其他依赖项 - 源文件包含的标头。你通常可以完全放弃这条规则;有一个implicit rule用于编译单个C ++文件。

第二个指定所有目标文件都依赖于所有源文件,并定义了一个不能编译任何东西的功能失调的规则。例如,定义SRC = a.cpp b.cpp,这会扩展为

g++ -c  a.cpp b.cpp -o a.o

失败,因为-c仅编译单个源文件:

g++: fatal error: cannot specify -o with -c, -S or -E with multiple files

答案 1 :(得分:0)

$(SRC)未包含所有源文件!它包含一个规则,如何从目标文件名构建源文件名。

如果$(SRC)包含所有源文件,如a.c和b.c,而$(OBJ)包含a.o和b.o,则规则扩展为:

a.o b.o: a.c b.c

无效!

区别:

$(OBJ)通常包含所需对象的列表。因此规则知道必须构建哪些对象。 Make将为所有源文件调用编译器并构建对象。

第一条规则只是一条规则,在没有任何其他trigger的情况下实际上什么都不做。

如果您完成示例:

 %.o : %.cpp
    $(CXX) -c $(CXXFLAGS) $^ -o $@

do: x.o y.o
    $(CXX) -o do x.o y.o

make知道do需要x.o和y.o.所以他寻找一条规则来建立它们并抓住你的第一条规则。

但是你的第一条规则不能手动定义,它通常已经存在。对于所有隐式规则,请查看: https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html