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 robią $@
i $<
robią dokładnie?
Odpowiedzi:
$@
to nazwa generowanego pliku i$<
pierwszy warunek wstępny (zwykle plik źródłowy). Listę wszystkich tych zmiennych specjalnych można znaleźć w instrukcji GNU Make .Rozważmy na przykład następującą deklarację:
W tym przypadku:
$@
ocenia naall
$<
ocenia nalibrary.cpp
$^
ocenia nalibrary.cpp main.cpp
źródło
$@
niekoniecznie musi to być plik, może to być również nazwa.PHONY
celu.$@s
aby wygenerować dane wyjściowe zestawu, takie jak name.os?$@
I$<
nazywane są zmienne automatyczne . Zmienna$@
reprezentuje nazwę pliku, który został utworzony (tj. Cel) i$<
stanowi pierwszy warunek wstępny wymagany do utworzenia pliku wyjściowego.Na przykład:
Oto
hello.o
plik wyjściowy. To właśnie się$@
rozwija. Pierwsza zależność tohello.c
. To właśnie się$<
rozwija.-c
Flaga generuje.o
plik; zobaczman gcc
bardziej szczegółowe wyjaśnienie.-o
Określa plik wyjściowy do tworzenia.Aby uzyskać więcej informacji, możesz przeczytać ten artykuł o Makefiles Linux .
Możesz także sprawdzić instrukcje GNU
make
. Ułatwi to tworzenie plików Makefiles i ich debugowanie.Jeśli uruchomisz to polecenie, wyświetli on bazę danych makefile:
źródło
$<
rozwinięta dohello.c hello.h
(oba). Proszę o wyjaśnienie.$<
to tylko pierwszy element. Aby uwzględnić wszystkie, użyj$^
.Z zarządzania projektami za pomocą GNU Make, wydanie trzecie, str. 16 (na licencji GNU Free Documentation License ):
źródło
$@
I$<
specjalne makra.Gdzie:
$@
to nazwa pliku celu.$<
to nazwa pierwszej zależności.źródło
Makefile buduje
hello
wykonywalny jeśli ktoś zmain.cpp
,hello.cpp
,factorial.cpp
zmianie. Najmniejszy możliwy Makefile, aby osiągnąć tę specyfikację, mógł być:Aby poprawić powyższe, kompilujemy tylko te pliki C ++, które były edytowane. Następnie po prostu łączymy powstałe pliki obiektów razem.
Aby to poprawić, możemy zastąpić wszystkie reguły plików obiektowych jedną
.cpp.o
regułą:Tutaj
.cpp.o
zasada określa, jak budowaćanyfile.o
odanyfile.cpp
.$<
pasuje do pierwszej zależności, w tym przypadkuanyfile.cpp
$@
pasuje do cel, w tym przypadkuanyfile.o
.Inne zmiany obecne w Makefile to:
źródło
na przykład, jeśli chcesz kompilować źródła, ale masz obiekty w innym katalogu:
Musisz zrobić :
ale w przypadku większości makr wynikiem będą wszystkie obiekty, a po nich wszystkie źródła, takie jak:
więc to nic nie skompiluje ^^ i nie będzie można umieścić plików obiektów w innym katalogu :(
rozwiązaniem jest użycie tych specjalnych makr
wygeneruje to plik .o (obj / plik.o) dla każdego pliku .c w SRC (src / file.c)
to znaczy :
ale linie po liniach ZAMIAST wszystkich linii OBJ, po których następują wszystkie linie SRC
źródło