在makefile中,`OBJECTS = $(SOURCES:.cpp=.o)`是什么意思?

6

我正在学习这个教程,其中有类似于这样的内容

# File names
EXEC = run
SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES:.cpp=.o)    

.....
%.o: $(SRCPATH)/%.cpp $(INC)
    $(CC) $(CXXFLAGS) $(INCLUDES) -c $< -o $@

我不确定是否理解该文件,希望有人能解释最后两个语句。以下是我关于Makefile的三个问题:

问题1:

什么是

 SOURCES = $(wildcard *.cpp)

并且

 SOURCES = $(*.cpp)

它说第二种情况只有当存在.cpp文件时才起作用,因为它们不存在,所以它不起作用。我的问题是为什么第一种方法有效?
问题2: 通配符*表示什么? 最后一个语句OBJECTS = $(SOURCES:.cpp=.o)表示什么?
问题3: 在作为目标时,%.o表示什么?* .o,%.o和通配符* .cpp之间有什么区别?

那个页面的意思是 *.cpp 而不是 $(*.cpp)$(*.cpp) 是错误的。此外,该页面关于 *.cpp 的说法也是不正确的。 - Etan Reisner
2个回答

9
SOURCES = $(*.cpp)
SOURCES = *.cpp
SOURCES = $(wildcard *.cpp)

第一个错误,第二个太晚扩展(不在定义时),第三个搜索源目录中所有后缀为.cpp的文件。
内置函数wildcard用于在自然未发生通配符展开的情况下强制进行通配符展开。
OBJECTS = $(SOURCES:.cpp=.o)

这意味着在每个项目的末尾用.o替换每个.cpp后,OBJECTS将被分配为SOURCES的值。

%.o作为目标意味着你正在定义一个从其他东西创建.o的规则。

参考:GNU make手册

这里有一个很好的基本makefile:https://stackoverflow.com/a/26579143


目标文件%.o是否适用于找到的所有.o文件?我的意思是,如果有6个.o文件,这将被调用6次吗? - MistyD
适用于所有.o文件,make需要制作(不是找到)。无论如何,这个规则过于复杂了。 - Deduplicator

2
你可以通过阅读GNU Make手册来获得所有答案。
值得一读的是GNU Make手册中关于通配符的部分,这与该页面作者试图解释不使用*.cpp有关,因为它可能无法达到你想要的效果。(然而,作者关于裸通配符忽略修改时间的观点是完全错误的。)
该部分继续介绍了wildcard函数的部分。这只是一个make扩展的globbing函数,用于控制扩展时间(变量定义时间而不是变量使用时间)。 $(SOURCES:.cpp=.o)是一个替换引用
作为目标的%.o是一个模式规则*.o是一个glob。 $(wildcard *.cpp)(而不是wildcard *.cpp)已经在早些时候介绍过了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接