Многострочные команды 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 случае?

653   4  

4 ответов:

Я хотел бы использовать обратный слеш-новая строка:

foo:
    for i in `find`;     \
    do                   \
        all="$$all $$i"; \
    done;                \
    gcc $$all

UPD.

или, в случае, если просто хотите передать весь список, возвращенный find до gcc:

foo:
    gcc `find`

как указано в вопросе, каждая субкоманда выполняется в своей собственной оболочке. Это делает написание нетривиальных сценариев оболочки немного грязным -- но это возможно! решение состоит в том, чтобы объединить ваш скрипт в то, что make будет рассматривать одну субкоманду (одну строку).

советы по написанию сценариев оболочки в makefiles:

  1. избежать использования скрипта $ заменять $$
  2. преобразовать скрипт для работы в одну строку, вставив ; от команды
  3. если вы хотите написать сценарий на нескольких строках, экранируйте конец строки с помощью \
  4. дополнительно начинаться с set -e чтобы соответствовать положению make для прерывания при сбое субкоманды
  5. это совершенно необязательно, но вы можете заключить сценарий в скобки с () или {} чтобы подчеркнуть связность последовательности из нескольких строк - что это не типичная последовательность команд 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

    Ничего не найдено.