混淆Makefile规则
在第一个示例中Makefile工作正常,而在第二个示例中完全不工作,这让我有点困惑 工作:混淆Makefile规则,makefile,gnu-make,Makefile,Gnu Make,在第一个示例中Makefile工作正常,而在第二个示例中完全不工作,这让我有点困惑 工作: CC=gcc CFLAGS=-Wall -Wextra -Werror FILES=$(addprefix src/, ft_putnbr ft_putchar main) OBJ=$(addsuffix .o, $(FILES)) NAME=put $(NAME): $(OBJ) $(CC) -o $(NAME) $(OBJ) %.o: %.c gcc -c $^ -o $@ $(CF
CC=gcc
CFLAGS=-Wall -Wextra -Werror
FILES=$(addprefix src/, ft_putnbr ft_putchar main)
OBJ=$(addsuffix .o, $(FILES))
NAME=put
$(NAME): $(OBJ)
$(CC) -o $(NAME) $(OBJ)
%.o: %.c
gcc -c $^ -o $@ $(CFLAGS) -I includes/
clean:
rm -f $(OBJ)
不工作:
CC=gcc
CFLAGS=-Wall -Wextra -Werror
FILES=$(addprefix obj/, ft_putnbr ft_putchar main)
OBJ=$(addsuffix .o, $(FILES))
NAME=put
$(NAME): $(OBJ)
$(CC) -o $(NAME) $(OBJ)
%.o: $(subst obj,src, %.c)
gcc -c $^ -o $@ $(CFLAGS) -I includes/
clean:
rm -f $(OBJ)
唯一的区别是将FILES前缀设置为obj/,因为我想将obj文件与源文件分开,所以需要使用$(substitute)函数来更改其中一个规则中的目录。
第二个Makefile生成:
make: *** No rule to make target 'obj/ft_putnbr.o', needed by 'put'. Stop.
有人看到我的错误了吗?在makefile中,需要扩展的上下文是
$(…)
或${…}
模式规则不是其中之一。因此:
%.o: %.c
...
由make
解释为stem.o
由stem.c
通过执行…
,对于stem
的任何值,但%.o:%.c
的形式不是$(…)
,而是
没有扩大
因此,在上下文中
%.o: $(subst obj,src, %.c)
含义:
$(subst obj,src, %.c)
简单地说就是:将字符串%.c
中所有出现的obj
替换为src
。
字符串%.c
中没有出现obj
。所以结果就是%.c
,
不变。因此,您的第二个makefile相当于:
CC=gcc
CFLAGS=-Wall -Wextra -Werror
FILES=$(addprefix obj/, ft_putnbr ft_putchar main)
OBJ=$(addsuffix .o, $(FILES))
NAME=put
$(NAME): $(OBJ)
$(CC) -o $(NAME) $(OBJ)
%.o: %.c
gcc -c $^ -o $@ $(CFLAGS) -I includes/
clean:
rm -f $(OBJ)
其中,例如,目标obj/ft_putnbr.o
将满足
规则%.o:%.c
当且仅当存在一个先决条件obj/ft\u putnbr.c
。
但它并不存在。因此:
No rule to make target 'obj/ft_putnbr.o
而是使用:
Makefile
CC=gcc
CFLAGS=-Wall -Wextra -Werror
SRCS=ft_putnbr.c ft_putchar.c main.c
OBJS=$(addprefix obj/,$(SRCS:.c=.o))
NAME=put
$(NAME): $(OBJS)
$(CC) -o $(NAME) $(OBJS)
obj/%.o: src/%.c | obj
gcc -c $< -o $@ $(CFLAGS) -I includes/
obj:
mkdir -p $@
clean:
rm -fr obj $(NAME)
CC=gcc
CFLAGS=-Wall-Wextra-Werror
SRCS=ft_putnbr.c ft_putchar.c main.c
OBJS=$(addprefix obj/,$(SRCS:.c=.o))
NAME=put
$(名称):$(OBJS)
$(CC)-o$(名称)$(OBJS)
obj/%.o:src/%.c | obj
gcc-c$<-o$@$(CFLAGS)-I包括/
obj:
mkdir-p$@
清洁:
rm-fr obj$(名称)
或类似的。顺便提一下,这个makefile确保目录obj
存在
在尝试将任何对象文件编译到其中之前,请将该目录设置为
$(OBJS)