2016-09-29 1 views
1

Ich habe ein sehr bizzare Problem mit GNU make. Ich habe die folgenden Dateien:Makefile wendet eine Regel rekursiv an, auch wenn es nicht

a/x.html 
b/Makefile 
b/c/Makefile 

Der Inhalt a/x.html irrelevant sind. Der Inhalt b/Makefile sind wie folgt:

SRC=../a 
all: x.html 

%.html: ${SRC}/%.html 
     rsync $< [email protected] 

Der Inhalt b/c/Makefile sind die gleichen, mit Ausnahme der Definition von SRC:

SRC=../../a 

Wenn ich make in b/c/ das Ergebnis ausgeführt wird, wie erwartet:

rsync ../../a/x.html x.html 

und x.html wird vonkopiertbis b/c/.

Wenn ich jedoch make in b/ laufen die Ausgabe ich erhalte, ist mehrere Zeilen:

make: stat: ../a/../a/.. (repeated many times) ../a/x.html: File name too long 

Es scheint, dass make wird die Regel für %.html rekursiv anwenden, aber warum? Gibt es etwas Offensichtliches, das mir fehlt?

Antwort

1

ein Ziel zu erstellen, die das Muster entspricht %.html (das heißt jeden Zielnamen, der in .html endet), machen gilt die Regel, wenn es um die Abhängigkeit zu bauen (von dem ursprünglichen Ziel gebaut Ziel mit ../a/ vorangestellten).

  1. Sie fragen, x.html zu bauen. Dies entspricht dem Muster %.html, so dass die Regel gilt: make sieht, ob ../a/x.html erstellt werden kann.
  2. ../a/x.html entspricht dem Muster %.html, so gilt die Regel: make sieht, ob es ../a/../a/x.html bauen kann.
  3. ../../a/x.html entspricht dem Muster %.html, so gilt die Regel, usw.

Der Stamm Charakter einen beliebigen Teil eines Pfades passen kann, einschließlich Verzeichnistrenn.

können Sie sehen, was durch Ausführen make -r -d machen versucht (-d Debugging-Ausgabe zu zeigen, -r integrierte Regeln auszuschalten, die eine große Menge an Lärm verursachen würden).

Wenn Sie in b/c sind, stoppt dies bei Schritt 2, weil ../../a/x.html existiert, aber ../../../../a/x.html nicht.

Eine Möglichkeit, dies zu beheben, besteht darin, die Dateien aufzulisten, auf die Sie reagieren möchten. Sie können diese Liste aus der Liste der Dateien erstellen, die bereits in ../a existieren:

$(notdir $(wildcard ${SRC}/*.html)): %.html: ${SRC}/%.html 
     rsync $< [email protected] 

Dies hat den Nachteil, dass, wenn die HTML-Dateien in ../a sich in b/Makefile durch eine Regel gebaut sind, dann make in b gewonnen laufen‘ Ich habe sie in einem ursprünglichen Quellverzeichnis erstellt.Dies sollte jedoch kein Problem sein: Es wäre ungewöhnlich, ein Makefile in b bauen Dinge außerhalb b zu haben.

Ein anderer Ansatz, der diesen Fehler nicht aufweist, ist die Verwendung eines absoluten Pfades.

%.html: $(abspath ${SRC})/%.html 
     rsync $< [email protected] 
+0

Vielen Dank! Ich denke, ich werde die Abspath-Lösung verwenden. –

Verwandte Themen