#makefile #gnu-make
#makefile #gnu-make
Вопрос:
У меня есть такое Makefile
с содержимым для создания скрипта:
.PHONY cluster-run
cluster-run:
make $(TARGET) --just-print >> tmp_script.sh;
И еще один nn.mk
:
.PHONY nn-model
include Makefile
nn-model:
python run-nn.py
У меня есть два отдельных Make-файла для удобства чтения, потому что их содержимое большое, и у меня есть другие файлы ‘* .mk’, например nn-lstm.mk
, nn-conv.mk
, и т.д.
Я запускаю следующим образом:
make -f nn.mk cluster-run TARGET=nn-model
Но make
выдает ошибку:
make nn-model --just-print >> tmp_script.sh;
make[1]: *** No rule to make target `nn-model'. Stop.
make: *** [cluster-run] Error 2
Для меня такое поведение странно, потому что цель nn-model
действительно существует. Как я могу решить эту проблему?
Ответ №1:
Во-первых, вы никогда не должны использовать raw make
в рецептах. Всегда используйте $(MAKE)
переменную.
Во-вторых, проблема заключается в том, что при запуске вложенного make вы не предоставляете эту -f
опцию:
make nn-model --just-print >> tmp_script.sh;
Из-за этого он читает Makefile
, но нет nn.mk
, и поэтому нет правила для построения цели nn-model
.
Помните, что если вы запускаете подобную вспомогательную команду, это запускает совершенно новый процесс создания с чистого листа: ни одна из целей, определенных в родительском процессе создания, не известна вспомогательной команде при ее запуске.
Я не знаю, что вы подразумеваете под тем, что цель nn_model
действительно существует, но там определенно нет файла с именем nn_model
, иначе вы не получили бы эту ошибку.
Комментарии:
1. Как я могу получить путь, переданный с
-f
аргументом родительскому процессу?2. Я не думаю, что понимаю вопрос, но у дочернего make нет возможности запросить родительский make, чтобы выяснить, что он использовал. Вы должны изменить рецепт родительского make, который вызывает дочерний make, чтобы он передавал правильные параметры. Действительно, я думаю, что ваша организация makefile проблематична, и вам следует сделать что-то другое. Я думаю, что это может быть проблемой XY: если бы вы более четко описали, какую проблему вы пытаетесь решить, структурировав свои makefile таким образом, возможно, мы могли бы предложить лучшие альтернативы.
Ответ №2:
Итак, что происходит, так это то, что при сборке cluster-run
он вызывает рекурсивный make, который считывает Makefile
и запрашивает сборку $(TARGET)
(которая будет включать nn-model
).
Обратите внимание, что рекурсивный make является новым make и не наследует переменные или правила от родительского make, поэтому этот экземпляр make понятия не имеет, как строить nn-model
, если вы хотите, чтобы дочерний make видел это, тогда дочерний make должен включать родительский…