【问题标题】:gmake ignores files dependent on -include filesgmake 忽略依赖于 -include 文件的文件
【发布时间】:2015-06-10 19:18:51
【问题描述】:

为了用实际使用 make 的东西替换我们从另一个项目继承的混乱的独立 makefile(如 this question 中所述,我遇到了一个相当不寻常的情况,其中 @ 987654324@ 忽略它无法生成也找不到的文件。

这是一个演示问题的简短示例文件:

# Remove ALL default rules
.SUFFIXES:
(%): %
%.out: %
%.c: %.w %.ch
%.tex: %.w %.ch
%:: %.v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%

SOURCES = a.c b.c

OBJS = $(SOURCES:%.c=%.o)

DEPFILES = $(SOURCES:%.c=%.c.d)

EXE = a

.PHONY: all
all: $(EXE)

$(DEPFILES): %.c.d : %.c
        @echo "Determining dependencies for $(<F)"
        @$(CC) -E -MM -MF$@ -MP $<

$(OBJS): %.o: %.c
        @echo "Compiling $(<F)"
        @$(CC) -c $< -o $@

$(EXE): $(OBJS)
        @echo "Linking $(@F)"
        @$(CC) $+ -o $@

# This seems to be the troublemaking line!
-include $(DEPFILES)

如果缺少一个或多个源文件,则不会按预期生成对应的.d 文件,不会将源文件标记为丢失。如果我用一个简单的make 命令运行它,输出nothing,退出状态为2。

有什么办法可以解决这个问题吗?

哦,虽然在这个例子中看起来很傻,但我在这个项目中确实有几个限制:

  • 我们必须使用gmake 3.81。不允许升级或修补。
  • 完整的 makefile 同时构建了一个调试版本和一个发布版本,因此依赖项是单独生成的,一劳永逸。事实证明,这种方式更简单。
  • 在这里使用静态模式规则似乎很愚蠢,但在大型 makefile 中它可以解决很多问题。
  • 在实际系统中,依赖项的实际生成要复杂得多,我使用我编写的 Perl 脚本将英特尔编译器套件的等效输出(同样,要求)转化为有用的东西。
  • 我考虑过预先测试每个文件的存在,但在生成依赖文件之前,并不是所有文件都是已知的。就目前而言,只有这个文件,目录中没有其他文件,no shell 命令会被执行。

【问题讨论】:

  • all : $(DEPFILES) $(EXE) 也许?强制依赖文件成为其他东西的先决条件,而不仅仅是 -include 指令,根据定义,它会忽略命名文件的不存在。
  • 这可能适用于这个简化的示例,但找出在具有可能数十个不同目标的复杂 makefile 中添加先决条件的位置可能并不容易。
  • @JoeSewell 考虑使用remake 来帮助您以交互方式确定先决条件可能的去向。
  • 我很乐意,@rocky,但我们不允许添加未经批准的软件。此外,make -d 显示 make 的输出可能会忽略 -include 文件的先决条件,而忘记注意正确的目标-先决条件关系。如果我被允许,我会检查这是否已在 4.1 中修复,但同样,这是一个安全问题。

标签: makefile gnu-make


【解决方案1】:

这似乎是 gmake 3.81 及更高版本中的一个错误,与 this bug 有关。我已经报告了this specific bug,因为它略有不同。

我选择使用的解决方法受到上述链接的启发,如下所示:

# Remove ALL default rules
.SUFFIXES:
(%): %
%.out: %
%.c: %.w %.ch
%.tex: %.w %.ch
%:: %.v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%

SOURCES = a.c b.c

# WORKAROUND: check for existence of files here
EXISTING_SOURCES = $(wildcard $(SOURCES))
MISSING_SOURCES = $(filter-out $(EXISTING_SOURCES),$(SOURCES))
ifneq "" "$(MISSING_SOURCES)"
$(error Missing source files: $(MISSING_SOURCES))
endif
# END WORKAROUND

OBJS = $(SOURCES:%.c=%.o)

DEPFILES = $(SOURCES:%.c=%.c.d)

EXE = a

.PHONY: all
all: $(EXE)

$(DEPFILES): %.c.d : %.c
    @echo "Determining dependencies for $(<F)"
    @$(CC) -E -MM -MF$@ -MP $<

$(OBJS): %.o: %.c
    @echo "Compiling $(<F)"
    @$(CC) -c $< -o $@

$(EXE): $(OBJS)
    @echo "Linking $(@F)"
    @$(CC) $+ -o $@

# This seems to be the troublemaking line!
-include $(DEPFILES)

【讨论】:

    猜你喜欢
    • 2011-01-13
    • 2013-02-08
    • 2015-06-16
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 1970-01-01
    • 2017-08-11
    • 2022-01-17
    相关资源
    最近更新 更多