为什么 Makefile 不包含 header?

Why is Makefile not including the header?

我正在尝试为我的项目创建一个库,但我对 Makefile 非常陌生。我尝试了几种配置并添加了 -I 但 none 有效。

我有以下三个:

libft/
../includes/
....libft.h
../lst
....ft_lstnew.c
....ft_lstadd_front.c
....ft_lstadd_back.c
....  [...]
../src
....ft_isalpha.c
....ft_isalnum.c
....  [...]

以及以下生成文件:

NAME=libft.a

LIBSO=libft.so

CC=gcc

CFLAGS=-Wall -Wextra -Werror

SRC_DIR=src/

BONUS_DIR=lst/

OBJ_DIR=obj/

SRC_FILES=  ft_bzero.c      \
            ft_isalmun.c    \
            ft_isalpha.c    \
            ft_isascii.c    \
            ft_isdigit.c    \
            ft_isprint.c    \
            ft_memchr.c     \
            ft_memcpy.c     \
            ft_memmove.c    \
            ft_memset.c     \
            ft_strchr.c     \
            ft_strlcat.c    \
            ft_strlcpy.c    \
            ft_strlen.c     \
            ft_strncmp.c    \
            ft_strrchr.c    \
            ft_tolower.c    \
            ft_toupper.c    

BONUS_FILES=ft_lstadd_back.c    \
            ft_lstadd_front.c   \
            ft_lstdelone.c      \
            ft_lstclear.c       \
            ft_lstiter.c        \
            ft_lstlast.c        \
            ft_lstmap.c         \
            ft_lstnew.c         \
            ft_lstsize.c        

SRC_PATH=$(addprefix $(SRC_DIR), $(SRC_FILES))

BONUS_PATH=$(addprefix $(BONUS_DIR), $(BONUS_FILES))

SRC_NAMES=$(SRC_FILES:.c=.o)

BONUS_NAMES=$(BONUS_FILES:.c=.o)

SRC_PATH_O=$(addprefix $(SRC_DIR), $(SRC_NAMES))

BONUS_PATH_O=$(addprefix $(BONUS_DIR), $(BONUS_NAMES))

HDR_NAME=libft.h

HDR_DIR=includes/

HDR= $(addprefix $(HDR_DIR),$(HDR_NAME))

all: $(NAME)

$(NAME): $(SRC_PATH_O)
    ar rc $@ $<
    ranlib $@

$(OBJ_DIR):
    mkdir $@

$(OBJ_DIR)%.o: $(SRC_DIR)%.c $(HDR_NAME)
    $(CC) $(CFLAGS) -c $< -o $@ -I $(HDR)

clean:
    rm -rf $(OBJ_DIR)
    
fclean: clean
    rm -f $(NAME)

re: fclean all

.PHONY: all clean fclean re

每次我在终端上输入 make 时,我都会收到这个消息:

gcc -Wall -Wextra -Werror   -c -o src/ft_bzero.o src/ft_bzero.c
src/ft_bzero.c:1:10: fatal error: libft.h: No such file or directory
    1 | #include "libft.h"
      |          ^~~~~~~~~
compilation terminated.
make: *** [<builtin>: src/ft_bzero.o] Error 1

我错过了什么吗?这真的是我第一次。

是的,您遗漏了一些东西。

首先看命令行make显示:

gcc -Wall -Wextra -Werror   -c -o src/ft_bzero.o src/ft_bzero.c

请注意,此处的输出不适合您创建的模式规则的配方:没有 -I 选项,并且 object 文件正在写入 src/obj/.

从这里你应该意识到你的模式规则根本没有被使用,相反 make 正在使用它的 built-in 规则来构建 object 文件。

为什么你的模式规则没有被使用?一起来看看吧:

$(OBJ_DIR)%.o: $(SRC_DIR)%.c $(HDR_NAME)

变量展开后这是什么?

obj/%.o: src/%.c libft.h

此模式(与所有模式一样)只有在所有先决条件都已经存在或可以构建的情况下才能匹配。 src/%.c 在模式替换后存在。 libft.h 呢?不,那不存在。 存在的是 includes/libft.h,但这不是一回事。

因此,此规则无法匹配,make 将返回使用其默认规则。

如果你想说每个 object 文件都依赖于那个 header,你必须在编写模式时使用 header 文件的正确路径。

接下来,这是错误的:

$(CC) $(CFLAGS) -c $< -o $@ -I $(HDR)

什么是$(HDR)?它是文件的名称:include/libft.h-I 中不包括 header 个文件名;您包括了 目录 ,header 是在其中查找的。所以您在这里需要 $(HDR_DIR)