【发布时间】:2021-02-07 16:23:05
【问题描述】:
我有一个 Makefile 定义一个变量依赖目标,如下所示:
SRCFILES=./src/main.c ./src/file.c
# Get the filenames of all the sources
SRCNAMES=$(notdir $(SRCFILES))
OBJDIR=./obj/
# Replace .c to .o in all source names
OBJNAMES=$(SRCNAMES:.c=.o)
# Add the obj/ repository as prefix
OBJFILES=$(addprefix $(OBJDIR), $(OBJNAMES))
NAME=myprog
all: $(NAME)
$(NAME): $(OBJFILES)
gcc $(OBJFILES) -o $(NAME)
$(OBJDIR)%.o: ./src/%.c
mkdir -p $(OBJDIR)
gcc -c $< -o $@
# If the make debug rule is called, I want my objects to be build into ./obj/debug/
debug: OBJDIR = ./obj/debug/
debug: all
有了这个 Makefile,当我运行 make debug 时,我有以下输出:
❯ make debug
mkdir -p ./obj/debug/
gcc -c src/main.c -o obj/main.o
mkdir -p ./obj/debug/
gcc -c src/file.c -o obj/file.o
gcc ./obj/debug/main.o ./obj/debug/file.o -o myprog
gcc: error: ./obj/debug/main.o: No such file or directory
gcc: error: ./obj/debug/file.o: No such file or directory
gcc: fatal error: no input files
compilation terminated.
make: *** [Makefile:16: myprog] Error 1
我的问题出在这个输出的前两行:
mkdir -p ./obj/debug/ # <----------- Here we see that the $(OBJDIR) variable has been updated
gcc -c src/main.c -o obj/main.o # <-- However, the $@ variable which is generated from $(OBJDIR)%.o hasn't been updated accordingly
如何使$@ 自动变量在 $(OBJDIR) 更改时更新?
【问题讨论】:
-
您的
OBJFILES=$(addprefix $(OBJDIR), $(OBJNAMES))似乎是在您更新debug: OBJDIR = ./obj/debug/之前设置的。在填充...FILES变量之前,您需要确保设置了要使用的目录。 -
@DavidC.Rankin 我不这么认为,
OBJFILES变量已正确更新,如第 5 行所示:gcc ./obj/debug/main.o ./obj/debug/file.o -o myprog -
是的,但
./obj/debug/main.o ./obj/debug/file.o不存在。它们被编译到上面的cc -c src/main.c -o obj/main.o。 -
@DavidC.Rankin 是的,这是我的问题。
-o $@应该是./obj/debug/main.o,因为它来自$(OBJDIR)%.o,并且OBJDIR在调用all之前由debug重新定义。我无法提前知道 Makefile 是否会使用debug规则调用。 -
我过去处理这个问题的唯一方法是将变量传递给
make,例如make with=debug然后检查ifeq ($(with), debug)然后更新目录位置。否则,如果make debug应该自动为您处理 - 我必须返回文档并弄清楚。