it-swarm.dev

Agregar a GNU crear variables a través de la línea de comando

Estoy utilizando un Makefile GNU-make para construir un proyecto en C con varios objetivos (all, clean, y algunos objetivos específicos del proyecto). En el proceso de depuración, me gustaría agregar algunas marcas a una única compilación sin editar permanentemente el Makefile (por ejemplo, agregar símbolos de depuración o establecer una marca de preprocesador).

En el pasado, he hecho lo siguiente (usando el ejemplo de los símbolos de depuración):

make target CFLAGS+=-g

Desafortunadamente, esto no se está agregando a la variable CFLAGS, sino que, en cambio, la borra y deja de compilar. ¿Hay una forma clara de hacerlo sin definir algún tipo de variable ficticia añadida al final de CFLAGS y LDFLAGS?

55
Michael Koval

Echa un vistazo a la directiva de anulación . Probablemente necesitará modificar el makefile una vez, pero debería hacer lo que quiera.

Ejemplo de makefile:

override CFLAGS += -Wall

app: main.c
    gcc $(CFLAGS) -o app main.c 

Ejemplo de líneas de comando:

$ make
gcc -Wall -o app main.c 
$ make CFLAGS=-g
gcc -g -Wall -o app main.c 
75
Carl Norum

Para el registro, la respuesta de @Carl Norum antepasa la variable, desde la perspectiva de la línea de comando.

Necesitaba una manera de añadir realmente y se me ocurrió:

override CFLAGS := -Wall $(CFLAGS)
25
aib

Hay dos formas de pasar variables para hacer:

  • Usando argumentos de línea de comando:

    make VAR=value
    
  • Usando el medio ambiente:

    export VAR=var; make
    

    o (mejor porque cambia el entorno solo para el comando actual)

    VAR=var make
    

Son ligeramente diferentes. El primero es más fuerte. Significa que sabes lo que quieres. El segundo puede ser considerado como una pista. La diferencia entre ellos es sobre los operadores = y += (sin override). Estos operadores se ignoran cuando una variable se define en la línea de comando, pero no se ignoran cuando la variable se define en el entorno. Por lo tanto, te sugiero que tengas un Makefile con:

CC ?= gcc
CFLAGS += -Wall
INTERNAL_VARS = value

y llámalo con:

CFLAGS=-g make

Tenga en cuenta que si desea retirar -Wall, puede usar:

make CFLAGS=

No utilice la palabra clave override, de lo contrario no tendrá ninguna forma de cambiar una variable afectada con override.

15
Jezz

Solo una nota, ya que me confundí, que este sea el archivo testmake:

$(eval $(info A: CFLAGS here is $(CFLAGS)))

override CFLAGS += -B

$(eval $(info B: CFLAGS here is $(CFLAGS)))

CFLAGS += -C

$(eval $(info C: CFLAGS here is $(CFLAGS)))

override CFLAGS += -D

$(eval $(info D: CFLAGS here is $(CFLAGS)))

CFLAGS += -E

$(eval $(info E: CFLAGS here is $(CFLAGS)))

Entonces:

$ make -f testmake
A: CFLAGS here is 
B: CFLAGS here is -B
C: CFLAGS here is -B
D: CFLAGS here is -B -D
E: CFLAGS here is -B -D
make: *** No targets.  Stop.
$ make -f testmake CFLAGS+=-g
A: CFLAGS here is -g
B: CFLAGS here is -g -B
C: CFLAGS here is -g -B
D: CFLAGS here is -g -B -D
E: CFLAGS here is -g -B -D
make: *** No targets.  Stop.

Con las directivas override eliminadas del archivo testmake:

$ make -f testmake
A: CFLAGS here is 
B: CFLAGS here is -B
C: CFLAGS here is -B -C
D: CFLAGS here is -B -C -D
E: CFLAGS here is -B -C -D -E
make: *** No targets.  Stop.
$ make -f testmake CFLAGS+=-g
A: CFLAGS here is -g
B: CFLAGS here is -g
C: CFLAGS here is -g
D: CFLAGS here is -g
E: CFLAGS here is -g
make: *** No targets.  Stop.

Asi que,

  • si una variable usó override una vez, solo se puede agregar con otra declaración con override (las asignaciones normales se ignorarán);
  • cuando no ha habido ningún override en absoluto; al intentar agregar (como en +=) desde la línea de comandos, se sobrescriben todas las instancias de esa variable.
6
sdaau