【问题标题】:Define a makefile target from variables set with eval从使用 eval 设置的变量定义生成文件目标
【发布时间】:2018-05-08 10:58:25
【问题描述】:

我必须定义一个包含版本号的目标,该版本号又是从 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 实现我想要的?

【问题讨论】:

  • 您似乎想在黑匣子中计算dynamic_prerequisite 的值。您对黑盒是脚本还是规则有偏好?
  • 这是我用例中的一个脚本。
  • 现在,看到您的回答,我意识到我的示例实际上过于简化了。我的回答也应该是“规则”,因为脚本本身取决于另一个目标。我将编辑问题以反映这一点。

标签: makefile gnu-make


【解决方案1】:

我发现问题可以通过constructed include files来解决。

为了构建文件本身,我创建了一个简单的 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

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

【讨论】:

    【解决方案2】:

    这是一个更简单的方法:

    blackbox.sh:

    #!/bin/bash
    echo 1.0
    

    生成文件:

    dynamic_prerequisite := $(shell ./blackbox.sh)
    
    file_$(dynamic_prerequisite):
        @echo target is $@
    

    【讨论】:

      【解决方案3】:

      另一种选择是使用更适合动态目标的构建工具。例如,我编写了一个类似于 Gnu Make 的工具,它结合了 DJB 的 ReDo 中的一些概念,称为 GoodMake。您等效的 makefile 将是:

      #? version_file
          checkout
      
      #? final_target
          $0 version_file     # Static dependency
          version=$(get version from version_file)
          $0 file_$version    # Dynamic dependency
      

      更简单,对吧?如果您试用 GoodMake,我很想听听您的想法!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多