GNU Make 4.2.1 中意外跳过先决条件
Unexpected prerequisite skip in GNU Make 4.2.1
我正在尝试创建一个通用 Makefile 以用于我的大部分项目。它应该按如下方式工作:只重建和 link 那些 .o 文件 .c 或 .h 依赖已经改变。 .o 和 .d 文件存储在名为 'build'.
的单独目录中
在官方 GNU Make 手册和一些谷歌搜索的帮助下,我已经设法实现了所需的行为,除了一件事:当我 运行 make re
我得到错误:
Assembler messages: Fatal error: can't create build/ft_build_buffer.o: No such file or directory
— 原因是 'build' 目录仅在生成 .d 文件时创建,但由于某种原因 re
rule 直接跳过这一步直接编译 .o 文件!注意:如果我 运行 make clean && make fclean && make all
(这应该是完全一样的东西)一切正常。
其他一些事情:我尝试使用 -MMD
选项动态生成依赖项,但在我的机器上导致 .d 文件仅包含 .c 依赖项。当然,我可以让所有 .c 文件都依赖于所有 .h 文件,但这似乎是一个非常草率的解决方案。
欢迎分享任何其他 advice/improvements 将使此文件更清晰和可读的内容,谢谢! :)
# Define the C compiler to use.
CC := gcc
# Define any compile-time flags.
CFLAGS := -I./include -Wall -Wextra -Werror -g
#CFLAGS := -I./include -march=native -O2 -pipe
# Define the executable file.
BIN := ft_hexdump
# Define build directory.
BUILD_DIR := build
# Define source files directory.
SRC_DIR := src
# Define the C source files.
SRCS := $(wildcard $(SRC_DIR)/*.c)
# Define the C object files.
OBJS := $(SRCS:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o)
# Define the prerequisite files.
DEPS := $(OBJS:%.o=%.d)
.PHONY: all clean fclean re
.DELETE_ON_ERROR:
all: $(BIN)
-include $(DEPS)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $^ -o $@
$(BUILD_DIR)/%.o: $(BUILD_DIR)/%.d
$(CC) $(CFLAGS) -c $(SRC_DIR)/$*.c -o $@
$(BUILD_DIR)/%.d: $(SRC_DIR)/%.c
@mkdir -p $(@D)
@set -e; rm -f $@; \
$(CC) $(CFLAGS) $(INCLUDE) -MM $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
clean:
-rm -rf $(BUILD_DIR)
fclean: clean
-rm -f $(BIN)
re: fclean all
这是@M.M
建议的修改后的工作版本
# Define the C compiler to use.
CC := gcc
# Define any compile-time flags.
CFLAGS := -I./include -Wall -Wextra -Werror -g
#CFLAGS := -I./include -march=native -O2 -pipe
# Define the executable file.
BIN := ft_hexdump
# Define build directory.
BUILD_DIR := build
# Define source files directory.
SRC_DIR := src
# Define the C source files.
SRCS := $(wildcard $(SRC_DIR)/*.c)
# Define the C object files.
OBJS := $(SRCS:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o)
# Define the prerequisite files.
DEPS := $(OBJS:%.o=%.d)
.PHONY: all clean fclean re
.DELETE_ON_ERROR:
all: $(BIN)
-include $(DEPS)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $^ -o $@
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
@mkdir -p $(@D)
$(CC) $(CFLAGS) -MMD -c $(SRC_DIR)/$*.c -o $@
clean:
-rm -rf $(BUILD_DIR)
fclean: clean
-rm -f $(BIN)
re:
$(MAKE) fclean
$(MAKE) all
我正在尝试创建一个通用 Makefile 以用于我的大部分项目。它应该按如下方式工作:只重建和 link 那些 .o 文件 .c 或 .h 依赖已经改变。 .o 和 .d 文件存储在名为 'build'.
的单独目录中在官方 GNU Make 手册和一些谷歌搜索的帮助下,我已经设法实现了所需的行为,除了一件事:当我 运行 make re
我得到错误:
Assembler messages: Fatal error: can't create build/ft_build_buffer.o: No such file or directory
— 原因是 'build' 目录仅在生成 .d 文件时创建,但由于某种原因 re
rule 直接跳过这一步直接编译 .o 文件!注意:如果我 运行 make clean && make fclean && make all
(这应该是完全一样的东西)一切正常。
其他一些事情:我尝试使用 -MMD
选项动态生成依赖项,但在我的机器上导致 .d 文件仅包含 .c 依赖项。当然,我可以让所有 .c 文件都依赖于所有 .h 文件,但这似乎是一个非常草率的解决方案。
欢迎分享任何其他 advice/improvements 将使此文件更清晰和可读的内容,谢谢! :)
# Define the C compiler to use.
CC := gcc
# Define any compile-time flags.
CFLAGS := -I./include -Wall -Wextra -Werror -g
#CFLAGS := -I./include -march=native -O2 -pipe
# Define the executable file.
BIN := ft_hexdump
# Define build directory.
BUILD_DIR := build
# Define source files directory.
SRC_DIR := src
# Define the C source files.
SRCS := $(wildcard $(SRC_DIR)/*.c)
# Define the C object files.
OBJS := $(SRCS:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o)
# Define the prerequisite files.
DEPS := $(OBJS:%.o=%.d)
.PHONY: all clean fclean re
.DELETE_ON_ERROR:
all: $(BIN)
-include $(DEPS)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $^ -o $@
$(BUILD_DIR)/%.o: $(BUILD_DIR)/%.d
$(CC) $(CFLAGS) -c $(SRC_DIR)/$*.c -o $@
$(BUILD_DIR)/%.d: $(SRC_DIR)/%.c
@mkdir -p $(@D)
@set -e; rm -f $@; \
$(CC) $(CFLAGS) $(INCLUDE) -MM $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
clean:
-rm -rf $(BUILD_DIR)
fclean: clean
-rm -f $(BIN)
re: fclean all
这是@M.M
建议的修改后的工作版本# Define the C compiler to use.
CC := gcc
# Define any compile-time flags.
CFLAGS := -I./include -Wall -Wextra -Werror -g
#CFLAGS := -I./include -march=native -O2 -pipe
# Define the executable file.
BIN := ft_hexdump
# Define build directory.
BUILD_DIR := build
# Define source files directory.
SRC_DIR := src
# Define the C source files.
SRCS := $(wildcard $(SRC_DIR)/*.c)
# Define the C object files.
OBJS := $(SRCS:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o)
# Define the prerequisite files.
DEPS := $(OBJS:%.o=%.d)
.PHONY: all clean fclean re
.DELETE_ON_ERROR:
all: $(BIN)
-include $(DEPS)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $^ -o $@
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
@mkdir -p $(@D)
$(CC) $(CFLAGS) -MMD -c $(SRC_DIR)/$*.c -o $@
clean:
-rm -rf $(BUILD_DIR)
fclean: clean
-rm -f $(BIN)
re:
$(MAKE) fclean
$(MAKE) all