2015-11-30 3 views
1

В моем проекте, у меня есть набор программ, которые строят из источников:марка: автоматическое выполнение целевых

SRC_FILES = $(wildcard $(SRC_DIR)/*.cpp) 
TARGETS = $(patsubst $(SRC_DIR)/%.cpp,$(BIN_DIR)/%,$(SRC_FILES)) 

Моя цель сборки проста и работает отлично:

all: $(TARGETS) 
    @echo "- Done target [email protected]" 

сейчас , Я хочу цель run, чтобы все эти программы запускались из оболочки по запросу. Скажем, если у меня есть 3 файлов, я хочу сделать для автоматического запуска:

>$ ./test1 
>$ ./test2 
>$ ./test3 

Или

>$ ./test1 && ./test2 && ./test3 

Я попытался это:

run: $(TARGETS) 
    $(addsuffix && ,$(TARGETS)) 

Это порождает следующую команду:

./test1&& ./test2&& 

но это не удается из-за след ING &&

(Конечно, я хочу, чтобы они были сгенерированы автоматически, так как может быть 3 ... или 30.)

Edit: собственно, && разделитель не требуется, так что-то вроде этого :

>$ ./test1; ./test2; ./test3; 

будет хорошо.

+0

Для записи, кроме ответов ниже, '$ (addsuffix;, $ (TARGETS))' тоже выполняет задание. – kebs

ответ

1

Как альтернатива полностью правильный ответ Basile Starynkevitch в here есть (по крайней мере) два других варианта, а также.

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

run: $(TARGETS) 
     $< $(addprefix &&,$(wordlist 2,$(words $^),$^)) 

Лучший вариант Я думаю, что, если предположить, что соединение команды с && не является необходимостью будет использовать $(foreach) генерировать команду, которая будет работать.

run: $(TARGETS) 
     $(foreach t,$^,$t;) 

Задний ; в том, что это важно как выход из $(foreach) представляет собой одну строку, и вы должны ; прекратить каждую команду оболочки (или она рассматривается как один длинный команды с аргументами).

2

Выпей .PHONY линию вблизи начала Makefile с

.PHONY: all run 

Вы могли бы иметь

run: $(TARGETS) 
    $(addsuffix && ,$(TARGETS)) true 

но это свинство.

Может быть, вы хотите, чтобы произвести вывод test2 в test2.out, то вы можете иметь

TESTSCRIPTS= $(wildcard test*[0-9]) 
run: $(patsubst %, %.out, $(TESTSCRIPTS)) 

test%.out: test% 
# here some command to run the test% 
+0

Спасибо. Хах! Мне нравится «истинный» трюк. Второе решение не может работать, так как мои имена файлов произвольны. – kebs

+0

До тех пор, пока у вас есть список тестовых файлов, вы можете адаптировать ... –

+2

Альтернативно '$ <$ (addprefix &&, $ (wordlist 2, $ (words $ ^), $ ^))' или '$ (foreach t, $ (TARGETS), $ t;) ', хотя последнее немного изменяет семантику. –

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