Frage

Ich habe ein Makefile, das nennt baut und dann eine andere Make-Datei. Da diese Make-Datei ruft mehr Makefiles, dass die Arbeit ist es wirklich ändern tut. So halten sie denken das Projekt gebaut und bis zu Datum.

dnetdev11 ~ # make
make: `release' is up to date.

Wie erzwinge ich die Make-Datei das Ziel neu zu erstellen?

clean = $(MAKE) -f ~/xxx/xxx_compile.workspace.mak clean


build = svn up ~/xxx                                                       \
        $(clean)                                                                \
        ~/cbp2mak/cbp2mak -C ~/xxx ~/xxx/xxx_compile.workspace        \
        $(MAKE) -f ~/xxx/xxx_compile.workspace.mak $(1)                    \


release:
        $(build )

debug:
        $(build DEBUG=1)

clean:
        $(clean)

install:
        cp ~/xxx/source/xxx_utility/release/xxx_util /usr/local/bin
        cp ~/xxx/source/xxx_utility/release/xxxcore.so /usr/local/lib

Hinweis: Die Namen entfernen, um die Unschuldigen zu schützen

Edit: Endgültige Fest Version:

clean = $(MAKE) -f xxx_compile.workspace.mak clean;


build = svn up;                                         \
        $(clean)                                        \
        ./cbp2mak/cbp2mak -C . xxx_compile.workspace;   \
        $(MAKE) -f xxx_compile.workspace.mak    $(1);   \


.PHONY: release debug clean install

release:
        $(call build,)

debug:
        $(call build,DEBUG=1)

clean:
        $(clean)

install:
        cp ./source/xxx_utillity/release/xxx_util /usr/bin
        cp ./dlls/Release/xxxcore.so /usr/lib
War es hilfreich?

Lösung

Sie können ein oder mehrere Ihrer Ziele erklären sein unecht .

  

Ein Pseudoziel ist eine, die nicht wirklich der Name einer Datei ist; sondern es   ist nur ein Name für ein Rezept ausgeführt wird, wenn Sie eine explizite machen   Anfrage. Es gibt zwei Gründe, ein falsches Ziel zu nutzen: zu vermeiden, eine   Konflikt mit einer Datei mit dem gleichen Namen, und die Leistung zu verbessern.

     

...

     

Ein Pseudoziel sollte keine Voraussetzung einer echten Zieldatei sein; wenn   es ist, wird das Rezept jedes Mal make zu aktualisieren geht ausgeführt werden, um die   Datei. Solange ein Pseudoziel nie eine Voraussetzung eines real   Ziel, das falsche Ziel Rezept wird nur dann ausgeführt werden, wenn die falsche   Ziel ist ein angegebenes Ziel

Andere Tipps

Der -B Schalter zu machen, dessen lange Form ist --always-make, sagt make Zeitstempel zu ignorieren und die festgelegten Ziele zu machen. Dies kann den Zweck der Verwendung machen besiegen, aber es kann sein, was Sie brauchen.

Ein Trick, der für make in einem Sun-Handbuch dokumentiert verwendet werden soll, ein (nicht vorhanden) Ziel verwenden ‚.FORCE‘. Sie können dies tun, indem Sie eine Datei, force.mk erstellen, das enthält:

.FORCE:
$(FORCE_DEPS): .FORCE

Dann Ihre vorhandene Make-Datei unter der Annahme, heißt makefile, könnten Sie laufen:

make FORCE_DEPS=release -f force.mk -f makefile release

Da .FORCE nicht vorhanden ist, alles, was davon abhängt wird veraltet und neu erstellt werden.

Dies wird mit jeder Version von make Alle arbeiten; unter Linux, haben Sie GNU deshalb Stellen und kann das .PHONY Ziel verwenden, wie diskutiert wird.

Es ist auch eine Überlegung wert, warum make Release hält auf dem neuesten Stand zu sein. Dies könnte sein, weil Sie in unter den ausgeführten Befehlen einen Befehl touch release haben; es könnte sein, weil es eine Datei oder das Verzeichnis ‚Release‘, das existiert genannt ist und keine Abhängigkeiten hat und so ist aktuell. Dann gibt es den eigentlichen Grund ...

Jemand anderes vorgeschlagen .PHONY die definitiv korrekt ist. .PHONY sollte für jede Regel verwendet werden, für die ein Datum Vergleich zwischen dem Eingang und dem Ausgang ungültig ist. Da Sie alle Ziele der Form output: input nicht haben sollten Sie .PHONY für alle von ihnen!

Alles, was gesagt, Sie wahrscheinlich einige Variablen am Anfang Ihrer Make-Datei für die verschiedenen Dateinamen definieren sollen, und definieren wirkliche Regeln machen, die sowohl Eingabe- und Ausgabeabschnitte, so dass Sie die Vorteile der Marke verwenden können, nämlich, dass Sie kompilieren eigentlich nur Dinge, die notwendig sind copmile!

Edit: hinzugefügt Beispiel. Ungeprüfte, aber das ist, wie Sie .PHONY tun

.PHONY: clean    
clean:
    $(clean)

Wenn ich mich richtig erinnere, ‚make‘ verwenden Zeitstempel (Dateiänderungszeit), um zu bestimmen, ob ein Ziel auf dem neuesten Stand ist. Ein üblicher Weg, um eine Re-Build Kraft ist, die Zeitstempel zu aktualisieren, den ‚Touch‘ Befehl. Sie könnten versuchen, ‚berühren‘ in Ihrem Makefile Aufruf den Zeitstempel eines der Ziele zu aktualisieren (vielleicht einer jener Untermakefiles), die diesen Befehl auszuführen machen könnten erzwingen.

Diese einfache Technik wird die Make-Datei normal funktionieren, wenn Zwingen nicht erwünscht ist. Erstellen Sie ein neues Ziel namens Kraft am Ende der Make-Datei . Das Kraft Ziel wird eine Datei berühren, die Ihr Standardziel abhängt. Im Beispiel unten, ich habe hinzugefügt Touch myprogram.cpp . Ich habe auch einen rekursiven Aufruf zu machen . Dies bewirkt, dass das Standardziel jedes Mal, wenn Sie auf geben gemacht werden macht Kraft .

yourProgram: yourProgram.cpp
       g++ -o yourProgram yourProgram.cpp 

force:
       touch yourProgram.cpp
       make

Ich habe versucht und es funktioniert für mich

fügen Sie diese Zeilen Makefile

clean:
    rm *.o output

new: clean
    $(MAKE)     #use variable $(MAKE) instead of make to get recursive make calls

speichern und jetzt rufen

make new 

, und es wird alles neu kompiliert wieder

Was ist passiert?

1) 'neu' nennt sauber. ‚Sauber‘ do ‚rm‘, die alle Objektdateien entfernt, die die Erweiterung von ‚.o‘ haben.

2) 'neue' Anrufe 'make'. ‚Make‘ sehen, dass es keine ‚.o‘ -Dateien, so erstellt es alle ‚.o‘ wieder. dann werden die Linker verbindet alle der .o-Datei eine ausführbare Ausgabe int

Viel Glück

Wie pro Millers rekursive Make schädlich Sie vermeiden sollten $(MAKE) ruft! Im Fall, dass Sie zeigen, es ist harmlos, denn dies ist nicht wirklich eine Make-Datei ist, nur ein Wrapper-Skript, das könnte genauso gut in Shell geschrieben wurde. Aber Sie sagen, Sie mögen, dass bei tieferen Rekursionsebenen fortsetzen, so haben Sie begegnen wahrscheinlich die dargestellten Probleme in diesem eye-opening Essay.

Natürlich mit GNU macht es umständlich ist zu vermeiden. Und obwohl sie sich dieses Problems bewusst sind, ist es ihre dokumentierter Weise, Dinge zu tun.

OTOH, makepp machen wurde für dieses Problem als eine Lösung geschaffen . Sie können Ihre Makefiles auf einem pro Verzeichnisebene schreiben, aber sie alle zusammen in einem vollen Blick auf Ihr Projekt gezogen bekommen.

Aber Vermächtnis Makefiles werden rekursiv geschrieben. So ist es eine Abhilfe, wo $(MAKE) nichts tut, sondern kanalisieren die Unteranfragen zurück zum Haupt makepp Prozess. Nur wenn Sie entlassen oder, schlimmer noch, widersprüchliche Dinge zwischen Ihrem submakes tun, müssen Sie --traditional-recursive-make (was natürlich bricht dieser Vorteil von makepp) anfordern. Ich weiß nicht, Ihre anderen Makefiles, aber wenn sie sauber geschrieben sind, mit makepp notwendigen Modernisierungen sollten automatisch, ohne dass irgendwelche Hacks vorgeschlagen hier von anderen passieren.

Wenn Sie nicht benötigen eine der Ausgaben bewahren Sie bereits erfolgreich kompiliert

nmake /A 

neu erstellt alle

Es hängt tatsächlich auf das, was das Ziel ist. Wenn es ein Pseudoziel ist (das heißt das Ziel nicht in eine Datei verwandt) Sie sollten es als .PHONY erklären.

Wenn jedoch das Ziel kein Pseudoziel ist, aber Sie wollen es einfach aus irgendeinem Grunde neu zu erstellen (ein Beispiel ist, wenn Sie die __TIME__ Vorverarbeitung Makro verwenden), sollten Sie die FORCE Schema hier in Antworten beschrieben verwenden.

Es wurde bereits erwähnt, aber dachte ich mit touch könnte hinzufügen

Wenn Sie alle Quelldateien touch kompiliert werden, ändert sich der touch Befehl die Zeitstempel einer Datei auf die Systemzeit der touch Befehl ausgeführt wurde.

Die Quelldatei timstamp ist, was make verwendet zu „wissen“, eine Datei geändert hat, und muss neu kompiliert werden

Zum Beispiel:. Wenn das Projekt ein c ++ Projekt ist, dann touch *.cpp tun, dann läuft make wieder und machen sollte das gesamte Projekt neu kompiliert

make clean löscht alle bereits kompilierten Objektdateien.

Auf meinem Linux-System (Centos 6.2), gibt es einen signifikanten Unterschied zwischen dem Ziel .PHONY erklärt und eine gefälschte Abhängigkeit von FORCE zu schaffen, wenn die Regel tatsächlich eine Datei mit dem Ziel passenden tut erstellen. Wenn die Datei jedes Mal neu generiert werden muss, benötigt er sowohl die gefälschte Abhängigkeit FORCE auf die Datei, und .PHONY für die gefälschte Abhängigkeit.

falsch:

date > $@

rechts:

FORCE
    date > $@
FORCE:
    .PHONY: FORCE
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top