2010-03-09 11 views
52

En la línea de comando de gcc, quiero definir una cadena como -Dname=Mary, luego en el código fuente quiero printf("%s", name); para imprimir Mary.
¿Cómo podría hacerlo?¿Cómo se define un literal de cadena en la línea de comando de gcc?

+6

le recomiendo que utilice todo en mayúsculas ('-dNOMBRE = \ "María \"') para los tokens que vas para def ine de esta manera, para que se vean como otras macros. –

+0

La macro en la pregunta de cadena: http://stackoverflow.com/questions/240353/convert-a-preprocessor-token-to-a-string –

Respuesta

61

Dos opciones. En primer lugar, escapar de las comillas por lo que el shell no comen:

gcc -Dname=\"Mary\" 

O, si realmente quiere -dNOMBRE = María, que puede stringize que, aunque es un poco hacky.

#include <stdio.h> 

#define STRINGIZE(x) #x 
#define STRINGIZE_VALUE_OF(x) STRINGIZE(x) 


int main(int argc, char *argv[]) 
{ 
    printf("%s", STRINGIZE_VALUE_OF(name)); 
} 

Tenga en cuenta que STRINGIZE_VALUE_OF estará feliz de evaluar a la definición final de una macro.

+0

muchas gracias Arthur. usted debe ser un experto en C. más pregunta: I perfer la segunda opción. cuando estoy usando STRINGIZE_VALUE_OF (name), lo traduzco a "1", en el caso de que tenga gcc -Dname = Mary -DMary. de todos modos hay que dejar que gcc deje de hablar con María – richard

+0

Richard, después de muchas críticas, no creo que pueda encontrar una forma que funcione en el ejemplo anterior. Lamentablemente, sus opciones no son expansión (por ejemplo, le da "nombre") y expansión completa (por ejemplo, nombre-> María-> 1 si María se define como 1). Dependiendo de su caso de uso exacto, puede haber formas de evitar esto, por ejemplo, si Mary puede convertirse en una int en lugar de una definición. –

+0

gracias de nuevo. Iré con la primera opción. – richard

23

para evitar la concha "comer" las comillas y otros caracteres, puede probar con comillas simples, como este:

gcc -o test test.cpp -DNAME='"Mary"' 

De esta manera usted tiene el control total de lo que se define (comillas, espacios, caracteres especiales, y todo).

5

La forma más portátil que encontré hasta ahora es usar \"Mary\" - funcionará no solo con gcc sino con cualquier otro compilador de C. Por ejemplo, si intenta utilizar /Dname='"Mary"' con el compilador de Microsoft, se detendrá con un error, pero /Dname=\"Mary\" funcionará.

4

En Ubuntu estaba usando un alias que define CFLAGS, y CFLAGS incluía una macro que define una cadena, y luego uso CFLAGS en un Makefile. Tuve que escapar de los caracteres de comillas dobles y también de los \ caracteres. Parecía algo como esto:

CFLAGS='" -DMYPATH=\\\"/home/root\\\" "' 
+0

única solución que realmente funciona – Cyan

+1

A veces, tanto el escapado único como el ajuste entre comillas simples no funcionaba, pero esto sí funcionaba. Otras veces, no fue así. Creo que la diferencia es si las banderas se ponen entre comillas general: ' 1) define -DLOGPATH = = \ "./ archivo de registro \" CFLAGS = -v $ (define) ....' '2 ) DEFINES = -DLOGPATH = \\\ "./ logfile \\\" CFLAGS = "-v $ (DEFINES) ...." ' Usar la opción del compilador -v es útil para ver qué está haciendo el preprocesador . – JasonDiplomat

0

FYI: Al parecer, incluso diferentes versiones de la misma cadena de herramientas en el mismo sistema pueden actuar de manera diferente en este sentido ... (como en, sería parecer esto sería una problema al pasar el proyectil, pero aparentemente no está limitado a simplemente el caparazón).

Aquí tenemos XC32-gcc 4.8.3 vs (AVR-) gcc 4.7.2 (y varios otros ) utilizando el mismo makefile y main.c, la única diferencia es 'make CC=xc32-gcc', etc.

CFLAGS += -D'THING="$(THINGDIR)/thing.h"' ha estado en uso en muchas versiones de gcc (y bash) durante varios años.

Para hacer esto compatible con el XC32-gcc (y la luz de otro comentario afirmando que \" es más portátil que '"), lo siguiente que había que hacer:

CFLAGS += -DTHING=\"$(THINGDIR)/thing.h\" 

ifeq "$(CC)" "xc32-gcc" 
CFLAGS := $(subst \",\\\",$(CFLAGS)) 
endif 

para hacer las cosas realmente confuso al descubrir esto: al parecer, una D-sin para con un // da como resultado un #define con un comentario al final ... por ejemplo

THINGDIR=/thingDir/ ->#define /thingDir//thing.h ->#define /thingDir

(Gracias por la ayuda de la respuesta s aquí, por cierto).

-1

Esta es mi solución para: -DUSB_PRODUCT=\""Arduino Leonardo\""
que lo utilizó en un makefile con:
GNU Make 3.81 (de GnuWin32)
y
avr-g ++ (AVR_8_bit_GNU_Toolchain_3.5.0_1662) 4.9.2

Los resultados en un archivo precompilado (-E opción para g ++) es:
const u8 STRING_PRODUCT[] __attribute__((__progmem__)) = "Arduino Leonardo";

Cuestiones relacionadas