为什么Makefile不包括头文件?



我正试图为我的项目制作一个库,但我对Makefiles非常非常陌生。我尝试了几种配置并添加了-I,但都不起作用。

我有以下三个:

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

和下面的makefile:

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选项,并且目标文件被写入src/而不是obj/

从这里你应该意识到你的模式规则根本没有被使用,取而代之的是使用它的内置规则来构建目标文件。

为什么你的模式规则没有被使用?我们来看看:

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

变量展开后是什么?

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

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

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

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

接下来,这是错误的:

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

$(HDR)是什么?这是文件的名称:include/libft.h。你不包括头文件名与-I;您包括目录查找头文件。所以这里需要的是$(HDR_DIR)

最新更新