10 Stimmen

Wenn eine Bedingung innerhalb eines Ziels in einer Makefile ist

Ich möchte etwas Ähnliches tun, wo ich einen svn commit ausführen möchte, wenn eine Datei geändert wurde. Die Datei hat einen Zeitstempel, der sich immer ändert. Also, wenn sich irgendetwas mehr als der Zeitstempel ändert, möchte ich die Datei committen.

Das Makefile wird etwas Ähnliches wie folgt haben. Aber die If-Bedingung funktioniert nicht richtig. Sie wird ausgeführt, auch wenn sie nicht erfüllt ist. Kann mir jemand sagen, was das Problem in diesem If ist?

    UPDATE_STATE_FILE :
        $(eval NO_LINES_CHANGES_IN_STATE = $(shell svn di STATE/build.state --diff-cmd=diff -x --normal | grep "^[<>]" | wc -l))
        @echo $(NO_LINES_CHANGES_IN_STATE)
    ifneq ($(strip $(NO_LINES_CHANGES_IN_STATE)), 2)
    ifneq ($(strip $(NO_LINES_CHANGES_IN_STATE)), 0)
        @echo $(NO_LINES_CHANGES_IN_STATE)
        $(SVN) commit;
        $(SVN) update;
    endif
    endif

18voto

MadScientist Punkte 80685

Sie können keine bedingten Anweisungen innerhalb von Befehlsregeln mischen. Bedingte Anweisungen sind wie Präprozessor-Anweisungen in C oder C++; sie werden beim Einlesen der Datei behandelt, bevor irgendwelche Verarbeitungen (wie das Ausführen von Regeln) durchgeführt werden.

Wenn Sie bedingte Anweisungen innerhalb der Regeln haben möchten, müssen Sie die Regel mit Shell-bedingten Anweisungen schreiben, nicht mit make-bedingten Anweisungen:

UPDATE_STATE_FILE :
        @NO_LINES_CHANGES_IN_STATE=`svn di STATE/build.state --diff-cmd=diff -x --normal | grep "^[<>]" | wc -l`; \
        echo $$NO_LINES_CHANGES_IN_STATE; \
        if [ $$NO_LINES_CHANGES_IN_STATE -ne 2 ] && [ $$NO_LINES_CHANGES_IN_STATE -ne 0 ]; then \
            echo $$NO_LINES_CHANGES_IN_STATE; \
            $(SVN) commit; \
            $(SVN) update; \
        fi

3voto

Myst Punkte 17326

Nachdem ich die Antwort von @MadScientist gelesen hatte, kam ich auf einen anderen Ansatz.

Da ich nicht wusste, ob Shell-Bedingungen in jeder Umgebung funktionieren (Windows vs. Linux), habe ich die Regeln stattdessen innerhalb der Bedingung eingeschlossen, anstatt eine Bedingung innerhalb der Regel zu haben. z.B.

ifdef MY_FLAG
%.o: %.c
    $(CC) -o $@ -c $^ $(CFLAGS)

else
%.o: %.c
    @$(CC) -o $@ -c $^ $(CFLAGS)

endif

Vielen Glück für alle, die hier vorbeischauen.

BEARBEITEN

Wie James Moore in den Kommentaren hervorgehoben hat, erfordert dieser andere Ansatz Sorgfalt und Hinweise darauf, wann und wie Variablen in Bezug auf die Platzierung des if-Statements im Kontrollfluss definiert werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X