C-构成file编译对象并移动它们的麻烦



这是我的makefile:

.PHONY : clean fclean re $(LIB_PATH) 
NAME = fillit
FLAGS = -Wall -Wextra -Werror
LIB_NAME = libft.a
LIB_DIR = ../libft/
LIB_PATH = $(LIB_DIR)$(LIB_NAME)
OBJ_DIR_NAME = objects
OBJ_DIR = $(OBJ_DIR_NAME)/
HEADER_DIR = ../libft/
SRC = main.c func1.c
OBJ = $(SRC:.c=.o)
all :
    mkdir -p $(OBJ_DIR_NAME)
    $(MAKE) $(NAME)
$(NAME): $(OBJ_DIR)$(OBJ) $(LIB_PATH)
    gcc -o $(NAME) $(addprefix $(OBJ_DIR), $(OBJ)) -L$(LIB_DIR) -lft -I$(HEADER_DIR)
$(LIB_PATH):
    $(MAKE) -C $(LIB_DIR) --no-print-directory
$(OBJ_DIR)%.o : %.c
    gcc $(FLAGS) -I $(HEADER_DIR) -c $<
    -mv $(@F) $(OBJ_DIR)
clean : 
    -rm $(addprefix $(OBJ_DIR), $(OBJ))
    -rm -rv $(OBJ_DIR_NAME)
fclean : clean
    -rm $(NAME)
    $(MAKE) -C $(LIB_DIR) fclean --no-print-directory
re: fclean
    make

当我制作时,我希望规则$(OBJ_DIR)%.o : %.c编译两个对象(func1.c main.c)并将它们移至对象目录。但是该规则仅发生在SRC

中的第一个源文件时发生

编译两个对象(reader.c main.c)

您是指func1.c而不是reader.c

如果是这种情况,请检查func1.c文件是否与main.c相同的目录。如果它不在同一目录中,则必须编写另一个模式规则。这样的东西:

FUNC1_DIR = # The directory where your func1.c is located, maybe src/ or something alike
$(OBJ_DIR)%.o : $(FUNC1_DIR)%.c
    gcc $(FLAGS) -I $(HEADER_DIR) -c $<
    -mv $(@F) $(OBJ_DIR)

$(NAME): $(OBJ_DIR)$(OBJ)不将$(objdir)应用于每个项目$(OBJ)。从字面上看,它只是将$(objdir)连接到列表中。这就是为什么您的模式规则只有一个实例(只有一个.o具有该模式试图匹配的路径前缀)。

而是使用:

OBJ_WITH_PATH := $(foreach obj,$(OBJ),$(OBJ_DIR)$(obj))

然后将您名称规则的依赖性更新为

$(NAME): $(OBJ_WITH_PATH) $(LIB_PATH)

顺便说一句,我发现添加

之类的规则有时很有帮助
.PHONY: DEBUG
DEBUG:
    @echo MAKING SURE THIS WORKS: $(OBJ_DIR)$(OBJ)
    @echo ALTERNATE: $(OBJ_WITH_PATH)

然后您可以运行调试目标:

$ make DEBUG
MAKING SURE THIS WORKS temp/a.o b.o
ALT temp/a.o temp/b.o

最新更新