gmake 忽略依赖于 -include 文件的文件
gmake ignores files dependent on -include files
为了用实际使用 make
的东西替换我们从另一个项目继承的混乱的独立 makefile(如 this question 中所述,我遇到了一个gmake 3.81
忽略它无法生成也无法找到的文件的相当不寻常的情况。
这是一个演示问题的简短示例文件:
# 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 脚本将 Intel 编译器套件的等效输出(同样是一项要求)转化为有用的东西。
- 我考虑过预先测试每个文件的存在,但在生成依赖文件之前并不是所有文件都是已知的。就目前而言,只有这个文件,目录中没有其他文件,no shell 命令得到执行。
这似乎是 gmake 3.81 及更高版本中的错误,与 this bug. I've reported this specific bug 相关,因为它略有不同。
我选择使用的解决方法受到上述 link 的启发,如下所示:
# 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)
为了用实际使用 make
的东西替换我们从另一个项目继承的混乱的独立 makefile(如 this question 中所述,我遇到了一个gmake 3.81
忽略它无法生成也无法找到的文件的相当不寻常的情况。
这是一个演示问题的简短示例文件:
# 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 脚本将 Intel 编译器套件的等效输出(同样是一项要求)转化为有用的东西。
- 我考虑过预先测试每个文件的存在,但在生成依赖文件之前并不是所有文件都是已知的。就目前而言,只有这个文件,目录中没有其他文件,no shell 命令得到执行。
这似乎是 gmake 3.81 及更高版本中的错误,与 this bug. I've reported this specific bug 相关,因为它略有不同。
我选择使用的解决方法受到上述 link 的启发,如下所示:
# 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)