2013-05-01 8 views
1

Это мой Makefile:Makefile: править с тем же именем, подкаталог игнорировал

all: first second 

second: 
    @echo "==Building second==" 

first: 
    @echo "==Building first==" 

Если есть каталог с именем second, правило с таким же именем будет полностью игнорироваться Makefile. Если этого не происходит, все идет нормально.

Обратите внимание, что это происходит независимо от того, находится ли в нем файл second в качестве файла Makefile.

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

Решение тривиально: измените имя правила внутри Makefile ... но это поведение кажется довольно странным: есть ли у вас какие-либо идеи/идеи по этому вопросу и какое другое возможное решение?

Я использую GNU Make 3.81, внутри Bash 4.2.25, под Ubuntu 12.04.2 LTS.

+0

Вы хотите, чтобы правило 'second' вызывало' second/Makefile' из 'second /', это правильно? – Beta

ответ

3

Если вы просто ищете причину, по которой правило не выполняется, это просто: make пытается построить цели. Цели представлены (по умолчанию) наличием артефактов в файловой системе. Не имеет значения, является ли артефакт файлом или каталогом (или, теоретически, что-либо еще).

Для того, чтобы сделать просмотр устаревшего файла и необходимость обновления (и, следовательно, для make для запуска рецепта, связанного с целью), должно быть истинно хотя бы одно из двух: либо target (т. е. файл или каталог) не может существовать или, если он существует, его последнее измененное время должно быть старше, по крайней мере, одного из его предварительных условий.

В вашей ситуации у вас есть second, который существует, поэтому первое требование для перестройки - это не я, и у которого нет предпосылок, поэтому второе требование не выполняется ... и поэтому цель не считается отсутствующей даты и рецепт не вызывается.

Как подсказывает bobbogo, вы можете сказать, что цель всегда должна быть перестроена, независимо от чего-либо еще, объявив цель равной .PHONY. Make поймет, что цель не представляет собой артефакт в файловой системе и вместо этого является лишь поддельной целью в make-файле, используемом для организации сборки.

1

Кажется, что вы хотите, чтобы всегда выполнялось правило second, независимо от того, существует ли файл (или каталог) «второй». Вы можете сделать вторую подобную символическую цель, объявив ее в качестве предпосылки .PHONY.

.PHONY: all 
all: first second 

.PHONY: second 
second: 
    @echo "==Building second==" 
... 
0

Если я правильно понимаю вашу постановку проблемы, вы не вызываете echo, а скорее $(MAKE) -Csecond. Самое время прочитать Миллер Recursive Make Considered Harmful! Хотя это не совсем неотъемлемые проблемы традиционных марок, было бы трудно и неуклюже сделать это лучше с ними.

По этой причине makepp был создан. У вас могут быть одинаковые make-файлы, но вам не нужно указывать рекурсию. Если ваши целевые каталоги имеют make-файлы, они обычно автоматически загружаются в один и тот же процесс. Или, если ваши цели будут выпущены в другой каталог, вы должны сообщить makepp, какие make-файлы нужно загрузить. В любом случае один процесс имеет обзор всех зависимостей (автоматически обнаруженных!).

Существует много больше, чтобы makepp. Помимо выполнения почти всего, что может сделать GNU, есть много более полезных вещей, и вы даже можете расширить свои make-файлы с помощью некоторых программ Perl.

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