Pregunta

Estoy usando un código similar al siguiente en un 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)

Si utilizo esto en un directorio sin espacios, por ejemplo space-test, que funciona bien:

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

Sin embargo, si lo uso en un directorio con espacios, por ejemplo space test, entonces $(notdir) hace las cosas mal:

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

Lo que sucede aquí es que $(notdir) interpreta /tmp/space test/foo como dos caminos y devuelve la "parte de archivos" de ambos (es decir, space y foo). Lo extraño de esto es que se escapó TARGET adecuadamente; De alguna manera, dentro de la norma o $(notdir) el interior, están siendo ignorados los escapes de barra invertida.

¿Qué estoy haciendo mal aquí?

¿Fue útil?

Solución

La función $(notdir) en GNU Make toma una lista de argumentos, separados por espacios. Algunas funciones son compatibles con los espacios que escapan \\, pero $(notdir) no es uno de ellos.

Esto debería funcionar:

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

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

Esto define una versión "-espacio seguro" de notdir llamado notdirx. Es muy sencillo: primero s? convierte todos los espacios en signos de interrogación (esperando que no pueden estar presentes en los nombres de archivo), y ?s convierte de nuevo. Entre podemos llamar de forma segura la función notdir originales.

Para un excelente resumen en GNU Marca y espacios en los nombres de archivos, consulte GNU Make cumple con los nombres de archivo con espacios en ellos .

Otros consejos

Asumiendo que tiene un shell de Unix, usted podría pagar:

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

Una estrategia similar podría aplicarse a otras funciones. Sólo recuerde las comillas alrededor de la variable que contiene el texto de espacio en blanco infectados que se quiere tratar como un solo argumento. Esto también le protegerá de otros caracteres especiales (con excepción de las comillas!). Aquí hay un ejemplo de doble barra invertida escapar ningún espacio en el resultado de un glob comodín:

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

Windows está poniendo entre paréntesis en los nombres de directorio ahora, también:. C:\Program Files (x86)\ Todavía no está claro para mí lo son las implicaciones de esto cuando se utiliza make

Esto es sólo un tiro en la oscuridad:

TOP='"/home/chris/src/tests/make/space test"'
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top