Comment passer la définition de macro d'arguments de ligne de commande «make» (-D) au code source C?

107

Je passe généralement des définitions de macro de "make command line" à un "makefile" en utilisant l'option: -Dname = value. La définition est accessible dans le makefile.

Je passe également des définitions de macro du "makefile" au "code source" en utilisant l'option de compilation similaire: -Dname = valeur (prise en charge dans de nombreux compilateurs). Cette définition est accessible dans le code source.

Ce dont j'ai besoin maintenant, c'est de permettre à l'utilisateur de mon makefile de pouvoir passer des définitions de macro arbitraires de la ligne de commande "make.exe" au "code source" tout de suite, sans avoir à changer quoi que ce soit dans le makefile.

donc l'utilisateur peut taper: make -f mymakefile.mk -SOMEOPTION var = 5

puis directement le code main.c peut voir var:

int main()
{
  int i = var;
}
MohamedEzz
la source
15
Pourquoi le vote négatif? Cela me semble être une question parfaitement légitime.
Thomas

Réponses:

99

Appelez la makecommande de cette façon:

make CFLAGS=-Dvar=42

Et assurez-vous d'utiliser $(CFLAGS)dans votre commande compile dans le Makefile. Comme @ jørgensen l'a mentionné, placer l'affectation de variable après la makecommande remplacera la CFLAGSvaleur déjà définie dans le Makefile.

Vous pouvez également définir -Dvar=42une autre variable que CFLAGS, puis réutiliser cette variable CFLAGSpour éviter de la remplacer complètement CFLAGS.

ouah
la source
8
Vous ne pouvez pas utiliser "CFLAGS = $ (CFLAGS) -Wall"; ce serait une définition récursive et make ne le permet pas. Vous pouvez utiliser "CFLAGS: = $ (CFLAGS) -Wall", ou "CFLAGS + = -Wall", mais cela ne fonctionnera pas non plus car une affectation sur la ligne de commande a une priorité plus élevée. Vous pouvez utiliser "override CFLAGS + = -Wall", mais généralement nous vous recommandons de choisir simplement différentes variables en interne. Les normes de codage GNU exigent que CFLAGS etc. soit laissé à l'utilisateur, et makefiles choisit une autre variable, comme "local_CFLAGS = $ (CFLAGS) -Wall".
MadScientist
2
Juste pour ajouter à la note @MadScientist, les normes de codage GNU indiquent également que $(CFLAGS)doit venir en dernier, de sorte que toutes les options spécifiées par un utilisateur remplacent tout ce que le Makefile définit en interne. Cela signifierait utiliser par exemple local_CFLAGS = -Wall $(CFLAGS). Inversement, s'il y a quelque chose que vous voulez vraiment avoir la priorité, mettez-le après $(CFLAGS), comme dans le commentaire @MadScientist.
Sam
1
Comment définir plusieurs macros par cela?
Woody Huang
2
@WoodyHuang par exempleCFLAGS="-Dvar1=42 -Dvar2=314"
ouah
1
CPPFLAGSpourrait représenter un meilleur ajustement que CFLAGSou CXXFLAGS: stackoverflow.com/a/53527858/2278206
psq
11

Utilisez simplement une variable spécifique pour cela.

$ 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
Tapis
la source
10

Appelez - faire de cette façon

make CFLAGS=-Dvar=42

parce que vous voulez remplacer les CFLAGS de votre Makefile, et pas seulement l'environnement (qui a une priorité inférieure en ce qui concerne les variables Makefile).

jørgensen
la source
6

En raison de ma faible réputation, je ne peux pas commenter la réponse acceptée.

Je voudrais mentionner la variable prédéfinie CPPFLAGS. Cela pourrait représenter un meilleur ajustement que CFLAGSou CXXFLAGS, car il est décrit par le manuel GNU Make comme:

Drapeaux supplémentaires à donner au préprocesseur C et aux programmes qui l'utilisent (les compilateurs C et Fortran).

Exemples de règles implicites intégrées qui utilisent CPPFLAGS

  • n.ose fait automatiquement à partir n.cd'une recette de la forme:
    • $(CC) $(CPPFLAGS) $(CFLAGS) -c
  • n.ose fait automatiquement à partir de n.cc, n.cppou n.Cavec une recette de la forme:
    • $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c

On utiliserait la commande make CPPFLAGS=-Dvar=123pour définir la macro souhaitée.

Plus d'informations

psq
la source
1
$ chat x.mak
tout:
    echo $ (OPTION)
$ make -f x.mak 'OPTION = -DPASSTOC = 42'
echo -DPASSTOC = 42
-DPASSTOC = 42
pmg
la source
-4

Trouvez le fichier C et l'implémentation Makefile ci-dessous pour répondre à vos besoins

toto.c

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

Makefile

all:
    gcc -DMAKE_DEFINE=11 foo.c
mahendiran.b
la source
la question est de passer des définitions arbitraires de la ligne de commande make directement au code source C "sans changer le makefile". Je voulais donc changer mon makefile une fois, pour permettre ces définitions arbitraires à faire.
MohamedEzz
Ça ne marche pas pour faire. C'est-à-dire que make -DMAKE_DEFINE = 11 indique une option invalide.
Ramakrishnan Kannan