我的基本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 $@ $<
等效,因为我不需要显式调用编译器吗?
但是,当我尝试在wich中添加一个子目录去做同样的事情时,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)
的解决方案,但我觉得它两次都需要编译器,而无需?
答案 0 :(得分:1)
此:
我想规则$(SRCS:.c = .o)相当于运行$(CC)$(CFLAGS)-o $ @ $ << / p>
不太正确。 Make有一套built-in pattern rules,如果您未定义自己的规则,则可以应用。其中之一告诉它如何从foo.o
文件构建foo.c
文件。
但是make没有内置的规则来告诉它如何从./builds/foo.o
文件构建foo.c
文件,因此您必须自己提供:
$(ODIR)/%.o : %.c
$(COMPILE.c) -o $@ $<
(这使用内置变量COMPILE.c
,这是内置规则使用的;当然,您可以定义自己的变量)。