Pasar variables adicionales desde la línea de comando para hacer

¿Puedo pasar variables a un Makefile de GNU como argumentos de línea de comando? En otras palabras, quiero pasar algunos argumentos que eventualmente se convertirán en variables en el Makefile.

Tiene varias opciones para configurar variables desde fuera de su archivo MAKE:

  • Desde el entorno : cada variable de entorno se transforma en una variable de archivo MAKE con el mismo nombre y valor.

    También es posible que desee establecer -e opción (aka --environments-override ), y sus variables de entorno --environments-override las asignaciones realizadas en makefile (a menos que estas asignaciones usen la directiva de override . Sin embargo, no se recomienda, y es mucho mejor y flexible para usar ?= asignación (el operador de asignación de variable condicional, solo tiene un efecto si la variable aún no está definida):

     FOO?=default_value_if_not_set_in_environment 

    Tenga en cuenta que ciertas variables no se heredan del entorno:

    • MAKE se obtiene del nombre del script
    • SHELL se establece dentro de un archivo MAKE, o por defecto es /bin/sh (justificación: los comandos se especifican dentro del archivo MAKE y son específicos del shell).
  • Desde la línea de comandos , make puede tomar asignaciones variables como parte de su línea de comando, mezcladas con los objectives:

     make target FOO=bar 

    Pero todas las asignaciones a la variable FOO dentro del archivo MAKE se ignorarán a menos que use la directiva de override en la asignación. (El efecto es el mismo que con la opción -e para variables de entorno).

  • Exportar desde el Make padre : si llama a Make desde un Makefile, generalmente no debería escribir explícitamente asignaciones de variables como esta:

     # Don't do this! target: $(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS) 

    En cambio, una mejor solución podría ser exportar estas variables. Al exportar una variable, se convierte en el entorno de cada invocación de shell y, al hacer llamadas desde estos comandos, se eligen estas variables de entorno tal como se especificó anteriormente.

     # Do like this CFLAGS=-g export CFLAGS target: $(MAKE) -C target 

    También puede exportar todas las variables usando export sin argumentos.

La forma más simple es:

 make foo=bar target 

Luego, en su archivo MAKE puede referirse a $(foo) . Tenga en cuenta que esto no se propagará a sub-marcas automáticamente.

Si está utilizando sub-marcas, vea este artículo: Comunicar variables a una sub-marca

Digamos que tienes un archivo MAKE como este:

 action: echo argument is $(argument) 

Entonces lo llamarías make action argument=something

Del manual :

Las variables en make pueden provenir del entorno en el que se ejecuta make. Cada variable de entorno que ve cuando se inicia se transforma en una variable make con el mismo nombre y valor. Sin embargo, una asignación explícita en el archivo MAKE, o con un argumento de comando, anula el entorno.

Entonces puedes hacer (desde bash):

 FOOBAR=1 make 

dando como resultado una variable FOOBAR en tu Makefile.

Si crea un archivo llamado Makefile y agrega una variable como $ (unittest), entonces podrá usar esta variable dentro del Makefile incluso con comodines.

ejemplo:

 make unittest=* 

Yo uso BOOST_TEST y al dar un comodín al parámetro –run_test = $ (unittest) entonces podré usar la expresión regular para filtrar la prueba que quiero que mi Makefile ejecute

 export ROOT_DIR= 

Luego usa la variable, $(ROOT_DIR) en el Makefile.

Hay otra opción que no se cita aquí y que se incluye en el libro Make de GNU de Stallman y McGrath (ver http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_7.html ). Proporciona el ejemplo:

 archive.a: ... ifneq (,$(findstring t,$(MAKEFLAGS))) +touch archive.a +ranlib -t archive.a else ranlib archive.a endif 

Implica verificar si un parámetro dado aparece en MAKEFLAGS . Por ejemplo … supongamos que está estudiando hilos en c ++ 11 y ha dividido su estudio en varios archivos ( class01 , …, classNM ) y desea: comstackr todo y ejecutar de forma individual o comstackr uno a la vez y ejecutarlo si se especifica una bandera ( -r , por ejemplo). Por lo tanto, podría obtener el siguiente Makefile :

 CXX=clang++-3.5 CXXFLAGS = -Wall -Werror -std=c++11 LDLIBS = -lpthread SOURCES = class01 class02 class03 %: %.cxx $(CXX) $(CXXFLAGS) -o $@.out $^ $(LDLIBS) ifneq (,$(findstring r, $(MAKEFLAGS))) ./$@.out endif all: $(SOURCES) .PHONY: clean clean: find . -name "*.out" -delete 

Teniendo eso, usted:

  • comstackr y ejecutar un archivo w / make -r class02 ;
  • construir todo w / make o make all ;
  • comstack y ejecuta todo w / make -r (supongamos que todos contienen cierto tipo de cosas de afirmación y solo quieres probarlas todas)