In der gcc-Befehlszeile möchte ich eine Zeichenfolge definieren, z. B. -Dname=Mary
im Quellcode, den ich printf("%s", name);
drucken möchte Mary
.
Wie könnte ich das machen?
In der gcc-Befehlszeile möchte ich eine Zeichenfolge definieren, z. B. -Dname=Mary
im Quellcode, den ich printf("%s", name);
drucken möchte Mary
.
Wie könnte ich das machen?
Antworten:
Zwei Optionen. Entferne zuerst die Anführungszeichen, damit die Shell sie nicht frisst:
gcc -Dname=\"Mary\"
Oder wenn Sie wirklich -Dname = Mary wollen, können Sie es stringisieren, obwohl es ein bisschen hacky ist.
#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));
}
Beachten Sie, dass STRINGIZE_VALUE_OF bis zur endgültigen Definition eines Makros problemlos ausgewertet wird.
Um zu vermeiden, dass die Shell die Anführungszeichen und andere Zeichen "frisst", können Sie einzelne Anführungszeichen wie folgt versuchen:
gcc -o test test.cpp -DNAME='"Mary"'
Auf diese Weise haben Sie die volle Kontrolle darüber, was definiert ist (Anführungszeichen, Leerzeichen, Sonderzeichen und alles).
Die tragbarste Methode, die ich bisher gefunden habe, ist die Verwendung \"Mary\"
- sie funktioniert nicht nur mit gcc, sondern mit jedem anderen C-Compiler. Wenn Sie beispielsweise versuchen, /Dname='"Mary"'
mit dem Microsoft-Compiler zu arbeiten, wird dieser mit einem Fehler beendet, /Dname=\"Mary\"
funktioniert jedoch.
In Ubuntu habe ich einen Alias verwendet, der CFLAGS definiert, und CFLAGS hat ein Makro enthalten, das eine Zeichenfolge definiert, und dann habe ich CFLAGS in einem Makefile verwendet. Ich musste den doppelten Anführungszeichen und den \ Zeichen entkommen. Es sah ungefähr so aus:
CFLAGS='" -DMYPATH=\\\"/home/root\\\" "'
1) DEFINES=-DLOGPATH=\"./logfile\" CFLAGS = -v $(DEFINES)....
2) DEFINES=-DLOGPATH=\\\"./logfile\\\" CFLAGS = "-v $(DEFINES)...."
Verwendung der Compileroption -v ist nützlich, um zu sehen, was der Präprozessor tut.
Hier ist ein einfaches Beispiel:
#include <stdio.h>
#define A B+20
#define B 10
int main()
{
#ifdef __DEBUG__
printf("__DEBUG__ DEFINED\n");
printf("%d\n",A);
#else
printf("__DEBUG__ not defined\n");
printf("%d\n",B);
#endif
return 0;
}
Wenn ich kompiliere:
$gcc test.c
Ausgabe:
__DEBUG__ not defined
10
Wenn ich kompiliere:
$gcc -D __DEBUG__ test.c
Ausgabe:
__DEBUG__ defined
30
Dies ist meine Lösung für: -DUSB_PRODUCT=\""Arduino Leonardo\""
Ich habe es in einem Makefile verwendet mit:
GNU Make 3.81 (von GnuWin32)
und
avr-g ++ (AVR_8_bit_GNU_Toolchain_3.5.0_1662) 4.9.2
Das Ergebnis in einer vorkompilierten Datei (Option -E für g ++) lautet:
const u8 STRING_PRODUCT[] __attribute__((__progmem__)) = "Arduino Leonardo";
Zu Ihrer Information: Anscheinend können sogar verschiedene Versionen derselben Toolchain auf demselben System in dieser Hinsicht unterschiedlich wirken ... (Wie in scheint es, dass dies ein Shell-Passing-Problem ist, aber anscheinend ist es nicht nur auf die Shell beschränkt).
Hier haben wir xc32-gcc 4.8.3 vs. (avr-) gcc 4.7.2 (und mehrere andere), die dasselbe Makefile und main.c verwenden, der einzige Unterschied ist 'make CC=xc32-gcc'
usw.
CFLAGS += -D'THING="$(THINGDIR)/thing.h"'
wurde über mehrere Jahre in vielen Versionen von gcc (und bash) verwendet.
Um dies mit xc32-gcc kompatibel zu machen (und angesichts eines anderen Kommentars, der behauptet, "ist portabler als"), musste Folgendes getan werden:
CFLAGS += -DTHING=\"$(THINGDIR)/thing.h\"
ifeq "$(CC)" "xc32-gcc"
CFLAGS := $(subst \",\\\",$(CFLAGS))
endif
um die Dinge wirklich verwirrend zu machen, wenn man dies entdeckt: Anscheinend führt ein nicht zitiertes -D mit einem // zu einem #define mit einem Kommentar am Ende ... z
THINGDIR=/thingDir/
-> #define /thingDir//thing.h
->#define /thingDir
(Danke für die Hilfe von Antwort s hier, btw).
Ich habe gerade festgestellt, dass eine unserer Anwendungen unter Ubuntu nicht kompiliert werden kann. Und da sich Linux und Windows nicht auf einen gemeinsamen Ansatz geeinigt haben, habe ich diesen verwendet:
NAME := "Mary"
ifeq ($(SystemRoot),)
# building on another OS
CFLAGS_ADD += -Dname=\"Mary\"
else
# building on Windows
CFLAGS_ADD += -Dname=\\\"Mary\\\"
endif
-DNAME=\"Mary\"
) für Token zu verwenden, die Sie auf diese Weise definieren, damit sie wie andere Makros aussehen.