| Termin | Definicja |
|---|---|
| Makefile | Makefile to plik konfiguracyjny narzędzia make definiujący reguły kompilacji projektu — powszechny w środowiskach programistycznych Linux/Unix. Makefile jako opis procesu budowania projektuMakefile jest tekstowym plikiem używanym przez narzędzie make do opisywania czynności potrzebnych przy przygotowaniu programu, biblioteki albo innego projektu do uruchomienia. Nie jest to zwykła lista poleceń wykonywanych zawsze w tej samej kolejności. Jego głównym zadaniem jest zapisanie zależności pomiędzy plikami oraz wskazanie, jakie polecenia należy uruchomić, gdy określony element projektu nie istnieje albo został zmieniony. Dzięki temu możliwe jest ponowne zbudowanie tylko tych części, które rzeczywiście wymagają aktualizacji. W typowym Makefile występują cele, zależności i reguły. Cel może oznaczać gotowy program, bibliotekę, plik obiektowy, paczkę instalacyjną albo czynność pomocniczą, taką jak wyczyszczenie katalogu wynikowego. Zależności określają, od jakich plików lub innych celów zależy dany rezultat. Reguła zawiera polecenia powłoki, które prowadzą do jego utworzenia. Przykładowa struktura może wyglądać następująco:
W tym zapisie Makefile w kontekście kompilacji i zależności plikówZnaczenie Makefile najlepiej widać w większym projekcie, w którym kod źródłowy jest podzielony na wiele modułów. Bez systemu reguł każda zmiana mogłaby wymagać ręcznego uruchamiania rozbudowanego zestawu poleceń. Narzędzie make porównuje znaczniki czasu plików i ustala, czy cel jest starszy od swojej zależności. Jeżeli plik źródłowy został zmieniony po utworzeniu odpowiadającego mu pliku obiektowego, wykonywana jest właściwa reguła kompilacji. Jeżeli nic się nie zmieniło, zbędna praca jest pomijana. Makefile może rozdzielać kompilację na dwa etapy. Najpierw pliki źródłowe, na przykład zapisane w języku C lub C++, są zamieniane na pliki obiektowe. Następnie obiekty są łączone w jeden program albo bibliotekę. Takie podejście skraca kolejne kompilacje i ułatwia wykrywanie miejsca, w którym pojawił się problem. Warto jednak pamiętać, że klasyczne sprawdzanie dat plików nie zawsze rozpoznaje wszystkie zmiany. Przy nietypowych procesach generowania kodu, zmianie parametrów kompilatora albo przełączaniu gałęzi projektu pomocne może być ręczne wykonanie celu czyszczącego i pełna budowa. W Makefile często stosuje się zmienne, aby nie powtarzać tych samych wartości. Można w nich przechowywać nazwę kompilatora, opcje ostrzeżeń, katalog plików wynikowych lub listę bibliotek. Zmienne zwiększają czytelność i pozwalają zmienić sposób budowania bez edytowania każdej reguły. W projektach przenośnych powinno się unikać założeń właściwych tylko dla jednego systemu, takich jak bezpośrednie używanie określonych ścieżek, narzędzi lub składni powłoki. Alternatywą dla Makefile mogą być systemy budowania generujące pliki wynikowe na podstawie dodatkowej konfiguracji, narzędzia zintegrowane ze środowiskiem programistycznym albo rozwiązania przeznaczone dla konkretnego języka. Makefile pozostaje jednak prosty, dostępny na wielu platformach i łatwy do uruchomienia z poziomu terminala. W porównaniu z ręcznym wpisywaniem poleceń oferuje automatyzację, a w porównaniu z rozbudowanymi systemami projektowymi często wymaga mniejszej liczby plików pomocniczych. Makefile i typowe problemy podczas używaniaJednym z najczęstszych problemów z Makefile jest nieprawidłowe wcięcie polecenia. Reguła wymaga tabulatora na początku linii wykonawczej, dlatego edytor automatycznie zamieniający tabulatory na spacje może uniemożliwić uruchomienie budowania. Objawem bywa komunikat o braku separatora. W takiej sytuacji należy sprawdzić niewidoczne znaki w edytorze oraz ustawienia formatowania. Inna grupa błędów wynika z niekompletnych zależności. Jeżeli plik źródłowy korzysta z nagłówka, lecz nagłówek nie został wpisany do reguły, zmiana tego nagłówka może nie spowodować ponownej kompilacji odpowiednich modułów. Rozwiązaniem jest jawne utrzymywanie zależności albo użycie możliwości kompilatora, który sam generuje pliki zależności. W większych projektach przydatne bywa także oddzielenie plików obiektowych i wyników od kodu źródłowego, ponieważ ułatwia to czyszczenie oraz kontrolę zawartości katalogu. Problemy może powodować również różnica pomiędzy powłoką używaną przez autora Makefile a powłoką dostępną na innym komputerze. Polecenie działające w jednym środowisku może nie istnieć w innym albo może mieć inną składnię. Dotyczy to zwłaszcza operacji na plikach, zmiennych środowiskowych i poleceń łączonych operatorami powłoki. Warto ograniczać reguły do przenośnych poleceń, jasno dokumentować wymagane narzędzia i unikać polegania na przypadkowych ustawieniach lokalnego systemu. Do nieporozumień prowadzą także cele pozorne, nazywane często celami pomocniczymi. Cel taki nie reprezentuje rzeczywistego pliku, lecz jedynie czynność, na przykład usunięcie plików wynikowych. Jeśli nazwa celu pokrywa się z nazwą istniejącego pliku, narzędzie może uznać zadanie za aktualne i pominąć jego wykonanie. Deklaracja celu pozornego informuje, że nazwa ma być traktowana jako polecenie, a nie jako ścieżka do rezultatu. Przydatne jest również rozdzielenie celów budowania, testowania, instalowania i czyszczenia, aby każda czynność miała jasne zastosowanie. Makefile w praktycznej organizacji pracy programistycznejPrzed utworzeniem Makefile warto opisać proces budowania zwykłymi poleceniami uruchamianymi ręcznie. Pozwala to ustalić, jakie pliki powstają, które narzędzia są wymagane i w jakiej kolejności wykonywane są działania. Dopiero potem można przełożyć te czynności na reguły. Takie podejście ogranicza ryzyko zapisania automatyzacji, która ukrywa błędy albo przypadkowo wykorzystuje stare pliki wynikowe. Dobry Makefile powinien mieć jeden łatwy do znalezienia cel domyślny oraz nazwy celów opisujące ich przeznaczenie. Pomocne jest dodanie celu pokazującego dostępne operacje, szczególnie gdy projekt będzie używany przez kilka osób. Komentarze powinny wyjaśniać nietypowe decyzje, wymagania dotyczące narzędzi i powody zastosowania określonych flag. Nie ma potrzeby komentowania każdej oczywistej linijki, lecz warto opisać elementy, których usunięcie mogłoby zmienić sposób kompilacji. Warto także rozdzielić ustawienia zależne od komputera od głównej logiki pliku. Lokalny użytkownik może potrzebować innego katalogu instalacyjnego, odmiennego kompilatora albo dodatkowych opcji diagnostycznych. Takie wartości można przekazywać przy uruchomieniu make lub przechowywać w osobnym pliku, którego nie dodaje się do wspólnego repozytorium. Należy zachować ostrożność przy przekazywaniu danych pochodzących z zewnątrz, ponieważ część wartości może zostać użyta jako fragment polecenia powłoki. Makefile może również uruchamiać testy, analizę statyczną, formatowanie kodu i tworzenie archiwów. Nie oznacza to, że wszystkie czynności powinny być połączone w jedną nieprzejrzystą regułę. Czytelniejszy jest zestaw mniejszych celów, które można uruchamiać osobno albo grupować w celach zbiorczych. Dzięki temu łatwiej ustalić, czy problem pojawił się w kompilacji, testach, pakowaniu czy przygotowaniu plików do wdrożenia. Jeżeli projekt przestał się budować po zmianie systemu, aktualizacji narzędzi lub przeniesieniu na inny komputer, należy najpierw odtworzyć dokładny komunikat błędu. Pomocne jest sprawdzenie wersji kompilatora, obecności wymaganych programów, wartości zmiennych środowiskowych i zawartości katalogu wynikowego. Pełne czyszczenie i ponowne budowanie powinno być wykonane dopiero po zabezpieczeniu lokalnych zmian, ponieważ niektóre reguły czyszczące usuwają wygenerowane pliki. Makefile a moment zgłoszenia problemu do serwisuNie każdy błąd zgłaszany podczas pracy z Makefile oznacza uszkodzenie sprzętu. Często przyczyną jest brak biblioteki, niezgodna wersja kompilatora, literówka w ścieżce, niewłaściwe wcięcie albo niepełna konfiguracja środowiska programistycznego. W takich przypadkach przydatne jest zachowanie komunikatu błędu, informacji o używanym systemie oraz fragmentu reguły, która została uruchomiona. Ułatwia to odróżnienie problemu z projektem od kłopotu z komputerem. Do serwisu warto zgłosić się wtedy, gdy problemy z budowaniem powtarzają się mimo poprawnej konfiguracji, komputer samoczynnie się wyłącza, zawiesza podczas kompilacji, przegrzewa się, wydaje nietypowe odgłosy albo wykazuje niestabilność także poza środowiskiem programistycznym. Znaczenie może mieć również uszkodzenie dysku, pamięci operacyjnej lub układu chłodzenia, ponieważ długotrwała kompilacja obciąża podzespoły w sposób bardziej wymagający niż proste korzystanie z przeglądarki. W Warszawie takie objawy można skonsultować z firmą Warszawskie Pogotowie Komputerowe 24/7, która zajmuje się serwisem laptopów i komputerów PC. Przed przekazaniem urządzenia należy przygotować opis objawów, wskazać, czy problem występuje tylko przy jednym projekcie, oraz zabezpieczyć kod i inne ważne dane. Sam Makefile nie powinien być traktowany jako zamiennik dokumentacji procesu budowania. Jasno opisane wymagania, wersje narzędzi i sposób uruchamiania celów skracają diagnozowanie zarówno problemów programowych, jak i sytuacji, w których źródłem kłopotu okazuje się sprzęt. |