GNU Make Tutorial

GNU Make Tutorial

GNU Make jest niezbędnym narzędziem do budowania i zarządzania projektami, zwłaszcza tam, gdzie projekt zawiera różne pliki, które są budowane przy użyciu różnych narzędzi. W takim przypadku GNU sprawia, że ​​Lokalizuje Makefile dla tego projektu, ponieważ plik określa wymagane zależności między różnymi plikami w danym projekcie a poleceniami, które są wymagane do zbudowania projektu.

GNU Make jest przeznaczony do obsługi dużych projektów. Określa sekcje programu, który musi zostać ponownie skompilowany po danym działaniu, i oferuje polecenia w celu ponownego skompilacji sekcji. Dzisiejszy post zapewnia praktyczny przewodnik po zrozumieniu wszystkiego o Make GNU.

Zrozumienie makefile

GNU spraw, aby odczytał Makefile projektu, aby ustalić, co powinien zrobić, aby zbudować i zarządzać projektem. Makefile ma trzy kluczowe elementy: cel, warunek wstępny i przepis.

A cel reprezentuje plik, że „robić„Polecenie może wygenerować. Cel może zależeć od warunków wstępnych i może być również działaniem, które należy przeprowadzić. Idealnie, cel podkreśla plik do zbudowania po wykonaniu „robić" Komenda.

A warunek wstępny reprezentuje plik do użycia jako wejście do tworzenia celu. Cel może zależeć od wielu warunków wstępnych.

A przepis jest działaniem lub poleceniem przeprowadzonym przez „robić„Aby ponownie skompilować cel, ilekroć warunki wstępne zmiany. Przepis może zawierać różne polecenia w tych samych lub różnych wierszach. A przestrzeń zakładka Poprzedzi każdą nową linię przepisu, a edytor podnosi błąd, jeśli brakuje ci dodania znaku TAB.

przepis Działa jako seria poleceń powłoki, zaczynając od znaku TAB. Oto przykład prostego Makefile, który podkreśla cel, warunki wstępne i przepis:

Dostarczony makefile składa się z jednej zasady w przepisie. Zwróć uwagę, że użycie pierwszej reguły w Makefile jako zasady domyślnej. Tak więc w takim makijażu „robić”Używa gcc -witajcie świetnie.C Z reguły budowanie i zarządzanie projektem. Reguła określa, że ​​abyś wykonał plik do wygenerowania Witamy plik, musimy uruchomić polecenie, które używa Świetnie.C jako dane wejściowe do utworzenia Witamy plik.

Znowu nie wszystkie zasady mają warunek wstępny. Na przykład, jeśli masz makefile do usunięcia plików pośrednich, które są tworzone podczas budowania pliku, taka reguła nie ma żadnego warunku wstępnego. Spójrz na następujący przykład:

W takim przypadku reguła usuwa wszystkie pliki zawierające *.o Rozszerzenie. Zatem warunek wstępny nie jest wymagany w takim przypadku, ponieważ nie jest wymagana żadna ponowna kompilacja celu.

Praca z Makefile

Pierwszym przykładem jest prosty projekt C z dwoma plikami C i plik nagłówka. Tworzymy funkcję, która drukuje komunikat powitalny i zawiera zewnętrzny plik nagłówka w naszym projekcie.

Oto główna funkcja:

Nasze pliki nagłówka wyglądają jak następujące:

Teraz utwórzmy Makefile, który kompiluje pliki projektu, aby utworzyć plik wykonywalny w bieżącym katalogu. Idealnie wykonujemy następujące polecenie, aby zbudować projekt:

$ GCC -O GREATMAKE Mainfunc.c Func1.c -i.

Na poniższym obrazie możemy zauważyć, w jaki sposób kompilacja z powodzeniem buduje projekt. Jeśli utworzymy utworzony plik wykonywalny, otrzymujemy pożądane dane wyjściowe.

Jak możemy reprezentować to samo i zamiast tego użyć makefile? Oto rzecz: chociaż bezpośrednio kompilowanie projektu na wierszu poleceń działa dobrze, problem pojawia się podczas przełączania komputerów lub utraty kodu kompilacji. W takim przypadku musisz ponownie skompilować projekt. Ponownie, za każdym razem, gdy wprowadzasz zmiany w jednym pliku, musisz ręcznie ponownie skompilować projekt, aby uwzględnić zmiany.

Cały ten kłopot można wykluczyć, tworząc prosty makefile, jak pokazano następująco:

