为什么 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)
。
我正在尝试为我的项目创建一个库,但我对 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)
。