2013-03-27 2 views
2

здесь является частью моего Makefile:Makefile: Еогеасп «сделать -C» называют

PATH := $(shell pwd) 
EDIR := impl 
EFFECTS := $(filter-out $(EDIR), $(shell find $(EDIR) -maxdepth 1 -type d)) 
ALLMAKES := $(patsubst %, $(PATH)/%, $(EFFECTS)) 


all: 
     $(foreach c,$(ALLMAKES),$(MAKE) -C $(c)) 

Так, по существу, я хочу назвать сделать для всех каталогов в каталоге «осущий» без «осущий» самого по себе. Я понимаю, что make запомнит последний каталог, который был при последнем вызове с аргументом -C, поэтому я даю абсолютный путь каждый раз. Что делать эхо, кажется, что я хочу:

make -C <projectdir>/impl/thing1 make -C <projectdir>/impl/thing2 make -C <projectdir>/impl/thing3 

Вопрос заключается в том, что делают не выполняет команду и просто печатает:

make: make: Command not found. 

я могу назвать «сделать -C < путь >» для каждого из каталогов отдельно вне make-файла, но он не работает в вызове foreach. Я пробовал это, но он не работает:

$(foreach c,$(ALLMAKES),$(shell make -C $(c))) 

Любые идеи?

+0

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

+0

Я удалил свой комментарий, потому что думал Я был на неправильном пути. Я работаю над лучшим ответом ... – Beta

ответ

8

Это потому, что вы вызываете один номер make с множеством аргументов, включая последующие команды make. Вам нужно добавить разделитель команд оболочки между вызовами make. Что-то вроде этого будет работать:

all: 
     $(foreach c,$(ALLMAKES),$(MAKE) -C $(c) &&) true 

Во втором взгляде есть другие проблемы с вашим make-файлом. Вы не должны устанавливать переменную make с именем PATH, потому что она будет переопределять переменную $PATH субголда. Вы можете просто использовать встроенную переменную make $(CURDIR), а не работать $(shell pwd). Вам фактически не нужно префиксные каталоги с контуром вообще, потому что запуск $(MAKE) -C ... не изменяет рабочий каталог shell, просто сделайте, и когда вы сделаете выходы, он будет установлен назад, поэтому вы можете просто использовать относительный путь ,

Также вызывает некоторые проблемы в подписях в цикле. Во-первых, вы уменьшаете количество распараллеливания, которое вы можете получить. Во-вторых, опция -k не может быть должным образом поддержана (без особых неприятных усилий). Лучший способ справиться с этой проблемой, чтобы воспользоваться тем, что сделать уже знает как построить много целей:

all: $(EFFECTS) 
$(EFFECTS): 
     $(MAKE) -C [email protected] 
.PHONY: all $(EFFECTS) 

Если у вас есть конкретные вопросы упорядочения между различными подкаталогами, вы можете определить их как скважина:

impl/thing2: impl/thing1 

и т. д. Это обеспечивает максимальные возможности параллелизации, сохраняя при этом важный порядок.

Чтобы добавить альтернативные правила, скажем, для clean, вы можете сделать что-то вроде этого:

CLEAN_EFFECTS := $(addsuffix .clean,$(EFFECTS)) 
clean: $(CLEAN_EFFECTS) 
$(CLEAN_EFFECTS): 
     $(MAKE) -C $(basename [email protected]) clean 
.PHONY: clean $(CLEAN_EFFECTS) 

Это хорошо, потому что вы можете также создать единый подкаталог (и все его предпосылки), запустив make impl/thing1, например. Или очистите их, запустив make impl/thing1.clean

Если у вас их больше, вы также можете получить представление о правилах шаблонов и т. Д., Чтобы избежать повторения этого для каждого типа цели. Это становится более громоздким.

+0

Ох * это * умный. – Beta

+2

Как правило, в моих файлах make-файлов я не люблю запускать суб-элементы в оболочном цикле, как это, потому что (а) он уменьшает возможности параллелизма с '-j' и (b), почти невозможно заставить его работать правильно с в отношении опции '-k'. Но это быстрое и грязное решение, которое отвечает на конкретный вопрос и будет работать. Я добавлю альтернативу, которая «чище». – MadScientist

+0

Спасибо! Это последнее предложение сделало трюк. Я обращу внимание на ваши другие предложения для будущих make-файлов (поскольку мне не понадобится $ (CURDIR), если я использую относительные пути) –

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