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;
}
MohamedEzz
źródło
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.

ouah
źródło
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
Mata
źródło
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).

jørgensen
źródło
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

psq
źródło
1
$ cat x.mak
wszystko:
    echo $ (OPCJA)
$ make -f x.mak 'OPCJA = -DPASSTOC = 42'
echo -DPASSTOC = 42
-DPASSTOC = 42
pmg
źródło
-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
mahendiran.b
źródło
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