Co oznaczają symbole makefile $@ i $
CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
    $(CC) $(LDFLAGS) $(OBJECTS) -o $@

.cpp.o:
    $(CC) $(CFLAGS) $< -o $@
Co dokładnie robią $@i $<?
 284
Author: Jonathan Leffler, 2010-07-10

5 answers

$@ jest nazwą generowanego pliku i $< pierwszym warunkiem (Zwykle plikiem źródłowym). Listę wszystkich tych specjalnych zmiennych znajdziesz w GNU Make manual .

Na przykład, rozważmy następującą deklarację:

all: library.cpp main.cpp

W tym przypadku:

  • $@ ocenia do all
  • $< ocenia do library.cpp
  • $^ ocenia do library.cpp main.cpp
 338
Author: bdonlan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-27 22:57:16

$@ i $< nazywane są zmiennymi automatycznymi. $@ jest zmienną wyjściową. $< jest pierwszą zmienną wejściową. Na przykład:

hello.o: hello.c hello.h
         gcc -c $< -o $@

Tutaj, hello.o jest plikiem wyjściowym. To jest to, co $@ rozszerza się do. Pierwsza zależność to hello.c. To jest to, co $< rozszerza się do.

Znacznik -c generuje plik .o; Zobacz man gcc, aby uzyskać bardziej szczegółowe wyjaśnienie. -o Określa plik do wyjścia.

Aby uzyskać więcej informacji, możesz przeczytać to .

MoĹźna teĹź sprawdziÄ ‡ podrÄ ™ czniki GNU. Istnieje sposób na debugowanie pliku makefile, aby lepiej go zrozumieć.

To wyświetli bazę danych makefile:

$make -p 
 60
Author: dexterous_stranger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-16 19:38:03

$@ i $< są specjalnymi makrami.

Gdzie:

$@ jest nazwą pliku docelowego.

$< to nazwa pierwszej zależności.

 33
Author: Eric,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-25 10:05:04

From Managing Projects with GNU Make, 3rd Edition (It ' s under GNU Free Documentation License):

zmienne automatyczne {[18] } są ustawiane przez make po dopasowaniu reguły. Oni zapewnić dostęp do elementów z listy docelowej i warunkowej, tak nie musisz jawnie określać żadnych nazw plików. Są bardzo przydatne do unikania powielania kodu, ale są krytyczne przy definiowaniu bardziej ogólne zasady.

Są siedem" rdzeniowych " zmiennych automatycznych:

  • $@: nazwa pliku reprezentująca obiekt docelowy.

  • $%: element nazwy pliku specyfikacji członka archiwum.

  • $<: nazwa pliku pierwszego warunku.

  • $?: nazwy wszystkich warunków wstępnych, które są nowsze niż cel, oddzielone spacjami.

  • $^: nazwy plików wszystkich warunków wstępnych, oddzielone spacjami. To lista usuwa zduplikowane nazwy plików, ponieważ dla większości zastosowań, takich jak kompilowanie, kopiowanie itp., duplikaty nie są poszukiwane.

  • $+: podobne do $^, są to nazwy wszystkich przesłanek oddzielonych przez spacje, z tym że $+ zawiera duplikaty. Zmienna ta była stworzony dla konkretnych sytuacji, takich jak argumenty do linkerów, gdzie zduplikowane wartości mają znaczenie.

  • $*: rdzeń nazwy pliku docelowego. Rdzeń jest zazwyczaj nazwą pliku bez jego przyrostek. Jego użycie poza regułami wzorca jest zniechęcony.

Ponadto każda z powyższych zmiennych ma dwa warianty dla kompatybilność z innymi markami. Jeden wariant zwraca tylko katalog część wartości. Wskazuje się to poprzez dodanie litery " D " do symbol, $(@D), $(<D), itd. Drugi wariant zwraca tylko plik część wartości. Wskazuje się to poprzez dodanie "F" do symbol, $(@F), $(<F), itd. Zauważ, że nazwy tych wariantów są więcej niż jeden znak długi i tak musi być zamknięty w nawiasach. GNU make zapewnia bardziej czytelną alternatywę z dir i notdir funkcje.

 28
Author: alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-08 11:27:02

Makefile buduje hello plik wykonywalny, jeśli któryś z main.cpp, hello.cpp, factorial.cpp zmieniony. Najmniejszym możliwym Makefile do osiągnięcia tej specyfikacji mogło być:

hello: main.cpp hello.cpp factorial.cpp
    g++ -o hello main.cpp hello.cpp factorial.cpp
  • pro: bardzo łatwy do odczytania
  • con: maintenance nightmare, duplikacja zależności C++
  • con: problem wydajności, rekompilujemy wszystkie C++ nawet jeśli tylko jeden został zmieniony

Aby poprawić powyższe, kompilujemy tylko te pliki C++, które zostały edytowane. Następnie łączymy wynikowe pliki obiektów razem.

OBJECTS=main.o hello.o factorial.o

hello: $(OBJECTS)
    g++ -o hello $(OBJECTS)

main.o: main.cpp
    g++ -c main.cpp

hello.o: hello.cpp
    g++ -c hello.cpp

factorial.o: factorial.cpp
    g++ -c factorial.cpp
  • pro: rozwiązuje problem wydajności
  • con: nowy koszmar konserwacji, potencjalne literówki w regułach plików obiektowych

Aby to poprawić, możemy zastąpić wszystkie reguły plików obiektowych jedną regułą .cpp.o:

OBJECTS=main.o hello.o factorial.o

hello: $(OBJECTS)
    g++ -o hello $(OBJECTS)

.cpp.o:
    g++ -c $< -o $@
  • pro: powrót do krótkiego pliku makefile, nieco łatwego do odczytania

Tutaj .cpp.o reguła określa jak zbudować anyfile.o z anyfile.cpp.

  • $< pasuje do pierwszej zależności, w tym przypadku anyfile.cpp
  • $@ pasuje do celu, w tym przypadku anyfile.o.

Inne zmiany obecne w pliku Makefile to:

  • ułatwiające zmianę kompilatorów z g++ na dowolny kompilator C++.
  • ułatwiające zmianę opcji kompilatora.
  • ułatwiające zmianę opcji linkera.
  • ułatwiające zmianę plików źródłowych i wyjściowych C++.
  • dodano domyślną regułę 'all', która działa jako szybkie sprawdzenie upewnij się, że wszystkie pliki źródłowe są obecne przed próbą zbudowania aplikacji.
 15
Author: Stephen Quan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-12 03:04:51