Wie übergebe ich die Makrodefinition von den Befehlszeilenargumenten (-D) "make" an den C-Quellcode?

106

Normalerweise übergebe ich Makrodefinitionen von "make command line" an ein "makefile" mit der Option: -Dname = value. Die Definition ist im Makefile zugänglich.

Ich übergebe auch Makrodefinitionen aus dem "Makefile" an den "Quellcode" mit der ähnlichen Compileroption: -Dname = value (wird von vielen Compilern unterstützt). Auf diese Definition kann im Quellcode zugegriffen werden.

Was ich jetzt brauche, ist, dem Benutzer meines Makefiles zu ermöglichen, beliebige Makrodefinitionen von der "make.exe-Befehlszeile" sofort an "Quellcode" zu übergeben, ohne etwas im Makefile ändern zu müssen.

Der Benutzer kann also Folgendes eingeben: make -f mymakefile.mk -SOMEOPTION var = 5

dann kann direkt der Code main.c var sehen:

int main()
{
  int i = var;
}
MohamedEzz
quelle
14
Warum das Downvote? Sieht für mich nach einer absolut legitimen Frage aus.
Thomas

Antworten:

99

Rufen Sie den makeBefehl folgendermaßen auf:

make CFLAGS=-Dvar=42

Und stellen Sie sicher, dass Sie $(CFLAGS)Ihren Kompilierungsbefehl im Makefile verwenden. Wie @ jørgensen erwähnt hat, makeüberschreibt das Setzen der Variablenzuweisung nach dem Befehl den CFLAGSWert, der bereits im Makefile definiert wurde.

Alternativ können Sie eine -Dvar=42andere Variable als festlegen CFLAGSund diese Variable dann wiederverwenden CFLAGS, um ein vollständiges Überschreiben zu vermeiden CFLAGS.

ouah
quelle
8
Sie können "CFLAGS = $ (CFLAGS) -Wall" nicht verwenden. Dies wäre eine rekursive Definition und make erlaubt dies nicht. Sie könnten "CFLAGS: = $ (CFLAGS) -Wall" oder "CFLAGS + = -Wall" verwenden, aber diese funktionieren auch nicht, da eine Zuweisung in der Befehlszeile eine höhere Priorität hat. Sie könnten "CFLAGS + = -Wall überschreiben" verwenden, aber im Allgemeinen empfehlen wir, nur intern verschiedene Variablen auszuwählen. Die GNU-Codierungsstandards verlangen, dass CFLAGS usw. dem Benutzer überlassen werden, und Makefiles wählen eine andere Variable aus, z. B. "local_CFLAGS = $ (CFLAGS) -Wall".
MadScientist
2
Um die Anmerkung von @MadScientist zu ergänzen, geben die GNU-Codierungsstandards auch an, dass $(CFLAGS)sie als letztes gelten sollen, damit alle von einem Benutzer angegebenen Optionen alles überschreiben, was das Makefile intern festlegt. Das würde bedeuten, zB zu verwenden local_CFLAGS = -Wall $(CFLAGS). Umgekehrt, wenn es etwas gibt, das wirklich Vorrang haben soll, setzen Sie es nach $(CFLAGS), wie im @ MadScientist-Kommentar.
Sam
1
Wie kann man damit mehrere Makros setzen?
Woody Huang
2
@ WoodyHuang zum BeispielCFLAGS="-Dvar1=42 -Dvar2=314"
ouah
1
CPPFLAGSkönnte eine bessere Passform darstellen als CFLAGSoder CXXFLAGS: stackoverflow.com/a/53527858/2278206
psq
11

Verwenden Sie dazu einfach eine bestimmte Variable.

$ cat Makefile 
all:
    echo foo | gcc $(USER_DEFINES) -E -xc - 

$ make USER_DEFINES="-Dfoo=one"
echo foo | gcc -Dfoo=one -E -xc - 
...
one

$ make USER_DEFINES="-Dfoo=bar"
echo foo | gcc -Dfoo=bar -E -xc - 
...
bar

$ make 
echo foo | gcc  -E -xc - 
...
foo
Matte
quelle
10

Rufen Sie machen diese Art und Weise

make CFLAGS=-Dvar=42

weil Sie die CFLAGS Ihres Makefiles überschreiben möchten und nicht nur die Umgebung (die in Bezug auf Makefile-Variablen eine niedrigere Priorität hat).

jørgensen
quelle
6

Aufgrund des geringen Ansehens kann ich die akzeptierte Antwort nicht kommentieren.

Ich möchte die vordefinierte Variable erwähnen CPPFLAGS. Es könnte eine bessere Passform darstellen als CFLAGSoder CXXFLAGS, da es im GNU Make- Handbuch wie folgt beschrieben wird :

Zusätzliche Flags für den C-Präprozessor und die Programme, die ihn verwenden (die C- und Fortran-Compiler).

Beispiele für integrierte implizite Regeln, die verwendet werden CPPFLAGS

  • n.owird automatisch n.cmit einem Rezept des Formulars erstellt:
    • $(CC) $(CPPFLAGS) $(CFLAGS) -c
  • n.owird automatisch aus hergestellt n.cc, n.cppoder n.Cmit einem Rezept der Form:
    • $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c

Man würde den Befehl verwenden make CPPFLAGS=-Dvar=123, um das gewünschte Makro zu definieren.

Mehr Info

psq
quelle
1
$ cat x.mak
alles:
    echo $ (OPTION)
$ make -f x.mak 'OPTION = -DPASSTOC = 42'
echo -DPASSTOC = 42
-DPASSTOC = 42
pmg
quelle
-4

Suchen Sie unten die C-Datei und die Makefile-Implementierung, um Ihre Anforderungen zu erfüllen

foo.c

 main ()
    {
        int a = MAKE_DEFINE;
        printf ("MAKE_DEFINE value:%d\n", a);
    }

Makefile

all:
    gcc -DMAKE_DEFINE=11 foo.c
mahendiran.b
quelle
Die Frage ist, beliebige Definitionen von der make-Befehlszeile direkt an den C-Quellcode zu übergeben, "ohne das Makefile zu ändern". Deshalb wollte ich mein Makefile einmal ändern, damit diese willkürlichen Definitionen vorgenommen werden können.
MohamedEzz
Funktioniert nicht für make. Das heißt, make -DMAKE_DEFINE = 11 sagt eine ungültige Option.
Ramakrishnan Kannan