我的Makefile正在重新链接,我找不到原因。
我不确定为什么malloc会假设必须执行$(NAME)。 $(SRC:.c = .o)宏是否会更改.o文件的时间戳或类似内容?
CC = gcc
NAME = app
#
CFLAGS = -Wall -Werror -Wextra -pedantic -pedantic-errors
INCLUDES = -I ./includes
#
DIRSRC = srcs/
DIROBJ = objs/
SRC += main.c
SRC += malloc.c
OBJ = $(SRC:.c=.o)
DIROBJS = $(addprefix $(DIROBJ), $(OBJ))
#
LIBS_PATH = ./libs
LIBFT_PATH = $(LIBS_PATH)/libft
LIBFT_INCLUDES = -I $(LIBFT_PATH)
LIBFT = -L $(LIBFT_PATH) -lft
#
COMPILE = $(CC) $(CFLAGS) $(INCLUDES)
#
all: $(NAME)
$(NAME): configure libs $(DIROBJS)
$(COMPILE) $(LIBFT) $(DIROBJS) -o $(NAME)
$(DIROBJ)%.o: $(DIRSRC)%.c
@echo Compiling: $<
$(COMPILE) $(LIBS_INCLUDES) -c $< -o $@
clean:
@rm -rf $(DIROBJ)
fclean: clean
@rm -rf $(NAME)
re: fclean all
#
configure:
@mkdir -p $(DIROBJ)
#
libs:
@$(MAKE) -C $(LIBS)
.PHONY: all configure clean fclean re libs cleanlibs fcleanlibs relibs
答案 0 :(得分:1)
它始终重新链接,因为configure
规则将始终运行。因此,Make认为其中一个依赖项已更改,并重新评估该规则。
我解决这个问题的方法是摆脱configure
规则并在构建目标文件的规则中移动@mkdir -p $(DIROBJS)
:
$(DIROBJ)%.o: $(DIRSRC)%.c
@mkdir -p $(DIROBJS)
@echo Compiling: $<
$(COMPILE) $(LIBS_INCLUDES) -c $< -o $@
可能有更多的原因(可能与您正在建造的图书馆有关),我不知道。如果这完全解决了,请告诉我们。
答案 1 :(得分:1)
@ rtur的答案有效,但我应该提到另一种选择。你可以这样做:
$(DIROBJ):
mkdir $@
$(DIROBJ)/%.o: $(DIRSRC)/%.c | $(DIROBJ)
@echo Compiling: $<
$(COMPILE) $(LIBS_INCLUDES) -c $< -o $@
这样,只有当目录不存在时才会生成目录。需要注意的是|
符号。这使$(DIROBJ)
成为order-only先决条件。这意味着如果它比目标更新,则不会导致目标重建。这对于目录非常重要,因为目录的时间戳是添加/删除/修改其中最后一项的日期,并且您的目标在没有该符号的情况下总是过时。这被认为更干净,因为这种方式调用mkdir
的次数较少。
此外,作为样式注释,通常,您不会在目录名称的末尾包含尾随/
。 $(OBJ_DIR)/%.o
看起来比$(OBJ_DIR)%.o
好。当然,这可能只是我的观点: - )