¿Puedes crear Makefiles válidos sin caracteres de tabulación?


114
target: dependencies
    command1
    command2

En mi sistema (Mac OS X), makeparece requerir que Makefiles tenga un carácter de tabulación antes del contenido de cada commandlínea, o arroja un error de sintaxis.

Esto es una molestia al crear o editar Makefiles porque tengo mi editor configurado para ser todo-espacios-todo-el-tiempo.

¿Puedes crear Makefiles válidos sin caracteres de tabulación?


4
También configuré mi editor para emular pestañas con espacios. Pero, mi editor también me permite escribir Ctrl-Tab en las raras ocasiones en las que definitivamente debo tener una pestaña, como en Makefiles. Quizás su editor también lo haga.
toolic

Respuestas:


118

Esta es una rareza / requisito de sintaxis de make, no tiene nada que ver con Mac OS X. Desafortunadamente, no hay nada que pueda hacer al respecto si lo va a usar make.

Editar : GNU Make ahora admite un prefijo de receta personalizado. Vea esta respuesta .

No eres el primero al que no le gusta este aspecto make. Para citar el manual de los enemigos de Unix :

El problema con el Makefile de Dennis es que cuando agregó la línea de comentario, sin darse cuenta insertó un espacio antes del carácter de tabulación al principio de la línea 2. El carácter de tabulación es una parte muy importante de la sintaxis de Makefiles. Todas las líneas de comando (las líneas que comienzan con cc en nuestro ejemplo) deben comenzar con tabulaciones. Después de que hizo su cambio, la línea 2 no lo hizo, de ahí el error.

"¿Y qué?" preguntas, "¿Qué hay de malo en eso?"

No hay nada de malo en ello, por sí solo. Es solo que cuando se considera cómo funcionan otras herramientas de programación en Unix, usar pestañas como parte de la sintaxis es como una de esas trampas de pungee stick en The Green Berets: el pobre chico de Kansas está caminando frente a John Wayne y no lo hace. t veo el cable de disparo. Después de todo, en los campos de maíz de Kansas no hay que tener cuidado con los cables trampa. ¡WHAM!


5
El problema con las pestañas es una de las primeras cosas que aprenden las personas que usan make: nunca me pareció un problema real.

2
@Neil, yo tampoco: nunca dije que estaba de acuerdo con la UHH, solo estaba diciendo que a algunas personas no les gusta. :-)
Alok Singhal

2
Parece un buen complemento para usar cmake. No es la única rareza frustrante en la sintaxis de make.
orodbhen

3
Acabo de encontrar gnu.org/software/make/manual/html_node/Special-Variables.html (ver .RECIPEPREFIX). Una de las respuestas a continuación también menciona eso, y debe marcarse como "correcta" en lugar de como mía. stackoverflow.com/a/21920142
Alok Singhal

3
No es un gran problema, pero es molesto. Todas y cada una de las veces. Es verdaderamente molesto y molesto en el tiempo lineal \ omicron.
Disparo parto

60

En el tiempo transcurrido desde que se hizo esta pregunta originalmente, se ha lanzado una versión de GNU Make que le permite usar algo más que Tabcomo carácter de prefijo. Desde el anuncio de la lista de correo :

Nueva variable especial: .RECIPEPREFIX le permite restablecer el carácter de introducción de la receta del predeterminado (TAB) a otra cosa. El primer carácter de este valor de variable es el carácter de introducción de nueva receta. Si la variable se establece en la cadena vacía, se usa TAB nuevamente. Se puede configurar y reiniciar a voluntad; las recetas utilizarán el valor activo cuando se analizaron por primera vez. Para detectar esta característica, verifique el valor de $ (. RECIPEPREFIX).

Esta característica se agregó en GNU Make 3.82, lanzado en julio de 2010 (seis meses después de la fecha de solicitud original de esta pregunta). Dado que a su vez han pasado tres años y han cambiado desde eso, es probable que otras versiones de Make hayan seguido a GNU Make.


