Gnu make:是否有可能将include指令延迟到二次扩展?

时间:2015-05-22 00:59:29

标签: include makefile gnu-make

我需要延迟包含依赖片段直到第二个扩展时间,因为我编辑的make文件本身就是一个包含文件,我将不会有源文件列表来生成包含,直到二次扩展。

.SECONDEXPANSION:
AUTO_DEPENDENCY_FILES = $(patsubst %.cc, depend/%.d, $(CC_SRC_FILES))

# the following does the work because the include argument is not a rule
# prerequisite therefore no secondary expansion occurs
include $$(AUTO_DEPENDENCY_FILES)

depend:
    -mkdir depend

all: autodepend

autodepend: depend autodepend_include

autodepend_include: $$(AUTO_DEPENDENCY_FILES)
    @echo \"$^\"

$$(AUTO_DEPENDENCY_FILES): depend

depend/%.d: | %.cc
    # generate .d files that do not exist
    $(COMPILE.cc) -E $*.cc > /dev/null

%.o: %.cc
    # update .d files that exist
    $(COMPILE.cc) -o $@ $<

注意COMPILE.cc是一个非常长的字符串,包含用于生成自动依赖关系的-MP -MMD -MFdepend/$*.d个标志。

1 个答案:

答案 0 :(得分:1)

我不知道这个问题有一个干净的解决方案,但有一点点黑客可以让你得到你想要的东西。

给出主要Makefile

$(info main one)

include depend.mk

$(info main two)

CC_SRC_FILES := $(addsuffix .c,a b c d e f)

$(info main three)

depend.mk

$(info depend one)

AUTO_DEPENDENCY_FILES = $(patsubst %.c,%.d,$(CC_SRC_FILES))
$(info AUTO_DEPENDENCY_FILES := $(AUTO_DEPENDENCY_FILES))
$(info MAKE_RESTARTS := $(MAKE_RESTARTS))
$(info CC_SRC_FILES := $(CC_SRC_FILES))

$(info depend two)

运行make时会得到以下输出:

main one
depend one
AUTO_DEPENDENCY_FILES :=
MAKE_RESTARTS :=
CC_SRC_FILES :=
depend two
main two
main three
make: `all' is up to date.

鉴于分配顺序和包含文件等,这并不奇怪。

这是可怕的黑客入侵的地方。

当make遇到引用不存在的文件的include指令时,make将文件粘贴在“missing include files”列表中并继续解析makefile。

当它到达makefile的末尾时,它会尝试将该列表中的每个条目视为潜在的目标目标 1 并尝试生成该文件。< / p>

一旦构建了makefile,make就会自行重启并再次尝试。

您可以使用它来捕获makefile包含的内置makefile中CC_SRC_FILES的值,并在需要时显示它。

如果我们将depend.mk看起来像这样:

$(info depend one)

include hack.mk

AUTO_DEPENDENCY_FILES = $(patsubst %.c,%.d,$(CC_SRC_FILES))
$(info AUTO_DEPENDENCY_FILES := $(AUTO_DEPENDENCY_FILES))
$(info MAKE_RESTARTS := $(MAKE_RESTARTS))
$(info CC_SRC_FILES := $(CC_SRC_FILES))

$(info depend two)

hack.mk: $(if $(MAKE_RESTARTS),,force)
        @echo creating hack.mk
        @echo 'CC_SRC_FILES := $(CC_SRC_FILES)' > '$@'

force: ;

然后make的输出变为:

main one
depend one
depend.mk:3: hack.mk: No such file or directory
AUTO_DEPENDENCY_FILES :=
MAKE_RESTARTS :=
CC_SRC_FILES :=
depend two
main two
main three
creating hack.mk
main one
depend one
AUTO_DEPENDENCY_FILES := a.d b.d c.d d.d e.d f.d
MAKE_RESTARTS := 1
CC_SRC_FILES := a.c b.c c.c d.c e.c f.c
depend two
main two
main three
make: `all' is up to date.

这为我们提供了我们想要的价值。

这不是很漂亮,但确实有效。