【发布时间】:2020-03-28 22:47:40
【问题描述】:
我正在尝试创建一个通用的 Makefile 以用于我的大多数项目。它应该按如下方式工作:仅重建和链接那些 .c 或 .h 依赖项已更改的 .o 文件。 .o 和 .d 文件存储在名为“build”的单独目录中。
在官方 GNU Make 手册和一些谷歌搜索的帮助下,我设法实现了所需的行为,除了一件事:当我运行 make re 时出现错误:
Assembler messages: Fatal error: can't create build/ft_build_buffer.o: No such file or directory — 原因是只有在生成 .d 文件时才会创建“build”目录,但由于某种原因,re 规则只是跳过了这一步并继续立即编译 .o 文件!注意:如果我运行make clean && make fclean && make all(应该是完全相同的东西)一切正常。
其他一些事情:我尝试使用 -MMD 选项即时生成依赖项,但在我的机器上导致 .d 文件仅包含 .c 依赖项。当然,我可以让所有 .c 文件都依赖于所有 .h 文件,但这似乎是一个非常草率的解决方案。
请随时分享任何其他建议/改进,以使此文件更加干净和可读,谢谢! :)
# 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[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
clean:
-rm -rf $(BUILD_DIR)
fclean: clean
-rm -f $(BIN)
re: fclean all
【问题讨论】:
-
我认为没有必要有
.d的规则,如果你使用-MD或-MMD与 gcc 它将自动构建它们任何时候对应的 .c 文件是已构建(这将在任何更改以更改该 .c 文件的依赖项时发生)。这样做,.o文件不应该依赖于.d -
@M.M 我已经修改了我的 Makefile 以使用
-MMD选项,令人惊讶的是,现在它可以工作了!我将发布修改后的版本作为答案。感谢您的快速回复! -
不用担心,很高兴你能成功
-
你应该阅读这个:make.mad-scientist.net/papers/…
-
@MadScientist 好的,我会的,谢谢! )