Сделать: Dynami c файл рекурсии? - PullRequest
0 голосов
/ 20 марта 2020

Предположим, у меня есть следующая структура каталогов с root -узлом:


/root/
  Makefile
  branch1/
  branch2/
  .../

И я пишу следующий минимальный make-файл:

branches=$(shell find * -maxdepth 1 -type d -printf "%f "}

%:
    -${MAKE} ${MAKECMDGOALS} -C branch1
    -${MAKE} ${MAKECMDGOALS} -C branch2
    ...

Подготовившись динамически выполнять это реле с переменной branches и безуспешно пробовавшее несколько вариантов правил с подстановочными знаками и потомками, мой вопрос сводится к следующему: как мне захватить любую цель команды из внешней области видимости (как я делаю сейчас) и выполнить команду make relay для каждого из файлов, обнаруженных моим выражением find?

В псевдокоде (не работал с моей версией make, которая является самой последней из доступных на Cygwin):

branches=$(shell find * -maxdepth 1 -type d -printf "%f "}

branch-%:
    -${MAKE} ${MAKECMDGOALS} -C $*

%: ${foreach branch,${branches}, branch-${branch}}

В отличие от оригинального make-файла, это не работает. Однако, похоже, что так и должно быть. Есть ли способ сделать это?

И есть вторая проблема

Параллелизм Make будет нарушен моим методом псевдокода (если он работал) с экспоненциальным веером, используя * Опция 1021 *, тогда как первый метод, который я использовал, не нарушит параллелизм.

Однако, в идеале, этот make-файл должен иметь возможность динамически выполнять одно реле make для каждого файла в списке ветвей. Однако в настоящее время я не вижу способа реализовать это динамически.

1 Ответ

1 голос
/ 20 марта 2020

Во-первых, я не уверен, почему вы используете сложную функцию shell; почему бы просто:

branches := $(wildcard */.)

Или, если вы не хотите, чтобы /. в конце:

branches := $(patsubst %/.,%,$(wildcard */.))

Во-вторых, причина, по которой ваша вторая попытка не работает что нельзя создавать шаблонное правило без рецепта. См. Правила отмены паттернов .

Вместо этого вы можете использовать специальную цель .DEFAULT. Это выглядело бы примерно так:

branch-%:
        -${MAKE} -C $* $(CMD)

.DEFAULT:
        @$(MAKE) CMD=$@ ${addprefix branch-,${branches}}

При этом используется рекурсивная компоновка, и она ведет себя немного иначе, чем ваш оригинал.

Я не уверен, что понимаю ваш второй пункт о -j , GNU make (если вы не используете действительно старую версию) может связываться между всеми субмаками, чтобы гарантировать, что они запускают столько заданий, но не больше, чем вы запрашивали.

О, я забыл, есть еще одно очевидное способ сделать это, если вы не хотите использовать .DEFAULT и рекурсию:

$(MAKECMDGOALS): $(addprefix branch-,$branches))
...