Makefile zawiera dwa cele: jeden z warunkami wstępnymi i poleceniem, a drugi tylko z poleceniem.

Wcześniej zauważyliśmy, że „robić”Używa pierwszego polecenia jako domyślnego polecenia, aby zbudować projekt. Stąd możemy wpisać robić w katalogu projektu, aby wykonać polecenie tworzenia projektu. Polecenie Make generuje cel, który jest Wysyłka Jako plik wykonywalny. Spójrz na następujące:

Teraz możemy wygodnie uruchomić plik wykonywalny, aby zobaczyć dane wyjściowe utworzonego projektu.

$ ./plik wyjściowy

Załóżmy, że używamy „robić„Aby wykonać inne polecenie zamiast domyślnego. Określ cel, który chcesz wykonać za pomocą polecenia Make.

$ Make Cel

Użyjmy tego samego Makefile i użyjmy Hello Target:

Zwróć uwagę, jak udaje nam się „zdobyć”robić„Aby uruchomić polecenie, ponieważ nie są określone w celu uzyskania żadnych warunków wstępnych.

Jeśli wprowadzimy pewne zmiany w jednym z plików w projekcie, uruchamianie „robić„Polecenie pomieści zmiany bez konieczności ręcznego rekompilacji projektu.

Mimo to, jeśli uruchomisz „robić„Polecenie bez nowych zmian”robić„Powiadomi Cię, że plik wykonywalny jest aktualny.

Załóżmy, że nie masz pewności co do dokonanych zmian lub tego, co robi polecenie Make Po wykonaniu. Możesz wykonać suchy bieg, dodając flagę -N.

Pierwszy przykład z poniższej ilustracji, marka -N, Pokazuje polecenie, które jest wykonywane za pomocą komendy domyślnej. W następnym przypadku make -n pokazuje zmiany dodane do celu hello.

Jeśli czujesz się komfortowo ze zmianami, możesz wykonać polecenie Make dla danego celu, aby uwzględnić zmiany jak w poniższym przykładzie:

Jak używać zmiennych Makefile

Jak dotąd zrozumieliśmy, jak „robić”Praca z makefile. Jednak nasze dotychczasowe podejście nie jest najlepsze do obsługi dużych projektów, szczególnie tam, gdzie niektóre wartości muszą się zmieniać z czasem. Lepsze podejście polega na stosowaniu zmiennych, tak że jeśli chcesz zmienić kompilator programu, możesz edytować zmienną zamiast ręcznie zmieniać kod Makefile dla kompilatora.

Ponadto zmienne pomagają osiągnąć czysty kod Makefile, który każdy może odczytać i zrozumieć.

Zróbmy przykład użycia zmiennych do tworzenia plików.

W Makefile definiujemy zmienną nazwaną akta który zawiera dwie wartości dla plików, które tworzymy podczas budowania projektu:

W tym przykładzie zapoznajmy się z naszym wcześniejszym przykładem kompilowania programu C. Ale w tym przypadku dodajmy kilka zmiennych, które możemy zmienić w całym programie.

Najpierw określamy ścieżkę, której kompilator powinien użyć do zlokalizowania plików nagłówka jako bieżącego katalogu (.). Lepszym podejściem jest określenie ścieżki jako zmiennej. Możesz określić zmienną, która ma być używana przez kompilator za pomocą Cflags Specjalne stałe, które są używane do komunikacji z kompilatorem.

Cflags = -i.

Użyj $ (Cflags) Zmienny symbol zastępczy zamiast ścieżki.

Mimo to możemy ustawić kompilator typu na użycie jako zmiennej, tak że ktoś, kto używa innego kompilatora, może zmienić zmienną, aby określić kompilator do użycia w ich przypadku.

CC = GCC

Użyj $ (Cc) Zmienny symbol zastępczy zamiast kompilatora. Oto ostateczny makefile z dodatkowymi zmiennymi:

Kiedy uruchamiamy polecenie Make, otrzymujemy takie samo wyjście, co wcześniej, tylko że nasz kod Makefile jest teraz czystszy i wyeliminowaliśmy wszelkie zwolnienia.

Podczas tworzenia Makefile możesz utworzyć makro Obj reprezentować warunki wstępne, które są wymagane do utworzenia celu. W ten sposób możesz szybko edytować pliki obiektowe z makra bez manipulowania drugim makefile. Na przykład możemy mieć makro OBJ dla naszego celu, jak pokazano następująco:

Zauważ, że zastępujemy warunki wstępne zmienną obiektu.

