我的all
规则中的echo打印出正确的内容,但是当我将OBJS的定义移动到我评论的行时,makefile不起作用。同样,makefile运行,但是当我移动OBJS时,我收到以下错误:
user @ machine $ make
OBJS = other.o main.o
g ++ -Wall other.o main.o -o main
g ++:错误:other.o:没有这样的文件或目录
g ++:错误:main.o:没有这样的文件或目录
#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
答案 0 :(得分:2)
使用=
(而不是:=
)设置的Makefile变量在设置时不会被评估和扩展,只有在使用它们时才会被评估和扩展。定义规则时会扩展规则中使用的变量(以确定目标和先决条件是什么),但在操作实际运行之前,操作中使用的变量不会扩展。
因此,在您的示例中,将OBJS = $(CPP_SRC:.cpp=.o)
设置OBJS
设置为该实际字符串(使用$
和所有内容)。然后,当您拥有规则all: $(OBJS)
时,它会展开$(OBJS)
,然后展开$(CPP_SRC)
,然后运行$(wildcard
...命令。另一方面,操作@echo "OBJS = $(OBJS)"
再次只记录没有扩展的字符串。只有当动作实际运行时(在读取整个Makefile之后发生,并且它开始计算要运行的内容)才会$(OBJS)
展开。
因此,向下移动OBJS
的定义意味着它在读取规则时尚未定义(因此它扩展为空字符串),但是在操作运行时定义。