为何静态库未包含源码中全部函数?Makefile问题求助
问题分析与解决
你的Makefile存在关键错误:所有目标文件都在编译同一个源文件,导致静态库中实际只有第一个函数的目标代码重复存在,其他函数的代码根本没被编译进去。
错误根源
看第21行的模式规则:
$(OBJS_DIR)%.o : $(SRC_PREFIXED)
这里把所有源文件(src/ft_isalpha.c src/ft_strlen.c)作为每个.o文件的依赖,而编译命令里用了$<——这个变量只会取依赖列表的第一个文件。所以不管是生成objs/ft_isalpha.o还是objs/ft_strlen.o,实际都是编译SRC列表里的第一个源文件,最终两个.o文件内容完全一致。当用ar打包时,重复的目标文件会被忽略,所以静态库只能访问第一个被编译的函数。
修正方案
把模式规则改成每个.o对应单个.c文件,替换第21-23行:
$(OBJS_DIR)%.o : $(SRC_DIR)%.c @mkdir -p $(OBJS_DIR) $(CC) $(FLAGS) -c $< -o $@
这样规则会自动匹配对应关系:
objs/ft_isalpha.o依赖src/ft_isalpha.cobjs/ft_strlen.o依赖src/ft_strlen.c
编译时$<会取到对应的源文件,生成正确的目标文件。
修正后的完整Makefile
SRC = ft_isalpha.c \ ft_strlen.c SRC_DIR = src/ SRC_PREFIXED = $(addprefix $(SRC_DIR), $(SRC)) NAME = libft.a OBJS_DIR = objs/ OBJS = $(SRC:.c=.o) OBJS_PREFIXED = $(addprefix $(OBJS_DIR), $(OBJS)) CC = gcc FLAGS = -Wall -Wextra -Werror $(OBJS_DIR)%.o : $(SRC_DIR)%.c @mkdir -p $(OBJS_DIR) $(CC) $(FLAGS) -c $< -o $@ $(NAME): $(OBJS_PREFIXED) ar r $(NAME) $(OBJS_PREFIXED) @echo $(SRC_PREFIXED) all: $(NAME) clean: @rm -rf $(OBJS_DIR) @echo "objects directory deleted" fclean: clean @rm -rf $(NAME) @echo ".a file deleted"
验证方法
修正后执行make,可以用nm libft.a查看静态库中的符号,应该能看到ft_isalpha和ft_strlen两个函数的条目,证明两个函数都被正确打包进去了。
内容的提问来源于stack exchange,提问作者hboudra
相关产品推荐
相关产品推荐

