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

makefile中的多个冒号和等号(需要解释),makefile,Makefile,这只是生成文件的一部分。我不太明白发生了什么事 OBJS = $(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o) $(OBJS):$(OBJ)/%.o: $(SRC)/%.cpp | print-opts $(cc-command) 我所理解的是,这些行使用“cc命令”将.cpp文件编译成.o,在“print opts”之后。但我不懂它的语义 如果我展开“OBJS”的宏,这一行应该是: $(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o) : $(OBJ)/%.o

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

OBJS = $(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o)
$(OBJS):$(OBJ)/%.o: $(SRC)/%.cpp | print-opts
    $(cc-command)
我所理解的是,这些行使用“cc命令”将.cpp文件编译成.o,在“print opts”之后。但我不懂它的语义

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

$(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o) : $(OBJ)/%.o: $(SRC)/%.cpp | print-opts
    $(cc-command)
对我来说,它看起来像是在“$(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o”中,它声称$(SRC)中的所有.cpp都将在$(OBJ)中变成.o,但这将取决于$(OBJ)/%.o,后者取决于$(SRC)/%.cpp。这没有道理


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

假设您已经定义了这三个变量(如果没有定义,则该规则将无法正常工作):

现在考虑任务

OBJS = $(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o)
这是一个,;它表示“对于
$(SRC)
中格式为
$(SRC)/%.cpp
的任何内容,请将其更改为
$(OBJ)/%.o
”。因此,
OBJS
将计算为
object\u dir/foo.o object\u dir/bar.o

现在规则是:

$(OBJS):$(OBJ)/%.o: $(SRC)/%.cpp | print-opts
    $(cc-command)
Thuis是一个。它指定目标列表(
$(OBJS)
)、目标模式(
$(OBJ)/%.o
)和先决条件模式(
$(SRC)/%.cpp
)。Make将目标与目标模式匹配,并使用该匹配来构造必备名称。因此,如果Make使用此规则构建
object\u dir/foo.o
,则stem将是
foo
,前提条件是
source\u dir/foo.cpp


(你没有问关于
|打印选项的问题,所以我想这已经很清楚了。)

非常感谢。对gnu“make”手册的参考也非常有用。(我以前看过那本手册,但我找不到我需要的信息)有点被替换参考弄糊涂了。因此,如果我有
main.c
,它会将其粘贴到objectfiles目录中,并将文件扩展名更改为
.o
。这将保留文件的内容,并仅更改扩展名。这将为我们最终使用的所有对象文件设置名称。然后,我们使用名称列表作为目标并编译为对象文件,然后用我们刚刚编译的新对象文件覆盖这些文件。正确吗?@Ungeheuer:不,替换引用对文件没有任何作用,它只是转换变量。它将“source_dir/main.cpp”转换为“object_dir/main.o”;这些是文件名,不是文件名。一旦我们有了字符串“object\u dir/main.o”,我们就可以将它传递给模式规则,它知道如何构造该名称的文件。好的,
OBJS
是单个目标吗(当我们用
$(OBJS)
替换它时)当需要将C文件编译成目标文件时,它将循环使用文件名列表?@Ungeheuer:No,
OBJS
是文件名列表,它是模式规则的目标。如果要生成所有这些文件,必须为每个文件调用该规则(例如,使用其先决条件中包含
$(OBJS)
)的规则)。我认为在尝试类似的操作之前,应该先使用一些简单的makefile。
$(OBJS):$(OBJ)/%.o: $(SRC)/%.cpp | print-opts
    $(cc-command)