Obsługa zależności

„„włączać”Pliki zależą od„.C”Pliki w projekcie. Podczas pracy z dużym projektem i edytujesz „włączać" plik, „Make” nie rekompiluje „”.C" akta. Ten błąd oznacza, że ​​Twój projekt nie zostanie poprawnie ponownie skompilowany, chyba że uczynimy MakeFile odnotowane istniejące zależności między „.C" I ".H" akta.

W takim przypadku musimy użyć specjalnej stałej DEPS Aby utworzyć makro, aby obsłużyć te zależności. Możemy reprezentować DEP z reguły, jak pokazano następująco:

Poprzednia zasada najpierw tworzy DEPS makro, którego wartość to plik nagłówka w plikach projektu. Następnie instruuje „robić”To przed wygenerem„.o”Plik, musi najpierw skompilować„.C”Plik za pomocą określonego kompilatora. Następnie flaga -C wskazuje kompilator do wygenerowania pliku obiektu, podczas gdy -o $@ instructs "robić”Aby umieścić skompilowane wyjście po lewej stronie okrężnicy.

Dzięki tej zasadzie obsługujemy wszystkie zależności, aby za każdym razem, gdy zmieniamy dowolny plik, „robić”Uwzględnia go podczas ponownego rozpoznania projektu.

Dodawanie innych Makefiles

Podczas pracy z Makefile można włączyć inne makefile. W ten sposób obecny Makefile może odczytać z dołączonych Fifiles w celu obsługi kompilacji.

Aby dołączyć inne makefile, dodaj włączać Słowo kluczowe, które instruuje „robić„Zatrzymać odczyt aktualnego Makefile i przeczytać inne zawarte makefile.

Uwzględnij nazwy plików

Możesz także dołączyć inne typy plików do Słowa kluczowego dołączania, pod warunkiem dodania odstępów między nazwami plików.

Podzielanie długich linii z makefiles

Chociaż "robić”Nie ma ograniczeń co do tego, jak długo może być oświadczenie, długie zdania szybko stają się nieczytelne i są złym stylem formatowania. GNU „robić”Obejmuje podział długich zdań, dodając charakter odwrotny.

Obj = mainfunc.C \
Func1.C

W tym przykładzie „robić”Odczytuje poprzedni wiersz jako Obj = mainfunc.c Func1.C i zignoruj ukośnik wsteczny.

Na dostarczonym obrazie podzieliliśmy linię przepisu z odwrotną.

Załóżmy, że chcesz przedstawić jedno słowo bez dodawania białej listy. Wymień operatę na znak dolara, prasę odwrotną i nową linią.

Oto przykład:

Gdy "robić”Czyta MakeFile, najpierw ignoruje operatę nowej linii. Następnie odczytuje znak dolara jako przestrzeń, która reprezentuje zmienną z jednym znakiem.

Dlatego ostatecznie traktuje twoje podzielone linie jako jedno słowo bez białej listy. Kiedy używamy „robić„Aby przeczytać Makefile, nie otrzymujemy błędu, ponieważ”robić”Traktuje podzielone linie w zmiennej jako jedno słowo.

Czyszczenie katalogu

Po skompilowaniu programu za pomocą „robić”, Może być konieczne wyczyszczenie niepotrzebnych plików, które są generowane jako wyjście. Chociaż możliwe jest tworzenie czystego celu, nie jest to zalecane podejście, jak pokazano następująco:

Poprzedni obraz instruuje "robić" Aby usunąć wszystkie pliki tekstowe i „.o”Pliki rozszerzenia, które są tworzone w bieżącym katalogu.

Aby poradzić sobie z nieoczekiwanymi sytuacjami, najlepiej stworzyć bardziej precyzyjną regułę i upewnić się, że nie dodajesz jej jako domyślnej (pierwszej) zasady w Makefile.

Podczas wykonywania czystej reguły użyj „Wyczyść się" Komenda.

Wniosek

GNU „Make” to przydatne narzędzie do budowania i zarządzania małymi i dużymi projektami. Wiedza o tym, jak go używać, jest dodatkową zaletą, ponieważ pomaga odczytać makefile i starannie skompilować projekty. Nauczyliśmy się, jak korzystać z GNU ”robić„Dogłębne i jak pracować z makefile, w tym zrozumienie, w jaki sposób czyta Makefile. Mamy nadzieję, że ten przewodnik położył fundament, aby poprawić twoje GNU, tworząc umiejętności w zakresie radzenia sobie z projektami.