重新评估GNU make makefile变量

时间:2018-12-13 02:32:21

标签: makefile gnu-make

我继承了一个大型分支项目?这要求将易失的.a档案集$(LIB_FILES)包含到链接目标中,该链接目标位于某些目录$(LIB_DIRS)中。我可以这样写一个表达式:

LIBDEP = $(foreach ldir, $(LIB_DIRS), \
    $(filter $(addprefix %/, $(LIB_FILES)), $(wildcard $(ldir)/* )))

问题在于它们可能在make调用时不存在,而是通过在另一个目标规则内调用$(MAKE)来构建的,这是链接步骤的先决条件。

问题在于应创建的文件的实际列表取决于在构建步骤中确定的外部因素,因此我无法正确地对其进行硬编码,而不会将makefile变成意大利面条,并且无法重新评估该变量在链接命令调用时。

我怀疑$(eval)函数可以以某种方式使用,但是手册不是很好,因为我没有找到以这种方式使用它的示例。

工具链:GCC和binutils,制作3.81

2 个答案:

答案 0 :(得分:2)

另一种解决方案是在当前创建变量$(LIB_FILES)的步骤的输出上创建make脚本的显式依赖项。这是手册在How makefiles are remade章中所要处理的内容,它的目标是最擅长的技术,即从文件(而不是变量)的存在和时间戳导出依赖关系。以下通过推导由两个变量$(LIBS_THIS_TIME)$(LIB_CONFIG_SET)模拟的一组新库的过程,希望可以描述您的情况。

LIBS_THIS_TIME = foo.a:baz.a:bar.a
LIB_CONFIG_SET = $(subst :,_,$(LIBS_THIS_TIME))

include libdeps.d

linkstep:
    @echo I am linking $^ now
    touch $@

libdeps.d: $(LIB_CONFIG_SET)
    -rm libdeps.d
    $(foreach lib,$(subst :, ,$(LIBS_THIS_TIME)),echo linkstep: $(lib) >> libdeps.d;)

$(LIB_CONFIG_SET):
    touch $@

如果make发现libdeps.d不是最新的当前库配置,则尽管make并不是makefile中的第一个目标,但它会在make执行任何其他规则之前被重新制作。这样,如果您的构建过程创建了一组新的或不同的库,则libdeps.d将首先被重新制作,然后make才能继续使用您顶层makefile中的其他目标,现在有了正确的依赖信息。

答案 1 :(得分:1)

有时候,您需要连续多次调用make。一种可能的方式是使用条件:

ifeq ($(STEP),)
all:
    <do-first-step>
    $(MAKE) STEP=2 $@
else ifeq ($(STEP),2)
all:
    <do-second-step>
    $(MAKE) STEP=3 $@
else ifeq ($(STEP),3)
all:
    <do-third-step>
endif

在每个步骤中,您都可以生成新文件并将其存在以供下一步使用。