Jak przekazać definicję makra z argumentów wiersza poleceń „make” (-D) do kodu źródłowego C?


107

Zazwyczaj przekazuję definicje makr z "make command line" do "makefile" używając opcji: -Dname = wartość. Definicja jest dostępna w pliku makefile.

Przekazuję również definicje makr z „makefile” do „kodu źródłowego” przy użyciu podobnej opcji kompilatora: -Dname = wartość (obsługiwana w wielu kompilatorach). Ta definicja jest dostępna w kodzie źródłowym.

To, czego teraz potrzebuję, to umożliwienie użytkownikowi mojego makefile natychmiastowego przekazania dowolnych definicji makr z wiersza polecenia „make.exe” do „kodu źródłowego”, bez konieczności zmiany czegokolwiek w pliku makefile.

więc użytkownik może wpisać: make -f mymakefile.mk -SOMEOPTION var = 5

następnie bezpośrednio kod main.c może zobaczyć var:

int main()
{
  int i = var;
}

15
Dlaczego głos przeciw? Dla mnie wygląda na całkowicie uzasadnione pytanie.
Thomas

Odpowiedzi:


99

Wywołaj makepolecenie w ten sposób:

make CFLAGS=-Dvar=42

I pamiętaj, aby użyć $(CFLAGS)polecenia kompilacji w pliku Makefile. Jak wspomniał @ jørgensen, umieszczenie przypisania zmiennej po makepoleceniu nadpisuje CFLAGSwartość już zdefiniowaną w Makefile.

Alternatywnie możesz ustawić -Dvar=42inną zmienną niż, CFLAGSa następnie ponownie użyć tej zmiennej w, CFLAGSaby uniknąć całkowitego zastąpienia CFLAGS.


8
Nie możesz użyć "CFLAGS = $ (CFLAGS) -Wall"; byłaby to definicja rekurencyjna i sprawia, że ​​na to nie pozwala. Możesz użyć „CFLAGS: = $ (CFLAGS) -Wall” lub „CFLAGS + = -Wall”, ale te też nie będą działać, ponieważ przypisanie w wierszu poleceń ma wyższy priorytet. Możesz użyć "override CFLAGS + = -Wall", ale generalnie zalecamy, abyś wewnętrznie wybierał różne zmienne. Standardy kodowania GNU wymagają pozostawienia CFLAGS itp. Dla użytkownika, a pliki makefiles wybierają inną zmienną, na przykład „local_CFLAGS = $ (CFLAGS) -Wall”.
MadScientist,

2
Aby dodać do notatki @MadScientist, standardy kodowania GNU określają również, że $(CFLAGS)powinno to być ostatnie, tak aby wszelkie opcje określone przez użytkownika nadpisały wszystko, co wewnętrznie ustawia Makefile. Oznaczałoby to użycie np local_CFLAGS = -Wall $(CFLAGS). I odwrotnie, jeśli jest coś, co naprawdę chcesz mieć pierwszeństwo, umieść to po $(CFLAGS), jak w komentarzu @MadScientist.
Sam

1
Jak przez to ustawić wiele makr?
Woody Huang

2
Na przykład CFLAGS="-Dvar1=42 -Dvar2=314"
@WoodyHuang

1
CPPFLAGSmoże oznaczać lepsze dopasowanie niż CFLAGSlub CXXFLAGS: stackoverflow.com/a/53527858/2278206
psq

11

Po prostu użyj do tego określonej zmiennej.

$ 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

10

Zadzwoń w ten sposób

make CFLAGS=-Dvar=42

ponieważ chcesz nadpisać CFLAGS swojego Makefile, a nie tylko środowisko (które ma niższy priorytet w odniesieniu do zmiennych Makefile).


6

Z powodu złej reputacji nie mogę skomentować zaakceptowanej odpowiedzi.

Chciałbym wspomnieć o predefiniowanej zmiennej CPPFLAGS. Może lepiej pasować niż CFLAGSlub CXXFLAGS, ponieważ jest opisane w podręczniku GNU Make jako:

Dodatkowe flagi, które należy przekazać preprocesorowi C i programom, które go używają (kompilatorom C i Fortran).

Przykłady wbudowanych niejawnych reguł, które używają CPPFLAGS

  • n.ojest wykonywany automatycznie n.cz receptury o postaci:
    • $(CC) $(CPPFLAGS) $(CFLAGS) -c
  • n.oodbywa się automatycznie z n.cc, n.cpplub n.Cz przepisu w postaci:
    • $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c

Polecenia make CPPFLAGS=-Dvar=123można by użyć do zdefiniowania żądanego makra.

Więcej informacji


1
$ cat x.mak
wszystko:
    echo $ (OPCJA)
$ make -f x.mak 'OPCJA = -DPASSTOC = 42'
echo -DPASSTOC = 42
-DPASSTOC = 42

-4

Znajdź plik C i implementację Makefile poniżej, aby spełnić swoje wymagania

foo.c

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

Makefile

all:
    gcc -DMAKE_DEFINE=11 foo.c

chodzi o przekazanie dowolnych definicji z linii poleceń make bezpośrednio do kodu źródłowego C „bez zmiany pliku makefile”. Chciałem więc raz zmienić plik makefile, aby umożliwić tworzenie dowolnych definicji.
MohamedEzz

Nie działa na markę. To znaczy make -DMAKE_DEFINE = 11 mówi, że opcja jest nieprawidłowa.
Ramakrishnan Kannan
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.