2016-06-12 4 views
1

Ich habe ein Makefile, das viele Ziele hat und das Rezept für jedes Ziel ist ziemlich ähnlich.Wie vermeidet man Doppelarbeit in Makefile-Zielen mit ähnlichen Rezepten?

foo: 
    gcc foo.c -o foo 
    mv foo ~/bin 

bar: 
    gcc bar.c -o bar 
    mv bar ~/bin 

baz: 
    gcc baz.c -o baz 
    mv baz ~/bin 

Ich möchte all diese Duplizierung vermeiden. Ich möchte etwas wie unten haben (das ist keine gültige Syntax; dies drückt nur meine Absicht aus).

TARGET_NAME: 
    gcc $(TARGET_NAME).c -o $(TARGET_NAME) 
    mv $(TARGET_NAME) ~/bin 

Ist es möglich, so etwas zu tun? Wenn nicht, was ist das beste Makefile, das ich schreiben kann, um Doppelungen in Rezepten zu minimieren?

+0

Wie bereits an anderer Stelle von @beta erwähnt, ist Ihr 'Makefile' defekt, weil Sie die Dateien, die Sie erstellen, verschieben, so dass sie jedes Mal neu erstellt werden, unabhängig davon, ob es notwendig ist. Außerdem kann die Option "-o" für "gcc" ein Unterverzeichnis übernehmen. 'bin /%:% .c; gcc $ <-o $ @ ' – tripleee

Antwort

4

Ihre Make-Datei ist falsch, weil Sie Ihre Ziele (foo, bar, etc.) nicht auf ihren Quelldateien ab (foo hängt nicht von foo.c, etc.) Also, den Quellcode ändern, werden die nicht dazu führen, Ziel, das neu aufgebaut werden soll.

Auch Ihr Makefile sagt, Sie erstellen eine Datei foo, aber Ihr Rezept erstellt tatsächlich eine Datei ~/bin/foo, die nicht das gleiche ist.

Wie auch immer, dies ist genau das, was pattern rules sind für:

EXES = foo bar baz 

all: $(addprefix $(HOME)/bin/,$(EXES)) 

$(HOME)/bin/%:: %.c 
     gcc $< -o [email protected] 

(Dank Beta für mein Think-o in den ursprünglichen Hinweis auf)

+2

Verstößt du nicht gegen eine deiner [eigenen Regeln] (http://make.mad-scientist.net/papers/rules-of-makefiles/)? Nummer 2 von 6, um genau zu sein: Das Zielmuster sollte mit dem tatsächlichen Namen des Dinges übereinstimmen, das gebaut wird ('~/bin /%'). – Beta

+0

Sie sollten [Regeln für statische Muster] (https://www.gnu.org/software/make/manual/html_node/Static-Usage.html) verwenden, um die Verwendung von [impliziten Regeln] zu vermeiden (https: //www.gnu. org/software/make/manual/html_node/Statisch-versus-Implizit.html). Etwas wie das: 'foo bar baz:%:% .c' – jml

+0

Sie haben Recht. Ich dachte, es wäre ein 'cp', kein' mv'. Ich werde aktualisieren. In Bezug auf "statische Musterregeln": Ich sehe diesen Ratschlag die ganze Zeit, dass Sie sie "benutzen" sollten. Ich benutze sie praktisch nie. Tatsächlich verwende ich immer normale Musterregeln und NUR statische Musterregeln, wenn ich eine Teilmenge von Zielen habe, die auf eine andere Art und Weise gebaut werden sollten. Ich denke, es ist ein Stil/Meinung Sache; Ich würde den Leuten nicht sagen, dass sie sie "ohne Grund" benutzen sollten. – MadScientist

2

A make Regel kann mehrere Ziele tatsächlich entspricht:

foo bar baz: 
    gcc [email protected] -o [email protected] 
    mv [email protected] ~/bin 

Sie sollten jedoch die Abhängigkeiten machen explizit in den Regeln:

Die ersten drei Zeilen geben nur die Abhängigkeiten ohne Aktionen an, um sie tatsächlich zu erstellen. Sie können diese mit Hilfe von gcc generieren: gcc -MM foo.c wird eine Regel für foo.c drucken.

Verwandte Themen