Для каждой цели переменной Makefile - PullRequest
0 голосов
/ 11 сентября 2018

У меня есть make-файл, который выглядит следующим образом

apps = app1 app2 app3

all: dir app1 app2 app3 zip cleanup

Теперь я хочу сделать цикл в списке apps varible,

что-то вроде

`loop on apps

endloop`

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

update

Допустим, эта переменная (apps) сгенерирована моей программой в файле make, которые предоставляют для каждого проекта различные значения приложений, иногда его apps= app1 app2иногда его apps= app1, а иногда может быть 20 или более приложений apps= app1 app2 appN

Как я могу перебрать apps переменную и сделать что-то, например, в каждой итерации вывести что-то вроде:

now im in `app1`
now im in `app2`
etc

При попытке следующего

.PHONY: foo
all: foo
APPS = app1 app2 app3 app4
foo : $(APPS)
    for $$f in $(APPS); do echo $$f is here; done

я получил следующую ошибку:

make: *** No rule to make target app1 ', необходимый для foo'. Stop.

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Я вижу, что вы пошли взад-вперед, поэтому позвольте мне сделать комментарий, который может или не может помочь.

Как правило, вы не пишете циклы внутри make recipes, потому что make самобеспечивает "зацикливание".Поэтому, когда вы пишете правило вроде:

all: app1 app2 app3 app4

, make будет пытаться создать каждую из этих предпосылок, по одной за раз.Поэтому, если вы хотите иметь make-файл, который отображает строку для каждой записи в переменной apps, вы должны сделать это так:

all: $(apps)

$(apps):
        @echo $@

Это говорит make, чтобы начать с цели all и попробовать«построить» каждое из его предварительных условий, которые являются значениями в переменной apps.

Затем вы определяете правило для того, как создавать приложения, и для каждого вы говорите, что это правило echo $@где $@ - это автоматическая переменная , которая расширяется до цели, создаваемой в настоящее время.

В make синтаксис:

foo bar biz:
        some command

сокращен и идентиченto, написание:

foo:
        some command
bar:
        some command
biz:
        some command

Важная вещь при написании make-файлов заключается в том, что вы думаете, как написать правило для создания одного файла (цели) из нуля или более необходимых файлов.Затем вы позволите себе позаботиться о том, как соединить все эти предпосылки вместе и правильно их упорядочить.

ETA Если вам нужно специальное правило для одной конкретной цели в длинном списке, хранящемся в $(apps) переменная, вы можете сделать это:

$(filter-out bar,$(apps)):
        @echo print $@

bar:
        some other command
0 голосов
/ 11 сентября 2018

Может быть, вы хотите что-то вроде (и я предполагаю, что некоторая другая часть Makefile описывает, как app1 и app2 и т. Д. ... должны быть построены с соответствующими правилами).

foo: app1 app2 app3 app4 
     for f in $^ ; do echo $$f is here ; done

или (немного лучше)

APPS = app1 app2 app3 app4
foo : $(APPS)
     for f in $(APPS); do echo $$f is here; done

и вас может заинтересовать foreach функция в make (или, возможно, ее eval функция , возможно, смешанная с чем-то другим)

Наконец, ваш make-файл (или некоторые части , включающие в себя ) может быть сгенерирован каким-либо скриптом (shell, AWK, Python, ...) (или даже другой программой, написанной на C ++, Java, Окамл, как хочешь)

Я рекомендую использовать римейк , как remake -x, для отладки вашего Makefile

Вы также можете сгенерировать submakefile и запустить $(MAKE) -f submakefile по некоторому рецепту.

Я настоятельно рекомендую потратить как минимум один час на чтение полностью , документация GNU делает перед тем, как что-то кодировать в Makefile. И вам также может понадобиться прочитать документацию bash.

Наконец, вы можете рассмотреть другой инструмент автоматизации сборки, например ninja (философия которого отличается : ожидается, что файл build.ninja будет сгенерирован и вы должны предоставить генератор для этого)

Для вашего следующего вопроса, пожалуйста, предоставьте MCVE

...