首页 > 解决方案 > 从使用 eval 设置的变量定义生成文件目标

问题描述

我必须定义一个包含版本号的目标,该版本号又是从 git 检索的某个文件(此目标的先决条件)中提取的。

我首先尝试的是设置一个变量eval并在名称中使用它,就像这样。

version_file:
  @checkout

version: version_file
  @eval version := get version from version_file

file_$(version):
  @echo file_$(version)

final_target: file_$(version)
  @echo $@

这行不通:make在第一遍中读取 makefile 并没有找到变量dynamic_prerequisite,因此创建的目标只是命名为file_

但是当我尝试动态创建规则时,在设置变量之后,像这样

...
define rule_file_version
file_$(version):
  @echo version: $@
endef

version: version_file
  @eval version := get version from version_file
  $(eval $(rule_file_version))

...这给了我错误信息:

makefile:12: *** 无法在配方中定义先决条件。

当然,我不能将eval目标移到配方之外,因为我遇到了和以前一样的问题。

有没有办法实现我想要的gnu make

标签: makefilegnu-make

解决方案


我发现问题可以通过使用构造的包含文件来解决。

为了构建文件本身,我创建了一个简单的 shell 脚本,它将动态设置的变量作为参数:

#!/bin/bash

read -r -d '' MAKE <<EOF
file_$1:
    @echo version: $1

final_target: file_$1
    @echo final_target: $1
EOF

echo "$MAKE" > rules.mk

这用于makefile创建包含的 makefile rules.mk,如下所示:

version_file:
  @checkout

version: version_file
  @eval version := get version from version_file

rules.mk: version
    $(shell ./create_rules_mk.sh $(version))

-include rules.mk

当我运行make final_target它时,它会根据需要创建rules.mk

对我来说,最重要的是,目标名称本身依赖于其他目标必须使用生成文件的动态创建。


推荐阅读