Gcc 请解释这个makefile中变量的奇怪生存期

Gcc 请解释这个makefile中变量的奇怪生存期,gcc,makefile,Gcc,Makefile,我的all规则中的echo打印出正确的内容,但是当我将OBJS的定义移动到我注释的行时,makefile不起作用。按原样,makefile会运行,但当我移动OBJS时,会出现以下错误: user@machine$make OBJS=other.o main.o g++-Wall-other.o main.o-o main g++:错误:其他。o:没有这样的文件或目录 g++:错误:main.o:没有这样的文件或目录 #生成文件 CPP_COMP=g++ CFLAGS=-Wall CPP_SRC=

我的
all
规则中的echo打印出正确的内容,但是当我将OBJS的定义移动到我注释的行时,makefile不起作用。按原样,makefile会运行,但当我移动OBJS时,会出现以下错误:

user@machine$make
OBJS=other.o main.o
g++-Wall-other.o main.o-o main
g++:错误:其他。o:没有这样的文件或目录
g++:错误:main.o:没有这样的文件或目录

#生成文件
CPP_COMP=g++
CFLAGS=-Wall
CPP_SRC=$(通配符*.CPP)
#在这里定义obj,makefile就可以工作了。在此处定义OBJS*失败,如下所示。
OBJS=$(CPP_SRC:.CPP=.o)
全部:$(OBJS)
@echo“OBJS=$(OBJS)”
$(CPP_COMP)$(CFLAGS)$(OBJS)-o主
#*这里*
#为什么我不能把CPP_SRC和obj放在这里?
#即使我把变量放在这里,上面的echo语句也会输出相应的值。
%.o:%.cpp
$(CPP_COMP)$(CFLAGS)-c$<-o$@
清洁:
rm*.o主管道

Makefile变量设置为
=
(与
:=
)时,仅在使用时,才会对其进行计算和扩展。规则中使用的变量在定义规则时展开(以确定目标和先决条件是什么),但操作中使用的变量在操作实际运行之前不会展开

因此,在您的示例中,设置
OBJS=$(CPP\u SRC:.CPP=.o)
OBJS
设置为实际字符串(使用
$
和所有内容)。然后,当您拥有规则
all:$(OBJS)
时,它将展开
$(OBJS)
,这反过来又展开
$(CPP_SRC)
,然后运行
$(通配符)
…命令。另一方面,操作
@echo“OBJS=$(OBJS)”
再次只记录该字符串,不进行扩展。只有当操作实际运行时(在读取整个Makefile并开始计算要运行的内容之后发生),才会展开
$(OBJS)
操作


因此,向下移动
OBJS的定义意味着在读取规则时它尚未定义(因此它扩展为空字符串),但在运行操作时定义。

Makefile变量设置为
=
(与
相反:=
)只有在使用时,才会在设置时对其进行计算和展开。规则中使用的变量在定义规则时展开(以确定目标和先决条件是什么),但操作中使用的变量在操作实际运行之前不会展开

因此,在您的示例中,设置
OBJS=$(CPP\u SRC:.CPP=.o)
OBJS
设置为实际字符串(使用
$
和所有内容)。然后,当您拥有规则
all:$(OBJS)
时,它会展开
$(OBJS)
,然后展开
$(CPP\u SRC)
,然后运行
$(通配符)
…命令。另一方面,操作
@echo“OBJS=$(OBJS)
再次只记录该字符串,而不进行扩展。只有当操作实际运行时(在读取整个Makefile并开始计算要运行什么之后发生),才会扩展
$(OBJS)

因此,向下移动
OBJS
的定义意味着在读取规则时尚未定义它(因此它扩展为空字符串),但在运行操作时定义它。

正如Spicer将添加:句点。:-)正如Spicer将添加:句点。:-)
#MAKEFILE

CPP_COMP=g++

CFLAGS = -Wall

CPP_SRC = $(wildcard *.cpp) 

#Define OBJS here and the makefile works. Define OBJS *HERE* it fails as shown below.
OBJS = $(CPP_SRC:.cpp=.o)

all: $(OBJS) 
        @echo "OBJS = $(OBJS)"
        $(CPP_COMP) $(CFLAGS) $(OBJS) -o main

#*HERE*
#Why can't I put CPP_SRC and OBJS here?
#The echo statement above prints out the appropriate value even if I put the variables here.

%.o: %.cpp
        $(CPP_COMP) $(CFLAGS) -c $< -o $@

clean:
        rm *.o main