【问题标题】:Unexpected prerequisite skip in GNU Make 4.2.1GNU Make 4.2.1 中意外的先决条件跳过
【发布时间】: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 好的,我会的,谢谢! )

标签: c makefile gnu-make


【解决方案1】:

这是@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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多