将 OBJ 文件放在 MAKEFILE 的子目录中

put OBJ files in subdirectory in MAKEFILE

我的基本 Makefile 创建 .o 无需使用 gcc 编写一行:

NAME = libtest.h
CC = gcc
CFLAGS = -I. -c
SRCS = example01.c \
       example02.c
OBJ = $(SRCS:.c=.o)

all: $(NAME)
$(NAME): $(OBJ)
       ar -rc $@ $<

我想规则 $(SRCS:.c=.o) 与 运行 $(CC) $(CFLAGS) -o $@ $< 等效,因为我不需要显式调用编译器?

但是,当我尝试对 OBJ 文件中添加的子目录执行相同操作时,它不起作用:

NAME = libtest.h
CC = gcc
CFLAGS = -I. -c
SRCS = example01.c \
       example02.c
ODIR = ./builds
OBJ = $(addprefix $(ODIR)/, $(SRCS:.c=.o))

all: $(NAME)
$(NAME): $(OBJ)
       ar -rc $@ $<

子目录当然已经存在于这个例子中。错误输出是:No rule to make target 'builds/example01.o', needed by 'libtest.a' 我看到了既显式调用编译器又具有规则 $(SRCS:.c=.o) 的解决方案,但我觉得它需要两次调用编译器,然后就不需要了?

这个:

I suppose that the rule $(SRCS:.c=.o) is making an equivalent as running $(CC) $(CFLAGS) -o $@ $<

不太对。如果您不定义自己的规则,Make 有一套 built-in pattern rules 可以应用。其中之一告诉它如何从 foo.c 文件构建 foo.o 文件。

但是 make 没有内置规则告诉它如何从 foo.c 文件构建 ./builds/foo.o 文件,所以你必须自己提供:

$(ODIR)/%.o : %.c
         $(COMPILE.c) -o $@ $<

(这使用内置变量 COMPILE.c,这是内置规则使用的;当然您可以定义自己的)。