Dlaczego Makefile chroni Cię przed kopiowaniem poleceń GCC

10

Bądźmy szczerzy. Ręczne wprowadzanie długich poleceń kompilacji gcc jest uciążliwe. Sytuacja szybko się pogarsza, gdy baza kodu rośnie, zawiera wiele bibliotek i ciągle wprowadzasz zmiany. Skończy się koszmarem kopiowania i wklejania, który pęka, jeśli przegapisz jedną flagę.

pliki makefile pojawiają się na zdjęciu.

Istnieją z jednego powodu: aby uniemożliwić ręczne wprowadzanie w kółko tej samej sekwencji kompilacji. Zamiast zapamiętywać dokładne flagi i kolejność plików obiektowych, piszesz przepis. Następnie po prostu wpisz „make”.

Jak faktycznie działa Makefile

Zaczynasz od utworzenia pliku zwanego dosłownie „makefile”. No extension. Only the name. Wewnętrznie definiujesz zależności.

Oto podstawowa struktura małego projektu w języku C:

Zwróć uwagę na wcięcia. Tutaj nowicjusze często się potykają. That space before gcc? Musi to być znak tabulacji. Not eight spaces. Tabulation. Jeśli użyjesz spacji, polecenie „make” wyświetli tajemniczy błąd i spędzisz dziesięć minut zastanawiając się, dlaczego twoja składnia wygląda dobrze dla ludzkiego oka, ale nie dla maszyny. Każdy wiersz poleceń w ramach zależności musi zaczynać się od tabulatora. Same definicje zależności powinny być wyrównane do lewej strony. Żadnych wyjątków.

Dependency logic

W pliku makefile znajdują się dwa typy linii. Pierwszą z nich są linie zależności. Wyglądają jak „cel: zależności”.

main.o: main.c util.h

Można to przetłumaczyć następująco: „Potrzebuję main.o. Aby to uzyskać, potrzebuję main.c i util.h.”

Drugi typ to ciąg wykonywalny. Jest uzależniona i zaczyna od zestawień. Jest to polecenie uruchamiane, jeśli „make” zdecyduje, że musi odbudować obiekt docelowy.

System działa na prostej zasadzie: jeśli jakikolwiek plik po prawej stronie dwukropka jest nowszy niż plik po lewej stronie, uruchamiane są poniższe polecenia. Did you change util.h? make widzi to, wie, że main.o i util.o są od tego zależne i odbudowuje je. To automatyzuje logikę.

Goal rule

Jest jedna złota zasada uruchamiania pliku makefile. Pierwszym określonym celem jest ten, który make próbuje domyślnie zbudować.

W powyższym przykładzie „main” jest pierwszą linią. Zatem kiedy uruchomisz make bez argumentów, zbuduje on ostateczny plik wykonywalny.

main: main.o util.o
gcc -o main main.o util.o

Jeśli zmienisz main.o, spowoduje to przebudowę main. Jeśli zmienisz main.c, uruchomi się main.o, które następnie uruchomi main. To reakcja łańcuchowa. Nie musisz tym zarządzać. Po prostu edytujesz kod źródłowy i uruchamiasz make.

A co, jeśli nie korzystam z Uniksa?

Jeśli używasz systemu Windows lub środowiska IDE, takiego jak Visual Studio lub Xcode, możesz nie widzieć pliku „makefile” w tradycyjnym znaczeniu. Nie panikować. Twój kompilator prawdopodobnie ma równoważną funkcjonalność.

Zintegrowane środowiska programistyczne często mają pod maską systemy kompilacji. Poszukaj „Konfiguracji kompilacji” lub „Właściwości projektu”. Robią to samo: śledzą zależności i odbudowują tylko to, co się zmieniło. Ale jeśli będziesz trzymać się wiersza poleceń, „make” będzie standardem.

The bigger picture

Using make is not