Może się już z tym spotkałeś, wielokrotnie uzywałeś ale jeżeli jeszcze nie to zerknij jak możesz sobie to ułatwić. Zawsze gdy rozwijasz oprogramowanie, zarządzasz procesem kompilacji i budowania może to stać się kłopotliwe. Zwłaszcza w przypadku dużych projektów z wieloma plikami źródłowymi. W takich sytuacjach narzędzie o nazwie Makefile staje się nieocenione.
Czym jest Makefile?
To plik tekstowy zawierający instrukcje dotyczące procesu kompilacji i budowania projektu. Jest to skrypt, który przekazuje polecenia do narzędzia Make, które następnie wykonuje odpowiednie akcje w celu zbudowania programu z plików źródłowych. Opisuje on zależności między różnymi plikami źródłowymi oraz instrukcje dotyczące sposobu kompilacji i linkowania tych plików.
To narzędzie jest często również używane dla wygodnego uruchamiania komend dla projektu.
Dla przykładu w projekcie symfony możesz zdefiniować sobie:
# Czyszczenie cache w Symfony clear-cache: php bin/console cache:clear # Odpalenie kolejek RabbitMQ run-rabbitmq: php bin/console messenger:consume async -vv
W powyższym przykładzie, komenda clear-cache
odpowiada za czyszczenie cache w Symfony za pomocą polecenia php bin/console cache:clear
. Natomiast komenda run-rabbitmq
uruchamia kolejki RabbitMQ przy użyciu polecenia php bin/console messenger:consume async -vv
.
Możesz teraz użyć tych komend w terminalu, wykonując make clear-cache
lub make run-rabbitmq
odpowiednio.
Uwaga! Upewnij się, że plik Makefile znajduje się w katalogu głównym Twojego projektu Symfony.
Po co używać Makefile?
Zdecydowanie upraszcza to proces budowania projektów poprzez automatyzację zadań związanych z kompilacją, co prowadzi do oszczędności czasu i eliminacji błędów ludzkich.
Pozwoli Ci to się skupić się na tworzeniu kodu, a nie na ręcznym zarządzaniu procesem kompilacji. Dodatkowo tak jak wspomniałem wyżej możesz sobie ułatwić podczas uruchamiania komend zarówno pod środowisko testowe, developerskie jak i produkcyjne.
Przykłady Zastosowania Makefile
Projekt C/C++: W projekcie C/C++ można użyć make do kompilacji plików źródłowych (np. .c lub .cpp) oraz do linkowania ich w celu utworzenia końcowego wykonywalnego pliku.
CC = gcc CFLAGS = -Wall -O2 program: main.o utils.o $(CC) $(CFLAGS) -o program main.o utils.o main.o: main.c $(CC) $(CFLAGS) -c main.c utils.o: utils.c $(CC) $(CFLAGS) -c utils.c
Projekt Python: Nawet w projekcie Pythona make może być używany do zarządzania środowiskiem wirtualnym i zależnościami.
install: python -m venv venv . venv/bin/activate && pip install -r requirements.txt run: . venv/bin/activate && python main.py
Składnia
Przykładowy plik z make składa się z reguł, z których każda definiuje sposób budowania jednego lub więcej plików wynikowych. Reguły zazwyczaj składają się z trzech elementów:
- Cel (Target): Plik wynikowy lub zadanie, które ma być wykonane.
- Zależności (Dependencies): Lista plików, od których zależy cel.
- Polecenie (Command): Komenda, która ma zostać wykonana w celu utworzenia celu.
Czym jest Phony?
Domyślnie cele w make są traktowane jako cele „plikowe”, co oznacza, że służą one do budowania plików z innych plików.
Jednak czasami chcemy, aby make uruchamiał polecenia, które nie odnoszą się do fizycznych plików. Dobre przykłady to popularne cele „clean” i „all”. Jednak może się zdarzyć, że istnieje plik o nazwie „clean” w głównym katalogu.
W takim przypadku Makefile byłby zdezorientowany, ponieważ domyślnie cel „clean” byłby powiązany z tym plikiem, a Make uruchomiłby go tylko wtedy, gdy plik nie wydaje się być aktualny względem swoich zależności.
Cele specjalne tego rodzaju nazywane są „phony”, i można wyraźnie powiedzieć Makefile, że nie są one związane z żadnymi plikami, na przykład:
.PHONY: clean clean: rm -rf *.o
Teraz make clean zostanie uruchomione zawsze, nawet jeśli masz plik o nazwie „clean”.
W kontekście make cel „phony” jest po prostu celem, który zawsze jest przestarzały, więc za każdym razem, gdy używasz make <cel_fony>, zostanie on uruchomiony, niezależnie od stanu systemu plików. Niektóre powszechne cele make, które często są „phony”, to: all, install, clean, distclean, TAGS, info, check.
Składnia z Argumentami
Makefile może również przyjmować argumenty, co czyni go jeszcze bardziej elastycznym i przydatnym narzędziem. Argumenty te mogą być wykorzystywane do dostosowywania procesu budowania w zależności od potrzeb użytkownika.
Przekazywanie Argumentów
Argumenty są przekazywane do Makefile jako zmienne środowiskowe, które można następnie odczytać i wykorzystać wewnątrz pliku.
# Przykład Makefile z argumentami build: @echo "Kompilacja z opcjami: $(OPTIONS)" $(CC) $(OPTIONS) -o program main.c
Wywołanie Makefile z Argumentami
Makefile można wywołać, przekazując wartości zmiennych jako argumenty.
make build OPTIONS="-Wall -O2"
W tym przykładzie, opcje kompilatora, takie jak „-Wall” (włączanie wszystkich ostrzeżeń) i „-O2” (optymalizacja kodu na poziomie 2), są przekazywane do Makefile jako wartość zmiennej „OPTIONS”.
Wykorzystanie argumentów w Makefile umożliwia dynamiczne dostosowywanie procesu budowania projektu do różnych potrzeb i scenariuszy. Dzięki temu programiści mogą łatwo kontrolować sposób kompilacji i dostosowywać go do wymagań swoich projektów.
Podsumowanie
Makefile to potężne narzędzie do zarządzania procesem kompilacji i budowania projektów programistycznych. Jeżeli chcesz poznać więcej możliwości makefile to sięgnij do dokumentacji makefile. Używanie Makefile może znacząco usprawnić pracę programisty, zapewniając automatyzację zadań związanych z budowaniem oprogramowania.
Fajny artykuł, przydałoby się więcej przykładów zaawansowanych z PHP Symfony. Dodatkowo jak uruchamiać całe projekty przez make.