makefile中的多个冒号和等号(需要解释)

Posted

技术标签:

【中文标题】makefile中的多个冒号和等号(需要解释)【英文标题】:Multiple colons and equal sign in makefile (need explanation) 【发布时间】:2012-07-11 05:19:28 【问题描述】:

这只是生成文件的一部分。我不太明白发生了什么。

OBJS = $(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o)
$(OBJS):$(OBJ)/%.o: $(SRC)/%.cpp | print-opts
    $(cc-command)

我所理解的是,这些行将 .cpp 文件编译为 .o,在“print-opts”之后,使用“cc-command”。但我不明白语义。

如果我展开'OBJS'的宏,这一行应该是:

$(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o) : $(OBJ)/%.o: $(SRC)/%.cpp | print-opts
    $(cc-command)

对我来说,它看起来像在 '$(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o)' 中,它声称 $(SRC) 中的所有 .cpp 都会变成 .o在 $(OBJ) 中,但这将取决于 $(OBJ)/%.o,这取决于 $(SRC)/%.cpp。这没有意义……

我不明白这里的等号是什么意思,多个冒号是什么意思。

【问题讨论】:

【参考方案1】:

假设你已经定义了这三个变量(如果你没有,规则就不会很好地工作):

SRC = source_dir
OBJ = object_dir
SRCS = source_dir/foo.cpp source_dir/bar.cpp

现在考虑分配

OBJS = $(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o)

这是substitution reference;它说“对于$(SRCS) 中具有$(SRC)/%.cpp 形式的任何内容,将其更改为$(OBJ)/%.o”。所以OBJS 将评估为object_dir/foo.o object_dir/bar.o

现在规则:

$(OBJS):$(OBJ)/%.o: $(SRC)/%.cpp | print-opts
    $(cc-command)

Thuis 是static pattern rule。它指定了一个目标列表 ($(OBJS))、一个目标模式 ($(OBJ)/%.o) 和一个先决条件模式 ($(SRC)/%.cpp)。 Make 将目标与目标模式匹配,并使用它来构造先决条件名称。因此,如果 Make 使用此规则构建 object_dir/foo.o,则主干为 foo,前提条件为 source_dir/foo.cpp

(你没有问过| print-opts,所以我认为它已经很清楚了。)

【讨论】:

非常感谢。对 gnu 'make' 手册的引用也非常有帮助。 (我以前看过那本手册,但找不到我需要的信息) 有点被替换引用弄糊涂了。所以如果我有main.c,它将把它粘贴到目标文件目录中,只需将文件扩展名更改为.o。这保留了文件的内容,只是更改了扩展名。这将为我们最终得到的所有目标文件设置名称。然后我们使用名称列表作为目标并编译为目标文件,并用我们刚刚编译的新目标文件覆盖这些文件。对吗? @Ungeheuer:不,替换引用对文件没有任何作用,它只是转换变量。它将“source_dir/main.cpp”变成“object_dir/main.o”;这些是文件名,而不是文件。一旦我们有了字符串“object_dir/main.o”,我们就可以将它传递给模式规则,它知道如何构造一个具有该名称的文件。 好的,那么OBJS 是一个单一目标(当我们用$(OBJS) 替换它时),它会在将C 文件编译为对象时循环遍历它的文件名列表文件? @Ungeheuer:不,OBJS 是文件名列表,它是模式规则的目标。如果要构建所有这些文件,则必须为每个文件调用该规则(例如,使用在其先决条件中包含 $(OBJS) 的规则)。我认为在尝试这样的事情之前你应该先玩一些简单的 makefile。

以上是关于makefile中的多个冒号和等号(需要解释)的主要内容,如果未能解决你的问题,请参考以下文章

makefile

初识makefile

IntelliJ IDEA 代码对齐,等号和冒号的对齐风格

makefile

pycharm 冒号和等号的颜色在哪里设置

MVC的前台界面中冒号与等号的区别