¿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?

xyz
fuente
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!

Alok Singhal
fuente
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.

Brighid McDonnell
fuente
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.

Jorge
fuente
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!

Pericolo
fuente
19

Esto lo hace por mí si desea usar espacios.

.RECIPEPREFIX +=

Ejemplo

Steven Penny
fuente
¿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.

Patrick Sanan
fuente
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
iver56
fuente
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.

ynn
fuente
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

nobjta_9x_tq
fuente
-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 :-)


fuente