Frage

Ich verwende Code ähnlich der folgenden in einem Makefile:

empty:=
space:= $(empty) $(empty)
path_escape = $(subst $(space),\$(space),$(1))

TOP=$(call path_escape,$(abspath .))
TARGET=$(TOP)/foo

$(info TOP='$(TOP)')
$(info TARGET='$(TARGET)')

all: $(TARGET)

$(TARGET):
    touch '$(notdir $@)'

.PHONY: $(TARGET)

Wenn ich das in einem Verzeichnis ohne Leerzeichen verwenden, sagen wir space-test, es funktioniert gut:

$ make
TOP='/tmp/space-test'
TARGET='/tmp/space-test/foo'
touch 'foo'

Allerdings, wenn ich es in einem Verzeichnis mit Leerzeichen verwenden, sagt space test, dann $(notdir) tut das Falsche:

TOP='/tmp/space\ test'
TARGET='/tmp/space\ test/foo'
touch 'space foo'

Was passiert hier ist, dass $(notdir) interpretiert /tmp/space test/foo als zwei Pfade und gibt den "Datei Teil" beide (das heißt, space und foo). Der seltsame Teil davon ist, dass TARGET richtig übersetzt wird; irgendwie, in der Regel oder innen $(notdir), die Backslash entkommt ignoriert werden.

Was mache ich hier falsch?

War es hilfreich?

Lösung

Die $(notdir) Funktion in GNU Make nimmt eine Liste von Argumenten, die durch Leerzeichen getrennt. Einige Funktionen unterstützen zu entkommen Räume mit \\, aber $(notdir) ist nicht einer von ihnen.

Dies sollte funktionieren:

s? = $(subst $(empty) ,?,$1)
?s = $(subst ?, ,$1)
notdirx = $(call ?s,$(notdir $(call s?,$1)))

$(TARGET):
    touch '$(call notdirx,$@)'

Dies definiert eine "Raum-safe" Version von notdir genannt notdirx. Es ist ganz einfach: s? dreht sich zunächst alle Räume Fragezeichen (in der Hoffnung, dass sie nicht in Dateinamen vorhanden sein können) und ?s Konvertiten zurück. Dazwischen können wir die ursprüngliche notdir Funktion sicher nennen.

Für eine ausgezeichnete Zusammenfassung auf GNU Make und Leerzeichen in Dateinamen finden Sie unter trifft GNU Make Dateinamen mit Leerzeichen in ihnen .

Andere Tipps

Angenommen, Sie eine Unix-Shell haben, könnten Sie berappen:

notdirx = $(shell basename '$1')
dirx = $(shell dirname '$1')

Eine ähnliche Strategie auf andere Funktionen anwenden könnte. Denken Sie daran, die Anführungszeichen um die Variable, die den Leerzeichen-infizierten Text enthält, dass Sie zu behandeln, als ein einziges Argument wollen. Dies wird Ihnen auch von anderen Sonderzeichen schützen (außer Anführungszeichen!). Hier ist ein Beispiel der doppelten Backslash alle Leerzeichen in dem Ergebnis einer Wildcard glob:

$(shell ls -1 '*.foo' | sed 's/ /\\\\ /g')

Windows Klammern in Verzeichnisnamen setzen jetzt auch: C:\Program Files (x86)\ Es ist mir noch nicht klar, was die Auswirkungen dieser, wenn make mit

.

Dies ist nur ein Schuss im Dunkeln:

TOP='"/home/chris/src/tests/make/space test"'
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top