Многострочные команды bash в makefile
у меня есть очень удобный способ скомпилировать мой проект с помощью нескольких строк команд bash. Но теперь мне нужно скомпилировать его через makefile. Учитывая, что каждая команда выполняется в своей собственной оболочке, мой вопрос каков наилучший способ запуска многострочной команды bash, зависящей друг от друга, в makefile?
Например, вот так:
for i in `find`
do
all="$all $i"
done
gcc $all
кроме того, может кто-нибудь объяснить, почему даже однострочная команда bash -c 'a=3; echo $a > file' работает правильно в терминале, но создать пустой файл в Makefile случае?
4 ответов:
Я хотел бы использовать обратный слеш-новая строка:
foo: for i in `find`; \ do \ all="$$all $$i"; \ done; \ gcc $$allUPD.
или, в случае, если просто хотите передать весь список, возвращенный
findдоgcc:foo: gcc `find`
как указано в вопросе, каждая субкоманда выполняется в своей собственной оболочке. Это делает написание нетривиальных сценариев оболочки немного грязным -- но это возможно! решение состоит в том, чтобы объединить ваш скрипт в то, что make будет рассматривать одну субкоманду (одну строку).
советы по написанию сценариев оболочки в makefiles:
- избежать использования скрипта
$заменять$$- преобразовать скрипт для работы в одну строку, вставив
;от команды- если вы хотите написать сценарий на нескольких строках, экранируйте конец строки с помощью
\- дополнительно начинаться с
set -eчтобы соответствовать положению make для прерывания при сбое субкоманды- это совершенно необязательно, но вы можете заключить сценарий в скобки с
()или{}чтобы подчеркнуть связность последовательности из нескольких строк - что это не типичная последовательность команд makefileвот пример, вдохновленный OP:
mytarget: { \ set -e ;\ msg="header:" ;\ for i in $$(seq 1 3) ; do msg="$$msg pre_$${i}_post" ; done ;\ msg="$$msg :footer" ;\ echo msg=$$msg ;\ }
конечно, правильный способ написать Makefile - это фактически документировать, какие цели зависят от каких источников. В тривиальном случае предложенное решение составит
fooзависит от себя, но, конечно,makeдостаточно умен, чтобы отбросить циклическую зависимость. Но если вы добавите временный файл в свой каталог, он "волшебным образом" станет частью цепочки зависимостей. Лучше создать явный список зависимостей раз и навсегда, возможно, с помощью скрипта.GNU make умеет работать
gccчтобы создать исполняемый файл из набора.cи.hфайлы, так что, возможно, все, что вам действительно нужно, составляетfoo: $(wildcard *.h) $(wildcard *.c)
что плохого в том, чтобы просто вызвать команды?
foo: echo line1 echo line2 ....и для вашего второго вопроса, вам нужно избежать
$С помощью$$вместо этого, т. е.bash -c '... echo $$a ...'.изменить: ваш пример может быть переписан в одну строку сценария, как это:
gcc $(for i in `find`; do echo $i; done)
Comments