Makefile 在接触目标文件后不调用操作
Makefile does not invoke action after touching the target file
这是我的 Makefile:
NAME := libftprintf.a
LIB := ar rcs
CC := gcc
CFLAGS := -Wall -Wextra -Werror
SRCS_DIR := ./sources/
HDRS_DIR := ./headers/
OBJS_DIR := ./objectives/
SRCS_FILES := ft_conv.c \
ft_eval_hex.c \
ft_eval_number.c \
ft_eval_string.c \
ft_parsers.c \
ft_strs_join.c \
ft_eval_char.c \
ft_eval_int.c \
ft_eval_percent.c \
ft_handler.c \
ft_printf.c
HDRS_FILES := ft_conv.h \
ft_eval_hex.h \
ft_eval_number.h \
ft_eval_string.h \
ft_parsers.h \
ft_strs_join.h \
ft_eval_char.h \
ft_eval_int.h \
ft_eval_percent.h \
ft_handler.h \
ft_printf.h
OBJS_FILES := $(SRCS_FILES:.c=.o)
SRCS := $(addprefix $(SRCS_DIR),$(SRCS_FILES))
HDRS := $(addprefix $(HDRS_DIR),$(HDRS_FILES))
OBJS := $(addprefix $(OBJS_DIR),$(OBJS_FILES))
LIBFT_DIR := ./libft/
LIBFT_NAME := libft.a
LIBFT := $(addprefix $(LIBFT_DIR),$(LIBFT_NAME))
RM := rm -rf
all: $(NAME)
bonus: all
bonus_one: all
bonus_two: all
$(NAME): $(OBJS)
$(LIB) $(NAME) $(OBJS) $(LIBFT)
$(OBJS_DIR)%.o: $(SRCS_DIR)%.c $(HDRS) Makefile | $(OBJS_DIR) subsystem
$(CC) $(CFLAGS) -c $< -o $@ -I $(HDRS_DIR) -I $(LIBFT_DIR)
subsystem:
@$(MAKE) -C $(LIBFT_DIR)
$(OBJS_DIR):
mkdir $(OBJS_DIR)
clean:
@$(MAKE) -C $(LIBFT_DIR) clean
$(RM) $(OBJS_DIR)
fclean: clean
@$(MAKE) -C $(LIBFT_DIR) fclean
$(RM) $(NAME)
re: fclean all
.PHONY: all subsystem bonus bonus_one bonus_two clean fclean re
问题是这样的:如果我这样做 make all
,那么 touch libftprintf.a
我希望 make all
将重建 libftprintf.a
,因为它已更改并且目标 [=17] =] 取决于该文件。但是,make 什么都不做,我无法理解这种行为。
此外,还有一个小问题:在 make all
期间,我创建了一个目录 objectives
,用于存储所有 .o
文件。调用 make fclean
和 make all
完全重建目标,但是调用 make re
会导致错误:
rm -rf ./objectives/
rm -rf *libft objectives here*
rm -rf libft.a
rm -rf libftprintf.a
make: *** No rule to make target `objectives', needed by `objectives/ft_conv.o'. Stop.
如果我在出现此错误后立即调用 make re
,目标将一如既往地构建。此外,如果我将 re
目标更改为此,我不会收到任何错误:
re:
@$(MAKE) fclean
@$(MAKE) all
无法在 Internet 上的任何地方找到解决我的问题的方法。
触摸 libprintf.a
不会导致任何重建。使重建目标过时。过期意味着目标不存在,或者目标的某些先决条件比目标更新。
在你 运行 make 之后 libprintf.a
是最新的,这意味着它比它的所有先决条件都新。 运行 touch libprintf.a
只是让它比以前的先决条件更新,所以 make 仍然认为它是最新的。
如果你想重建libprintf.a
你需要接触(或删除)它的先决条件之一,而不是目标本身。
你的第二个问题的原因似乎与libft
子目录中的makefile有关。看起来你在这里使用了 --no-print-directories
选项:你应该避免使用它,至少只要你在调试,这样你就可以看到 make 的去向以及它是哪个 makefile 运行宁.
这是我的 Makefile:
NAME := libftprintf.a
LIB := ar rcs
CC := gcc
CFLAGS := -Wall -Wextra -Werror
SRCS_DIR := ./sources/
HDRS_DIR := ./headers/
OBJS_DIR := ./objectives/
SRCS_FILES := ft_conv.c \
ft_eval_hex.c \
ft_eval_number.c \
ft_eval_string.c \
ft_parsers.c \
ft_strs_join.c \
ft_eval_char.c \
ft_eval_int.c \
ft_eval_percent.c \
ft_handler.c \
ft_printf.c
HDRS_FILES := ft_conv.h \
ft_eval_hex.h \
ft_eval_number.h \
ft_eval_string.h \
ft_parsers.h \
ft_strs_join.h \
ft_eval_char.h \
ft_eval_int.h \
ft_eval_percent.h \
ft_handler.h \
ft_printf.h
OBJS_FILES := $(SRCS_FILES:.c=.o)
SRCS := $(addprefix $(SRCS_DIR),$(SRCS_FILES))
HDRS := $(addprefix $(HDRS_DIR),$(HDRS_FILES))
OBJS := $(addprefix $(OBJS_DIR),$(OBJS_FILES))
LIBFT_DIR := ./libft/
LIBFT_NAME := libft.a
LIBFT := $(addprefix $(LIBFT_DIR),$(LIBFT_NAME))
RM := rm -rf
all: $(NAME)
bonus: all
bonus_one: all
bonus_two: all
$(NAME): $(OBJS)
$(LIB) $(NAME) $(OBJS) $(LIBFT)
$(OBJS_DIR)%.o: $(SRCS_DIR)%.c $(HDRS) Makefile | $(OBJS_DIR) subsystem
$(CC) $(CFLAGS) -c $< -o $@ -I $(HDRS_DIR) -I $(LIBFT_DIR)
subsystem:
@$(MAKE) -C $(LIBFT_DIR)
$(OBJS_DIR):
mkdir $(OBJS_DIR)
clean:
@$(MAKE) -C $(LIBFT_DIR) clean
$(RM) $(OBJS_DIR)
fclean: clean
@$(MAKE) -C $(LIBFT_DIR) fclean
$(RM) $(NAME)
re: fclean all
.PHONY: all subsystem bonus bonus_one bonus_two clean fclean re
问题是这样的:如果我这样做 make all
,那么 touch libftprintf.a
我希望 make all
将重建 libftprintf.a
,因为它已更改并且目标 [=17] =] 取决于该文件。但是,make 什么都不做,我无法理解这种行为。
此外,还有一个小问题:在 make all
期间,我创建了一个目录 objectives
,用于存储所有 .o
文件。调用 make fclean
和 make all
完全重建目标,但是调用 make re
会导致错误:
rm -rf ./objectives/
rm -rf *libft objectives here*
rm -rf libft.a
rm -rf libftprintf.a
make: *** No rule to make target `objectives', needed by `objectives/ft_conv.o'. Stop.
如果我在出现此错误后立即调用 make re
,目标将一如既往地构建。此外,如果我将 re
目标更改为此,我不会收到任何错误:
re:
@$(MAKE) fclean
@$(MAKE) all
无法在 Internet 上的任何地方找到解决我的问题的方法。
触摸 libprintf.a
不会导致任何重建。使重建目标过时。过期意味着目标不存在,或者目标的某些先决条件比目标更新。
在你 运行 make 之后 libprintf.a
是最新的,这意味着它比它的所有先决条件都新。 运行 touch libprintf.a
只是让它比以前的先决条件更新,所以 make 仍然认为它是最新的。
如果你想重建libprintf.a
你需要接触(或删除)它的先决条件之一,而不是目标本身。
你的第二个问题的原因似乎与libft
子目录中的makefile有关。看起来你在这里使用了 --no-print-directories
选项:你应该避免使用它,至少只要你在调试,这样你就可以看到 make 的去向以及它是哪个 makefile 运行宁.