Определите цель make-файла из переменных, установленных с помощью eval - PullRequest
0 голосов
/ 08 мая 2018

Мне нужно определить цель, которая содержит номер версии, который, в свою очередь, извлекается из некоторого файла (предпосылки этой цели), полученного из 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 читает make-файл при первом проходе и не находит переменную 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?

Ответы [ 3 ]

0 голосов
/ 10 мая 2018

Вот гораздо более простой подход:

blackbox.sh:

#!/bin/bash
echo 1.0

Makefile:

dynamic_prerequisite := $(shell ./blackbox.sh)

file_$(dynamic_prerequisite):
    @echo target is $@
0 голосов
/ 12 ноября 2018

Другой вариант - использовать инструмент сборки, более подходящий для динамических целей. Например, я написал Gnu Make-like инструмент, включающий некоторые концепции ReDo от DJB, под названием GoodMake . Ваш эквивалентный make-файл будет просто:

#? version_file
    checkout

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

Проще, а? Если вы попробуете GoodMake, я бы хотел услышать, что вы думаете!

0 голосов
/ 08 мая 2018

Я обнаружил, что проблему можно решить с помощью созданных включаемых файлов .

Для создания самих файлов я создал простой сценарий оболочки, который принимает динамически установленную переменную в качествеаргумент:

#!/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 для создания включенного make-файла 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 по желанию.

Суть в том, что имена целей, которые сами зависят от других целей, должны использовать динамическое создание make-файлов.

...