51

Hay una forma complicada de tener un archivo MAKE válido sin pestañas.

Si cambia su archivo MAKE para que lea:

target: dependencies; command1; command2

Si funcionará. Si lo desea en más de una línea, puede hacer lo siguiente:

target: dependencies; \
command1; \
command2

Desordenado, pero funciona.


La actualización a una versión de Make compatible .RECIPEPREFIXes probablemente el mejor enfoque. Sin embargo, como no tenía ganas de hacer eso, terminé usando una solución basada en esta. Línea 1:, target:\ Línea 2: [sangría de cuatro espacios] seguida de;command
LS

33

Si tiene un vimrc en su perfil, puede agregar esta línea para evitar que vim cambie a espacios:

autocmd FileType make setlocal noexpandtab

Yo también estaba luchando con esto, y esto me solucionó. ¡Difunde la buena palabra!


19

Esto lo hace por mí si desea usar espacios.

.RECIPEPREFIX +=

Ejemplo


¿Qué versión de make admite esto? Esto no funciona en GNU Make 4.1.
Cerin

2
GNU Make 4.1 Creado para x86_64-pc-linux-gnu lo siento, pero funciona
neok

probablemente, debe mencionarse, que esta variable debe declararse dentro del archivo make (prefijar el punto es fácil de no detectar)
urusai_na

Al menos en la versión 4.2, esto debería funcionar. La documentación dice en la explicación de .RECIPEPREFIXque "Si la variable está vacía (como está por defecto ) ese carácter es el carácter de tabulación estándar". Esto significa que la variable está definida por defecto. Se confirma usando ifeq ($(origin .RECIPEPREFIX), undefined). Debido a que +=agrega un solo espacio y el rhs al lhs, se var +=establece varen un solo espacio (más una cadena vacía) siempre que varya se haya definido. (Si varno está definido, +=es lo mismo que =.)
ynn

1
Esta respuesta ya no funciona. Vea mi respuesta para conocer la última solución.
ynn

11

En el modo de inserción de vim, se puede usar Ctrl-v <TAB>para insertar una pestaña literal, incluso si ha configurado la tecla de tabulación para insertar espacios. Esto no responde a su pregunta, por supuesto, pero podría ser una alternativa a los métodos disponibles para evitar la necesidad de pestañas literales.


10

Si está usando EditorConfig , puede agregar las siguientes líneas a su .editorconfigarchivo para forzar a su IDE a usar tabulación para sangría en lugar de espacios en Makefile:

[Makefile]
indent_style = tab

4

Hasta GNU Make 4.2

La respuesta de Steven Penny funciona.

.RECIPEPREFIX +=

La razón por la que esto funciona se describe en mi comentario .


Desde GNU Make 4.3 (lanzado el 19 de enero de 2020)

El comportamiento del +=operador se ha modificado de forma incompatible con versiones anteriores. Si el operando de la izquierda tiene un valor vacío, ya no se agrega un espacio .

En su lugar, puede utilizar

.RECIPEPREFIX := $(.RECIPEPREFIX)<space>

, donde <space>hay un solo espacio. Aunque $(.RECIPEPREFIX)se expande como un valor vacío, es necesario para que GNU Make no lo ignore <space>. Tenga en cuenta que este código funciona incluso en GNU Make anterior a la versión 4.3.


1

en ubuntu: vi Makefiles reemplaza el espacio por pestaña (o cualquier otra cosa que desee):

:%s/<space chars>/^I/g

Por ejemplo, reemplace 8 espacios por tabulación:

:%s/        /^I/g

Atención: ^ Inserto con la tecla de tabulación, no ^ e I caracteres: D


-6

No portátil. Ciertos tipos de marca requieren absolutamente caracteres de tabulación. Otra razón más para preferir las pestañas a los espacios :-)

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.