2016-10-18 4 views
0

Предположим, у меня есть следующие иерархии файлов:GNU сделать каждый подкаталог

Makefile 
dir1/ 
    script.sh 
    other_files.txt 
dir2/ 
    script.sh 
    other_stuff.dat 
dir3/ 
    script.sh 
    other_data.csv 

... где script.sh скрипт, который работает без каких-либо косметическим возможность вывода (например echo "Hello world!" В моем реальном примере, каждый dir. является R-пакетом).

Я пытаюсь создать Makefile, который будет запускать script.sh в каждом dir, но только если что-то в каталоге изменилось. То, что я пытался до сих пор это:

DIRS := dir1 dir2 dir3 
RUNFILES := $(DIRS:%=run.%) 

.PHONY: all ${DIRS} 

all: ${DIRS} 

dir2: dir3 

% : run.% 

run.% : $(wildcard %/*) 
    $(@D)/script.sh 
    touch [email protected] 

... где каждый вызов script.sh следует просто прикоснувшись новый run.dirX файл (например, dir/script1.sh; touch run.dir1). Но это не работает - работает make all просто говорит, что целей нет.

Кажется, должен быть чистый способ сделать это без неуклюжего решения о том, что скрипт генерирует весь makefile ... но я не уверен, что это такое. Есть предположения?

+0

Вы хотите сделать, чтобы запустить сценарий, если и только если ничего не изменилось? Обычно Make делает вещи только в том случае, если что-то изменилось. То, что вы просите, возможно, но решение может быть неудобным. – Beta

+0

Упс! Я имел в виду, если что-то изменилось, в типичной манере. Соответственно изменил мой вопрос. –

ответ

1

Вы очень близки. Мы можем устранить несколько ненужных шагов и имеют runfiles как основные цели:

DIRS := dir1 dir2 dir3 
RUNFILES := $(DIRS:%=run.%) 

.PHONY: all 
all: $(RUNFILES) 

Единственная хитрость заключается в том, что если мы ставим wildcard в список пререквизитов, сделать имеет тенденцию к расширению его до принятия решения, который нацелен на build-- когда правило шаблона по-прежнему является только правилом шаблона, и для сканирования нет каталога с именем «%». Таким образом, мы используем SECONDEXPANSION и дополнительный «$», чтобы сделать, чтобы отложить расширение до после того, как он выбрал стебель:

.SECONDEXPANSION: 
run.%: $$(wildcard %/*) 
    @$*/script.sh 
    @touch [email protected] 
+0

'.SECONDEXPANSION' - какое колдовство это !? Спасибо, это сработало красиво! –

Смежные вопросы