Nadpisać cel w makefile, aby dodać więcej poleceń?

W pracy używamy wspólnego pliku makefile, który zawierają inne pliki Makefile (poprzez polecenie include) i ma ogólny "czysty" cel, który zabija niektóre popularne pliki. Chcę dodać do tego celu w moim nowym pliku makefile, aby móc usunąć niektóre konkretne pliki, ale jeśli dodam czysty cel w moim pliku makefile, to po prostu nadpisuje Stary.

Wiem, że mogę po prostu zrobić nowy cel z nową nazwą i mieć go czysty, a potem robić inne rzeczy, ale ze względu na spójność chciałbym móc po prostu zadzwoń do Clean i niech zrobi wszystko.

Czy to możliwe?

 32
Author: Paul D., 2009-10-29

6 answers

Możesz napisać własne czyste i zrobić z niego preq zwykłego czystego.

clean: myclean

myclean:
    rm whatever
Twój będzie pierwszy. Jeśli z jakiegoś powodu chcesz, aby wspólne czyszczenie działało najpierw, rozwiązanie będzie bardziej skomplikowane.
 28
Author: Beta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-29 16:52:07

Widziałem to w kilku sklepach. Najczęstszym podejściem jest używanie reguł dwukropka, zakładając, że używasz czegoś takiego jak GNU make. W Twoim wspólnym makefile mielibyście coś takiego:

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

Zauważ, że istnieją dwa dwukropki po clean, a nie tylko jeden!

W twoim drugim pliku makefile po prostu deklarujesz clean ponownie, jako zasadę dwukropka:

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

Kiedy wywołasz make clean, GNU make automatycznie uruchomi obie te "gałęzie" czysta reguła:

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

Jest prosty w konfiguracji I wydaje mi się, że komponuje się całkiem zgrabnie. Zauważ, że ponieważ jest to reguła dwukropka, nie występują błędy "nadrzędnych poleceń", które zwykle występują, gdy zdefiniujesz dwie reguły dla tego samego celu. O to chodzi w zasadach dwukropka.

 55
Author: Eric Melski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-23 21:49:40

Wydaje się, że wspólna zasada makefile powinna być nazywana czymś w rodzaju common-clean. Następnie każdy główny plik makefile zadeklaruje swoją czystą regułę jako

clean: common-clean
I gotowe.

Jeśli to nie jest opcja, możesz rzucić okiem na Zasady dwukropka , ale te wprowadzają zupełnie inny zestaw problemów do rozważenia.

 5
Author: jamessan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-29 16:36:12

Użyj reguł ukrytych:

existing-target: my-extention

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

Bardzo prosty samouczek tworzenia, aby przyspieszyć.

Podczas stosowania :: możesz napotkać problemy, ponieważ skarży się, gdy wymieszasz pojedynczy dwukropek : i dwukropek podwójny :: reguły:

a:
    echo a

a::
    echo aa

Spowoduje:

. . .
*** target file `a' has both : and :: entries.  Stop.
 4
Author: Bohdan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-15 23:58:30

Dla naszej, definiujemy zmienną EXTRAFILESTOCLEAN, wtedy gdy działa reguła clean, ma ona krok, aby usunąć cokolwiek określonego w zmiennej EXTRAFILESTOCLEAN

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

Może to powodować nieoczekiwane problemy, jeśli ustawisz tę zmienną na dziwne wartości, ale możesz się przed nimi uchronić, dodając prefiksy lub inne testy.

 1
Author: davenpcj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-09 01:27:12

Dodanie innego możliwego rozwiązania, które widziałem dla potomności... Wiem, że OP był ostrożny w zmianie wspólnego makefile, ale coś takiego działa i wymaga minimalnych zmian.

Local makefile 1:

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

Local makefile 2:

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

Common makefile:

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

Zasadniczo chodzi o zdefiniowanie jakiejś zmiennej (w tym przypadku CLEAN) w każdym lokalnym pliku makefile ze wszystkimi konkretnymi elementami, które chcesz usunąć. Następnie common makefile działa rm -f na wszystkich typowe typy plików do usunięcia, plus to, co zostało specjalnie oznaczone do usunięcia w każdym lokalnym pliku makefile za pomocą zmiennej CLEAN. Jeśli nie ma nic konkretnego do usunięcia, po prostu pomiń deklarację zmiennej lub zostaw ją pustą (CLEAN=)

Więc teraz, jeśli uruchomimy make clean dla lokalnego makefile 1, to wykona

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

I jeśli uruchomimy make clean dla lokalnego makefile 2, to wykona

rm -f *.dep *.o *.a MyExe3 MyExe4
 1
Author: yano,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-20 18:26:50