run configurar makefile

configurar - makefile windows



Variable Makefile como requisito previo (7)

Como veo, el comando necesita la variable ENV para que pueda verificarlo en el comando mismo:

.PHONY: deploy check-env deploy: check-env rsync . $(ENV).example.com:/var/www/myapp/ check-env: if test "$(ENV)" = "" ; then / echo "ENV not set"; / exit 1; / fi

En un archivo Makefile, una receta de deploy necesita una variable de entorno ENV para establecerse para ejecutarse correctamente, mientras que a otros no les importa, por ejemplo:

ENV = .PHONY: deploy hello deploy: rsync . $(ENV).example.com:/var/www/myapp/ hello: echo "I don''t care about ENV, just saying hello!"

¿Cómo puedo asegurarme de que esta variable esté configurada, por ejemplo, hay una forma de declarar esta variable de archivo MAKE como un requisito previo de la receta de implementación, como:

deploy: make-sure-ENV-variable-is-set

?

Gracias.


Esto causará un error fatal si ENV no está definido y algo lo necesita (en GNUMake, de todos modos).

.PHONY: deploy check-env deploy: check-env ... other-thing-that-needs-env: check-env ... check-env: ifndef ENV $(error ENV is undefined) endif

(Tenga en cuenta que ifndef y endif no están sangrados, "$ (error" está indentado con espacios, no una pestaña; ellos controlan qué hace que "ve", surta efecto antes de que se ejecute Makefile ).


He encontrado que la mejor respuesta no se puede usar como un requisito, a excepción de otros objetivos de PHONY. Si se usa como una dependencia para un objetivo que es un archivo real, el uso de check-env obligará a reconstruir el objetivo del archivo.

Otras respuestas son globales (p. Ej., La variable es necesaria para todos los objetivos en el Makefile) o utilizan el intérprete de comandos, por ejemplo, si faltara ENV, la marca terminaría independientemente del objetivo.

Una solución que encontré para ambos problemas es

ndef = $(if $(value $(1)),,$(error $(1) not set)) .PHONY: deploy deploy: $(call ndef,ENV) echo "deploying $(ENV)" .PHONY: build build: echo "building"

La salida se ve como

$ make build echo "building" building $ make deploy Makefile:5: *** ENV not set. Stop. $ make deploy ENV="env" echo "deploying env" deploying env $

value tiene algunas advertencias atemorizantes, pero para este simple uso creo que es la mejor opción.


Puede crear un objetivo de guardia implícito, que verifica que la variable en el tallo esté definida, así:

guard-%: @ if [ "${${*}}" = "" ]; then / echo "Environment variable $* not set"; / exit 1; / fi

A continuación, agregue un objetivo guard-ENVVAR donde desee afirmar que se define una variable, como esta:

change-hostname: guard-HOSTNAME ./changeHostname.sh ${HOSTNAME}

Si llama a ''make change-hostname'', sin agregar HOSTNAME = somehostname en la llamada, entonces obtendrá un error y la compilación fallará.


Puede usar ifdef lugar de un objetivo diferente.

.PHONY: deploy deploy: ifdef ENV rsync . $(ENV).example.com:/var/www/myapp/ else @echo 1>&2 "ENV must be set" false # Cause deploy to fail endif


Un posible problema con las respuestas dadas hasta ahora es que el orden de dependencia en make no está definido. Por ejemplo, ejecutando:

make -j target

cuando el target tiene algunas dependencias no garantiza que se ejecutarán en un orden determinado.

La solución para esto (para garantizar que se verifique ENV antes de que se elijan las recetas) es verificar ENV durante el primer pase del fabricante, fuera de cualquier receta:

## Are any of the user''s goals dependent on ENV? ifneq ($(filter deploy other-thing-that-needs-ENV,$(MAKECMDGOALS)),$()) ifndef ENV $(error ENV not defined) endif endif .PHONY: deploy deploy: foo bar ... other-thing-that-needs-ENV: bar baz bono ...

Puede leer sobre las diferentes funciones / variables utilizadas here y $() es solo una manera de afirmar explícitamente que estamos comparando contra "nada".


Variante en línea

En mis makefiles, normalmente uso una expresión como:

deploy: test -n "$(ENV)" # $$ENV rsync . $(ENV).example.com:/var/www/myapp/

Las razones:

  • es un simple trazador de líneas
  • es compacto
  • está ubicado cerca de los comandos que usan la variable

No olvides el comentario que es importante para la depuración:

test -n "" Makefile:3: recipe for target ''deploy'' failed make: *** [deploy] Error 1

... te obliga a buscar el Makefile mientras ...

test -n "" # $ENV Makefile:3: recipe for target ''deploy'' failed make: *** [deploy] Error 1

... explica directamente lo que está mal

Variante global (para completar, pero no se pide)

Además de tu Makefile, también puedes escribir:

ifeq ($(ENV),) $(error ENV is not set) endif

Advertencias:

  • no use la pestaña en ese bloque
  • use con cuidado: incluso el objetivo clean fallará si ENV no está configurado. De lo contrario, vea la respuesta de Hudon que es más compleja