重新评估Makefile变量

11

有没有一种方法可以在每次使用时重新评估变量的定义?例如:

MAP_FILES = $(shell find $(TMP) -name "*.map")

all: generate_map_files work_with_map_files

generate_map_files:
   ./map-builder

work\_with\_map_files: $(MAP_FILES)
   ./map-user

%.map:
   ./map-edit $@
因此,当读取makefile时,MAP_FILES将被评估,如果在$TMP目录中没有.map文件,则变量为空。但是,在generate_map_files规则完成后,该目录中将有.map文件,我希望这些.map文件的列表成为work_with_map_files规则的先决条件。
在生成.map文件之前,我不知道.map文件的文件名,因此无法显式声明一个具有文件名的变量。我需要在生成.map文件后设置该变量以包含map文件的列表。任何建议都将非常有帮助。谢谢。
3个回答

5

您可以尝试使用递归make命令,例如:

MAP_FILES = $(shell find $(TMP) -name "*.map")

all: generate_map_files

generate_map_files:
   ./map-builder; $(MAKE) work_with_map_files

work\_with\_map_files: $(MAP_FILES)
   ./map-user

%.map:
   ./map-edit $@

4

使用GNU make,您可以利用makefile重新制作功能,如果在初始通行时更改了任何包含的makefile,则会导致GNU make自动重新启动。例如:

.PHONY: map_files.d
-include map_files.d
map_files.d:
        ./map_builder
        echo "work_with_map_files: `ls *.map`" > map_files.d

work_with_map_files:
        ./map_user

除了重新创建makefile的功能之外,该解决方案还利用了GNU make允许您为目标指定多行先决条件的事实。在这种情况下,地图文件的先决条件在动态生成的map_files.d文件中声明。将map_files.d声明为伪目标可确保在运行构建时始终重新生成它;根据您的需求情况而定,这可能适合或不适合。

1
一般来说,在Makefile中是不可能实现的,因为为了确定目标以及它们的制作顺序,`make`需要在执行规则之前提前知道它们的依赖关系。
在你的例子中,`make`如何知道何时评估`work_with_map_files`规则中的`$(MAP_FILES)`?顺序并没有明确定义,而是从依赖关系中推导出来的。在你的例子中,你希望它在执行`generate_map_files`规则后进行评估,但是`make`无法知道这一点,因为它需要知道这个变量的值来确定依赖关系,而依赖关系又决定了该值的评估顺序 - 这是一个自我引用的循环。

一个简单的技巧当然是运行两次make - 你可以通过在generate_map_files模板中的./mapbuilder命令后添加一个make work_with_map_files命令来自动完成,但是要小心一般情况下,因为如果work_with_map_files实际上被声明依赖于generate_map_files(应该是这样),这将导致无限递归的make循环。当然,这也破坏了make自动确定顺序的想法。否则,您需要一个可以提示此类顺序并进行多次传递的make替代品。

这就是在具有多个包含文件的更大代码库中,其中一个不想在Makefile中重复包含依赖项时,通常使用makedepend生成具有这些依赖项的单独Makefile的原因,该Makefile包含在主Makefile中。要构建一个,首先运行make depend,它调用makedepend生成包含文件依赖项,然后运行make。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接