Makefile – HowTo - www.srebniak.pl
Makefile – HowTo
14 listopada 2015
Categories: Linux
Makefile jest plikiem tekstowym, który został stworzony do ułatwienia kompilacji programów. Każdy kto kompilował paczkę z oprogramowaniem pod linuksem nieraz wydawał polecenie „make„. Dziś pokażę jak stworzyć taki plik oraz przedstawię prosty przykład do czego możemy użyć plików makefile.
Jak wspomniałem budowa plików makefile jest bardzo prosta. Reguły mają następujący wzorzec budowy:
CEL: SKLADNIKI
   POLECENIA
„CEL” – oznacza nasz cel, nazwę reguły.

SKLADNIKI – oznacza z czego zbudujemy nasz cel.

„POLECENIA” – określa nam w jaki sposób zbudujemy cel ze składników.
Reguły podstawowe
Pierwszą regułą jest reguła „all” wykonuje się ona po wydania polecenia bez parametru.

Reguła wypisująca prosty tekst:
all:
   @echo "Nasz"
Jeżeli chcemy wykonać kilka reguł wpisujemy nazwy reguł do listy składników.
all: first second
   @echo "drugi tekst"

first:
   @echo "To jest "

second:
   @echo "nasz"
Kompilacja aplikacji pozostawia masę śmiecia do wyczyszczenia folderu możemy użyć reguły „clean„.
#
# Reguła czyści nam strukturę z katalogów używanych przy kompilowaniu.
#
clean:
   rm -rf docs/
   rm -rf runtime/
   rm -rf build/
Aby reguła clean zadziałała poprawnie nie może być katalogu o nazwie reguły.
Dyrektywa .PHONY
W folderze gdzie znajduje się nasz plik Makefile, nie może być katalogów ani plików o nazwach reguł. Aby uniknąć takich problemów możemy dodać kłopotliwą nazwę do reguły .PHONY. Reguła ta mówi co ma być traktowane jak reguła.
.PHONY: clean all docs
Zmienne
Zmienne definiujemy jak w poniższym przykładzie. Make posiada swoje predefiniowane zmienne. Jednak w tym przykładzie pominiemy je.
CC=gcc

hellomake: hellomake.o hellofunc.o
   $(CC) -o hellomake hellomake.o hellofunc.o -I.
Dynamiczne zmienne
Zmienne dynamiczne / automatyczne – są zmiennymi które zmieniają się w trakcie wykonywania reguły.
CC=gcc
CFLAGS=-g
OBJS=hello.o aux.o

hello: $(OBJS)
   $(CC) $(LFLAGS) $^ -o $@

hello.o: hello.c
   $(CC) $(CFLAGS) -c $< -o $@

aux.o: aux.c
   $(CC) $(CFLAGS) -c $< -o $@
< - Aktualny plik z listy składników

@ – Nazwa pliku docelowego

^ – Wkleja listę składników

Powyższy przykład możemy skrócić używając zmiennych dynamicznych z wzorcem:
$(OBJS): %.o: %.c
   $(CC) -c $(CFLAGS) $< -o $@
Kolejne dodanie obiektu do kompilowania naszego programu sprowadza się do dopisania nazwy naszego pliku do zmiennej OBJS
Przykład
Makefile możemy używać np. do prostej automatyzacji wysyłania plików na serwer. W poniższym przykładzie usunąłem zbędne dane, aby nie zaśmiecać niepotrzebnie naszego skryptu.
SRC_DIR=src
DIST_DIR=dist
UPLOAD_DIR=/home/example/public_html/download

all: get_dependency configure compile run

get_dependency:
   sudo apt-get install libxml libjpeg1.0.0
   pip install -r requirements.txt

configure:
   python ./ansible_dynamic_inventory.py > $(DIST_DIR)/config.json

compile:
   pyinstaller $(SRC_DIR)/main.py

run:
   ./$(DIST_DIR)/main

build_pkg:
   make_pkgs.sh

upload:
   scp $(DIST_DIR)/debian_pkgs/*.deb upload@download.example.org:$(UPLOAD_DIR)

clean:
   rm -rf docs/_build
   rm -rf runtime
   rm -rf cermp/cermp/__pycache__

.PHONY: clean all docs
Wydając polecenie „make” uruchamiamy kolejno:
  1. pobieranie i instalowanie zależności
  2. Konfigurowanie aplikacji
  3. Kompilację kodu
  4. Uruchamiamy
Jeżeli nasza aplikacja działa – musimy ją przygotować do publikacji:
$ make build_pkg
Kopiowanie paczek na nasz serwer rozpocznie się po wydaniu polecenia
$ make upload
W razie pytań – służę pomocą
© 2021 Więcej informacji
o mnie