¿Cómo podría abortar una ejecución de make / makefile basada en una variable de makefile que no se establece / valora?
Se me ocurrió esto, pero funciona solo si la persona que llama no ejecuta explícitamente un objetivo (es decir, make
solo se ejecuta ).
ifeq ($(MY_FLAG),)
abort: ## This MUST be the first target :( ugly
@echo Variable MY_FLAG not set && false
endif
all:
@echo MY_FLAG=$(MY_FLAG)
Creo que algo como esto sería una buena idea, pero no encontré nada en el manual de make:
ifndef MY_FLAG
.ABORT
endif
Respuestas:
TL; DR : Use la
error
función :Tenga en cuenta que las líneas no deben sangrarse. Más precisamente, ninguna pestaña debe preceder a estas líneas.
Solución genérica
En caso de que vaya a probar muchas variables, vale la pena definir una función auxiliar para eso:
Y aquí está cómo usarlo:
Esto generaría un error como este:
Notas:
La verificación real se realiza aquí:
Esto refleja el comportamiento del
ifndef
condicional, de modo que una variable definida a un valor vacío también se considera "indefinida". Pero esto solo es cierto para variables simples y variables recursivas explícitamente vacías:Como lo sugiere @VictorSergienko en los comentarios, puede desearse un comportamiento ligeramente diferente:
Y:
Verificación específica del objetivo
También es posible extender la solución para que se pueda requerir una variable solo si se invoca un determinado objetivo.
$(call check_defined, ...)
desde dentro de la recetaSimplemente mueva el cheque a la receta:
El
@
signo inicial desactiva el comando que hace eco y:
es el comando real, un trozo de shell no operativo .Mostrando el nombre del objetivo
La
check_defined
función se puede mejorar para generar también el nombre de destino (proporcionado a través de la$@
variable):De modo que, ahora una comprobación fallida produce una salida con un formato agradable:
check-defined-MY_FLAG
objetivo especialPersonalmente, usaría la solución simple y directa anterior. Sin embargo, por ejemplo, esta respuesta sugiere usar un objetivo especial para realizar la verificación real. Se podría tratar de generalizar eso y definir el objetivo como una regla de patrón implícito:
Uso:
Observe que
check-defined-BAR
se enumera como el requisito previo de solo pedido (|...
).Pros:
Contras:
make -t
(consulte En lugar de ejecutar recetas ) contaminará su directorio raíz con muchoscheck-defined-...
archivos. Este es un triste inconveniente del hecho de que las reglas de patrón no se pueden declarar.PHONY
.Creo que estas limitaciones pueden superarse usando algunos hacks de expansión
eval
mágicos y secundarios , aunque no estoy seguro de que valga la pena.fuente
make --version
como el primer paso.Use la función de shell
test
:Uso:
fuente
checkforsomething
objetivo que solo tenía el contenidotest
yfoo
dependí de eso, y 2) cambié el cheque a@if test -z "$(something)"; then echo "helpful error here"; exit 1; fi
cambio. Eso me dio la posibilidad de agregar un error útil y me permitió hacer que el nombre del nuevo objetivo sea un poco más indicativo de lo que salió mal también.Makefile:5: *** missing separator. Stop.
test -n "$(something) || (echo "message" ; exit 1)
evitar lo explícitoif
.Puede usar un IF para probar:
Resultado:
fuente
[
es un alias para el comandotest
, por lo que esta es la misma respuesta que @Messa anterior. Sin embargo, esto es más compacto e incluye la generación de mensajes de error.Utilice el manejo de errores de shell para variables no establecidas (tenga en cuenta el doble
$
):Si necesita un mensaje de error personalizado, agréguelo después de
?
:fuente
Por simplicidad y brevedad:
Con salidas:
fuente