Переопределить цель в make-файле, чтобы добавить больше команд? - PullRequest
37 голосов
/ 29 октября 2009

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

Я знаю, что могу просто сделать новую цель с новым именем и сделать так, чтобы она называлась чистой, а затем делать другие вещи, но для последовательности я хотел бы иметь возможность просто вызвать команду make clean и сделать все .

Это возможно?

Ответы [ 6 ]

61 голосов
/ 29 октября 2009

Я видел это в нескольких магазинах. Наиболее распространенным подходом является использование правил с двойным двоеточием, при условии, что вы используете что-то вроде GNU make. В вашем обычном make-файле у вас будет что-то вроде этого:

clean::
        # standard cleanup, like remove all .o's:
        rm -f *.o

Обратите внимание, что за clean следуют два двоеточия, а не только один!

В другом вашем make-файле вы просто объявляете clean снова как правило с двумя двоеточиями:

clean::
        # custom cleanup, like remove my special generated files:
        rm -f *.h.gen

Когда вы вызываете make clean, GNU make автоматически запускает обе эти «ветви» чистого правила:

% make clean
rm -f *.o
rm -f *.h.gen

Его легко настроить, и я думаю, что он достаточно аккуратный. Обратите внимание, что именно из-за того, что это правило с двойным двоеточием, вы не получите ошибок «переопределения команд», которые обычно возникают при определении двух правил для одной и той же цели. В этом и заключается смысл правил двойного двоеточия.

31 голосов
/ 29 октября 2009

Вы можете написать свою собственную чистку и сделать ее обязательным условием обычной чистки.

clean: myclean

myclean:
    rm whatever

Ваш будет работать первым. Если по какой-то причине вы хотите, чтобы общая очистка выполнялась первой, решение будет более сложным.

5 голосов
/ 29 октября 2009

Кажется, что правило общего make-файла должно называться как common-clean. Тогда каждый основной make-файл объявляет их чистое правило как

clean: common-clean

и все готово.

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

4 голосов
/ 16 мая 2014

Используйте неявные правила:

existing-target: my-extention

my-extention:
    echo running command 1
    echo running command 2

Очень простое учебное пособие для наращивания.

При использовании :: вы можете столкнуться с проблемами, поскольку make жалуется при смешивании одного двоеточия : и двойного двоеточия :: rules:

a:
    echo a

a::
    echo aa

приведет к:

. . .
*** target file `a' has both : and :: entries.  Stop.
1 голос
/ 20 марта 2017

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

локальный make-файл 1:

CLEAN=MyExe1 MyExe2
....
include /my/common/makefile

локальный makefile 2:

CLEAN=MyExe3 MyExe4
....
include /my/common/makefile

общий make-файл:

clean:
     rm -f *.dep *.o *.a $(CLEAN)

По сути, идея состоит в том, чтобы определить некоторую переменную (в данном случае CLEAN) в каждом локальном make-файле со всеми конкретными элементами, которые вы хотите удалить. Затем общий make-файл запускает rm -f для всех общих типов файлов, которые нужно удалить, плюс все, что было специально помечено для удаления в каждом локальном make-файле через переменную CLEAN. Если ничего не нужно удалять, просто опустите объявление переменной или оставьте его пустым (CLEAN=)

Так что теперь, если мы запускаем make clean для локального make-файла 1, он выполняет

rm -f *.dep *.o *.a MyExe1 MyExe2

И если мы запустим make clean для локального make-файла 2, он выполнит

rm -f *.dep *.o *.a MyExe3 MyExe4
1 голос
/ 09 августа 2013

Для нас мы определяем переменную EXTRAFILESTOCLEAN, затем, когда запускается правило очистки, у него есть шаг для удаления всего, что указано в переменной EXTRAFILESTOCLEAN

clean:
    rm -f *.o
ifdef $(EXTRAFILESTOCLEAN)
    rm -f $(EXTRAFILESTOCLEAN)
endif

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...