переоценить переменные makefile - PullRequest
9 голосов
/ 17 февраля 2009

Есть ли способ пересмотреть определение переменной при каждом использовании? Например:

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 $@

Итак, MAP_FILES будет оцениваться при чтении make-файла, и если в каталоге $ TMP нет файлов .map, переменная будет пустой. Однако после выполнения правила generate_map_files в каталоге появятся файлы .map, и я бы хотел, чтобы список этих файлов .map был предварительным условием для правила work_with_map_files.

Я не знаю имен файлов .map до их генерации, поэтому я не могу объявить переменную с именами файлов явно. Мне нужно, чтобы переменная была установлена ​​со списком файлов карт после их создания. Любые предложения будут очень полезны. Спасибо.

Ответы [ 3 ]

4 голосов
/ 17 февраля 2009

Вы можете попробовать сделать рекурсивное создание, что-то вроде

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 $@
3 голосов
/ 22 марта 2009

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

В дополнение к функции переделки make-файла, это решение использует тот факт, что GNU make позволяет вам указать несколько строк предварительных условий для цели. В этом случае предварительные требования файла карты объявляются в динамически генерируемом файле map_files.d. Объявление map_files.d в качестве цели PHONY гарантирует, что оно всегда восстанавливается при запуске сборки; это может или не может быть целесообразным в зависимости от ваших потребностей.

0 голосов
/ 17 февраля 2009

В общем случае это невозможно в Makefiles, потому что для определения того, какие цели нужно сделать и в каком порядке, make необходимо заранее знать их зависимости, прежде чем будут выполнены правила.

В вашем примере, как make узнает, когда оценивать $(MAP_FILES) в правиле work_with_map_files? Порядок не определен явно, но выводится из зависимостей. В вашем примере вы хотите, чтобы оно оценивалось после выполнения правила generate_map_files, но у make нет способа узнать это, поскольку ему необходимо знать значение этой переменной для зависимостей, которые необходимы для определения порядок, в котором будет оцениваться это значение - это самоссылочный цикл.

Конечно, один простой трюк состоит в том, чтобы запустить make дважды - это можно сделать автоматически, добавив команду make work_with_map_files после команды ./mapbuilder в шаблоне generate_map_files, но будьте осторожны с этим в целом, потому что если work_with_map_files фактически будет объявлено зависимым от generate_map_files (что и должно быть), что приведет к бесконечному рекурсивному циклу make. И, конечно, это опровергает идею автоматического определения порядка make. В противном случае вам понадобится замена make, на которую могут быть намеки на такие заказы и сделать несколько проходов.

Это причина того, что в больших кодовых базах с несколькими включаемыми файлами, где не требуется повторять включаемые зависимости в Makefile, makedepend часто используется для генерации отдельного Makefile с этими зависимостями, который включены в основной Makefile. Для его создания сначала запускается make depend, который вызывает makedepend для генерации зависимостей включаемого файла, а затем make.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...