连续两次“make all”不返回“make:'all'没有任何事情要做。”
我注意到有很多人有消息“make:没有为'all'完成”的问题,但是我的问题恰恰相反。 这是我的生成文件:连续两次“make all”不返回“make:'all'没有任何事情要做。”
#################
## VARIABLES ##
#################
# Environment
OS := $(shell uname)
# Output
NAME := libft.a
DYNAMIC_NAME := ${NAME:a=so}
# Compiler
CC := gcc
ifneq ($(OS), Linux)
FLAGS += -Wall -Wextra -Werror
endif
DYN_FLAG := -shared
HEADERS := -I ./includes/
O_FLAG := -O2
# Directories
ADDITIONAL_FUNCTIONS = $(addprefix ./additional_functions/, $(ADDITIONAL))
BONUS_FUNCTIONS = $(addprefix ./bonus_functions/, $(BONUS))
LIBC_FUNCTIONS = $(addprefix ./libc_functions/, $(LIBC))
PERSONAL_FUNCTIONS = $(addprefix ./personal_functions/, $(PERSONAL))
DYN_OBJDIR = dyn_build/
OBJDIR := build/
# Sources
ADDITIONAL += ft_itoa.c
ADDITIONAL += ft_memalloc.c ft_memdel.c
ADDITIONAL += ft_putchar.c ft_putchar_fd.c
ADDITIONAL += ft_putendl.c ft_putendl_fd.c
ADDITIONAL += ft_putnbr.c ft_putnbr_fd.c
ADDITIONAL += ft_putstr.c ft_putstr_fd.c
ADDITIONAL += ft_strclr.c ft_strdel.c
ADDITIONAL += ft_strnew.c ft_strjoin.c
ADDITIONAL += ft_strequ.c ft_strnequ.c
ADDITIONAL += ft_striter.c ft_striteri.c
ADDITIONAL += ft_strmap.c ft_strmapi.c
ADDITIONAL += ft_strsplit.c ft_strsub.c ft_strtrim.c
BONUS += ft_lstadd.c ft_lstnew.c
BONUS += ft_lstdel.c ft_lstdelone.c
BONUS += ft_lstiter.c ft_lstmap.c
LIBC += ft_atoi.c
LIBC += ft_isalnum.c ft_isalpha.c ft_isascii.c
LIBC += ft_isdigit.c ft_isprint.c
LIBC += ft_memcpy.c ft_memccpy.c ft_memchr.c ft_memcmp.c
LIBC += ft_bzero.c ft_memmove.c ft_memset.c
LIBC += ft_strcat.c ft_strlcat.c ft_strncat.c
LIBC += ft_strchr.c ft_strrchr.c
LIBC += ft_strcmp.c ft_strncmp.c
LIBC += ft_strcpy.c ft_strncpy.c ft_strdup.c
LIBC += ft_strlen.c
LIBC += ft_strstr.c ft_strnstr.c
LIBC += ft_tolower.c ft_toupper.c
PERSONAL += ft_intlen.c
PERSONAL += ft_invert.c ft_islower.c ft_isupper.c
PERSONAL += ft_lstgetnode.c ft_lstsize.c
PERSONAL += ft_kill.c ft_putuchar.c ft_putuchar_fd.c
PERSONAL += ft_strrev.c ft_strrevcpy.c
PERSONAL += get_next_line.c
DYN_OBJECTS = $(patsubst %.c,$(DYN_OBJDIR)%.o,$(SRCS))
OBJECTS = $(patsubst %.c,$(OBJDIR)%.o,$(SRCS))
SRCS += $(ADDITIONAL_FUNCTIONS)
SRCS += $(BONUS_FUNCTIONS)
SRCS += $(LIBC_FUNCTIONS)
SRCS += $(PERSONAL_FUNCTIONS)
#################
## RULES ##
#################
all: $(NAME)
$(NAME): $(OBJECTS)
@ar rcs [email protected] $(patsubst %.c,$(OBJDIR)%.o,$(notdir $(SRCS)))
ranlib [email protected]
@echo "Static library created."
$(OBJECTS): | $(OBJDIR)
$(OBJDIR):
@mkdir -p [email protected]
$(OBJDIR)%.o: %.c
$(CC) $(FLAGS) $(O_FLAG) -c $< $(HEADERS) -o $(OBJDIR)$(notdir [email protected])
$(DYN_OBJECTS): | $(DYN_OBJDIR)
$(DYN_OBJDIR):
@mkdir -p [email protected]
$(DYN_OBJDIR)%.o: %.c
$(CC) $(FLAGS) $(O_FLAG) -c $< $(HEADERS) -fpic -o $(DYN_OBJDIR)$(notdir [email protected])
clean:
@/bin/rm -rfv $(OBJDIR)
@/bin/rm -rfv $(DYN_OBJDIR)
fclean: clean
@/bin/rm -fv $(NAME)
@/bin/rm -fv $(DYNAMIC_NAME)
re: fclean all
so: $(DYN_OBJECTS)
@$(CC) $(DYN_FLAG) -o $(DYNAMIC_NAME) $(patsubst %.c,$(DYN_OBJDIR)%.o,$(notdir $(SRCS)))
@echo "Dynamic library created."
.PHONY: all build clean dynbuild fclean re so
makefile工作得很好。它将不同目录中的每个.c文件创建一个对象目录,编译/如果该库是静态的,并且dyn_build /如果它是动态的,则将目标文件放入该目录中并从它们编译库。
我的问题是,如果我连续两次运行make,第二次不应该做任何事情,因为对象文件和库仍然存在并且是最新的。但是,不知怎的,连续两次导致第二次重复操作。
这是什么原因造成的,有没有办法解决这个问题?
你的问题可以减少到这一点:
ADDITIONAL += ft_strsplit.c
BONUS += ft_lstadd.c
ADDITIONAL_FUNCTIONS = $(addprefix ./add/, $(ADDITIONAL))
BONUS_FUNCTIONS = $(addprefix ./bonus/, $(BONUS))
SRCS += $(ADDITIONAL_FUNCTIONS)
SRCS += $(BONUS_FUNCTIONS)
OBJECTS = $(patsubst %.c,./build/%.o,$(SRCS))
# OBJECTS contains ./build/./add/ft_strsplit.o and ./build/./bonus/ft_lstadd.o
all: $(OBJECTS)
$(OBJDIR)%.o: %.c
$(CC) ...
所以要运行与例如最后的规则作为目标的是build/./add/ft_strsplit.o
,以及add/ft_strsplit.c
作为前提条件。问题是如何编写配方以构建build/ft_strsplit.o
。
正如@ user657267指出的那样,有一个(非PHONY)规则不会生成一个名称是规则目标的文件是错误的。因此,让我们首先要问做出我们实际需要的文件:
ADDITIONAL += ft_strsplit.c
BONUS += ft_lstadd.c
SRCS += $(ADDITIONAL)
SRCS += $(BONUS)
OBJECTS = $(patsubst %.c,./build/%.o,$(SRCS))
# OBJECTS contains ./build/ft_strsplit.o and ./build/ft_lstadd.o
到目前为止好,但现在如何使找到来源?当我们要求Make制造./build/ft_strsplit.o
时,它怎么知道ft_strsplit.c
是哪里?
我们使用vpath:
vpath %.c add bonus
现在的makefile正常工作。并vpath
线自动写入这一点,我们可以只拉目录名了分配:
# Directories
ADDITIONAL_DIR := ./additional_functions
BONUS_DIR := ./bonus_functions
...
ADDITIONAL_FUNCTIONS = $(addprefix $(ADDITIONAL_DIR)/, $(ADDITIONAL))
BONUS_FUNCTIONS = $(addprefix $(BONUS_DIR)/, $(BONUS))
...
vpath %.c $(ADDITIONAL_DIR)
vpath %.c $(BONUS_DIR)
...
正是我需要的。感谢您的回答,并让我了解vpath。 –
试着去'make --trace'或使用['remake'](http://bashdb.sourceforge.net/remake /)用'-x'来了解更多发生了什么 –
我看到了从现在开始的地方,谢谢! –
'$(OBJDIR)$(notdir $ @)'和'$(DYN_OBJDIR)$(notdir $ @)'打破第二条规则[here](http://make.mad-scientist.net/papers/rules- of-makefiles /),对象文件的配方不会创建您在规则中指定的文件。 – user657267