2011-10-27 10 views
5

chciałbym zbudować regułę podobny do tego w moim Makefile:Producent: wykonać akcję dla każdego warunków wstępnych

log: test_A test_B 
    ./test_A >> [email protected] 
    ./test_B >> [email protected] 

ale test_A i test_B są częścią zmiennej $(TESTS).

Czy możliwe jest wykonanie akcji (tutaj: wywołanie programu) dla każdego wymagania wstępnego w GNU/make?

Uwaga: How do I make a makefile rule execute its prerequisites? nie rozwiązuje tego problemu całkowicie, ponieważ wymagany jest cel log (make log).

Odpowiedz

15

Zasadniczo chcesz zapętlić się z wymaganiami wstępnymi. Oczywistym sposobem, aby to zrobić, to punt do powłoki:

log: test_A test_B 
     for f in $^; do ./$$f; done 

Albo można napisać pętlę jako GNU make foreach pętlę, choć trzeba uważać, że polecenia, które wynikają z ciała pętli pojawiają się na oddzielnych liniach (przez define) lub są terminator powłoki (tj średnik, co jest łatwiejsze):

log: test_A test_B 
     $(foreach f,$^,./$(f);) 

Wreszcie, w tym przypadku można to napisać bardziej zwięzły i bardziej niejasno jako zastąpienie wzoru dla każdego zapętlonego elementu:

log: test_A test_B 
     $(patsubst %,./%;,$^) 

(. Jestem pewien, że można dodać przekierowanie wyjścia i $(TESTS) zmienną odpowiednio)

+1

Dzięki za odpowiedź, to potwierdza to, co skończyło się z: '$ (test foreach $ ^, $ (shell ./$(test) >> $ @)) ' – CJlano

+1

Jeśli to polecenia dla twojej reguły _log_, to' $ (shell ...) 'jest rodzajem podważania rzeczy: polecenia dla reguły będą puste , a wykonanie 'test_?' stanie się produktem ubocznym polegającym na odgadywaniu poleceń (zamiast wydawania poleceń). Filozoficznie błędne i - bardziej praktycznie - niemożliwe do rozszerzenia, aby uchwycić błąd jednego z twoich skryptów "testowych". (Ale mimo wszystko wydaje się, że chcesz oznaczyć tę odpowiedź jako zaakceptowaną ...) –

+0

Nie wykonasz tej pętli dwukrotnie, raz dla test_A i raz dla test_B? Mam podobny problem i marka zachowuje się bardzo dziwnie. – Jaseem

Powiązane problemy