Slovník pojmů

Make

Make popisuje, co má vzniknout, na čem výsledek závisí a jak jej vytvořit. Umí tím řídit klasický inkrementální build, ale může také sjednotit krátké příkazy pro testy, analýzu nebo lokální vývoj.

Stručná definice

Pravidla v Makefile propojí cíle, vstupy a příkazy.

GNU Make čte soubor Makefile a pracuje s pravidly ve tvaru target, prerequisites a recipe. Target neboli cíl bývá soubor, který má vzniknout, prerequisite je jeho vstup nebo jiný potřebný cíl a recipe je sada příkazů, které výstup vytvoří. Make není omezený na C nebo C++; stejný model lze použít pro generování dokumentace, frontendové assety i jiné souborové výstupy.

U souborových cílů Make běžně porovnává časy poslední změny. Pokud cíl chybí nebo je starší než některý prerequisite, spustí recipe. Tím dokáže přestavět jen dotčené části buildu. Make však nezná význam příkazu uvnitř recipe: správné vstupy, výstupy a závislosti musí popsat autor Makefile.

Cíl může místo souboru pojmenovat akci, například test. Takový cíl se označuje jako .PHONY, aby se spustil i tehdy, když v adresáři existuje stejnojmenný soubor. V této podobě Make funguje jako tenká vrstva nad příkazovým řádkem, nikoli jako nový shell, správce balíčků nebo celý CI/CD systém.

Jaký problém řeší

Opakovatelný příkaz a pouze nezbytná práce.

Projekt nemusí po každé změně ručně spouštět všechny kroky ani udržovat dlouhý návod pro každého vývojáře. Make může zachytit závislosti a nabídnout stejné vstupní příkazy lokálně i v automatizaci.

  • sestavení jen těch souborů, jejichž vstupy se změnily
  • jednotné příkazy pro testy, statickou analýzu, generování nebo lokální spuštění
  • vyjádření pořadí mezi úlohami pomocí prerequisites místo ručního řazení kroků
  • skrytí přiměřeného množství přepínačů nástrojů za čitelným projektovým cílem
  • sdílení stejného Makefile mezi vývojářem a CI pipeline
  • paralelní provedení nezávislých recipes, pokud jsou závislosti popsané správně

Praktický příklad

Jednotné příkazy pro testy a statickou analýzu PHP projektu

Tento krátký Makefile nevytváří soubory. Cíle test a analyse proto patří do .PHONY: příkaz make test má spustit PHPUnit pokaždé a nesmí jej zablokovat náhodný soubor pojmenovaný test. Recipe začínají tabulátorem, jak vyžaduje tradiční syntaxe Makefile.

Jde o dokumentační příklad. Make PHPUnit ani PHPStan neinstaluje a projekt je musí mít skutečně dostupné ve vendor adresáři. V reálném repozitáři mají cíle odpovídat jeho vlastním podporovaným kontrolám; samotné přidání názvu do Makefile žádnou kontrolu nevytvoří.

Makefile

.PHONY: test analyse

test:
	php vendor/bin/phpunit

analyse:
	php vendor/bin/phpstan analyse

Jak funguje

Zvolený cíl → závislosti → kontrola aktuálnosti → recipe.

Make prochází graf pravidel od požadovaného cíle. U klasického souborového buildu rozhodují deklarované vazby a timestampy, u phony cíle se záměrně provede akce.

  1. Načtení Makefile Make načte pravidla, proměnné a direktivy. Bez uvedeného cíle obvykle vybere první vhodný target jako default goal, proto má pořadí prvního pravidla praktický význam.
  2. Rozvinutí prerequisites Nejprve vyhledá, co požadovaný target potřebuje. Prerequisite může být existující soubor nebo další target, který se musí vyhodnotit dříve.
  3. Kontrola timestampů Souborový target je zastaralý, pokud neexistuje nebo je starší než některý běžný prerequisite. Make nesleduje obsah automaticky a špatně uvedený vstup proto může vést k neaktuálnímu výsledku.
  4. Spuštění recipe Potřebné příkazy provede shell. Recipe musí při úspěchu opravdu vytvořit či aktualizovat slíbený výstup; Make obsah příkazů ani jejich vedlejší efekty nerozumí.
  5. Výsledek nebo akce Souborový cíl zůstane pro další běh jako doklad aktuálnosti. .PHONY target žádný takový soubor nereprezentuje a při explicitním požadavku se provede znovu.

Hlavní části a koncepty

Makefile je malý deklarativní graf s recipes pro vytvoření cílů.

Nejdůležitější je přesně rozlišit, zda pravidlo modeluje skutečný výstup, nebo jen pojmenovanou akci.

Target

Cíl, o který uživatel nebo jiné pravidlo žádá. Často je to generovaný soubor, ale může jít i o název akce. Target tedy není vždy skutečný soubor.

Prerequisite

Vstup nebo mezikrok, který musí být připraven před targetem. U běžného prerequisite jeho novější timestamp zároveň znamená, že souborový target je potřeba přestavět.

Recipe

Jeden nebo více příkazových řádků, které Make předá shellu. Ve výchozím modelu jsou samostatné řádky recipes spouštěny v samostatných shellech, takže změna adresáře nebo shellová proměnná se bez odpovídajícího zápisu nepřenese automaticky na další řádek.

.PHONY

Speciální deklarace pro targety představující akci. Brání kolizi se stejnojmenným souborem a dává najevo, že se nemá rozhodovat podle existence tohoto souboru.

Proměnné

Pomáhají sdílet příkazy, cesty a přepínače. Mají zůstat čitelné a nemají skrývat, které vstupy mění výsledek nebo jaké prostředí recipe očekává.

Paralelní build

GNU Make může s volbou -j spustit nezávislé recipes souběžně. Je to bezpečné jen tehdy, když graf obsahuje skutečné závislosti a jednotlivé kroky si nekolidují ve výstupech.

Výhody, omezení a časté chyby

Jednoduchý vstup pro tým, ale žádné automatické porozumění projektu.

Konkrétní přínosy

  • timestampový model může výrazně zkrátit build s mnoha skutečnými výstupy
  • krátké cíle sjednotí běžné příkazy napříč lokálním prostředím a CI
  • graf prerequisites umí vyjádřit pořadí i prostor pro paralelní běh
  • Make je zavedený, malý nástroj dostupný v mnoha unixových vývojových prostředích

Omezení a chyby

  • chybějící prerequisite může způsobit použití zastaralého souboru
  • akční target bez .PHONY může přestat fungovat po vzniku stejnojmenného souboru
  • mezery místo požadovaného tabulátoru v recipe vedou k obtížně čitelné syntaktické chybě
  • souběžný běh odhalí skrytou závislost nebo zápis více recipes do stejného výstupu
  • rozsáhlá shellová logika, platformní podmínky a rekurzivní Make mohou zhoršit srozumitelnost
  • GNU Make ani jiné implementace Make nejsou automaticky dostupné na každém operačním systému

Kdy dává smysl

Když projekt potřebuje čitelné cíle nebo skutečný závislostní build.

Make se hodí pro projekt s několika opakovanými příkazy, pokud tým přijme jeho syntaxi a cíle zůstanou tenkou vrstvou. V PHP aplikaci může sjednotit spuštění testů, analýzy, lokálních kontejnerů a dokumentace. CI/CD pak stále řeší runner, oprávnění, secrets, artefakty a podmínky nasazení; Make pouze vykoná část projektových kroků.

U složitého multiplatformního buildu, dynamického grafu nebo rozsáhlého monorepa může být vhodnější specializovaný build systém či nástroj pro orchestraci úloh. Make není package manager: může zavolat Composer, npm nebo Yarn, ale samo neřeší registry, verze balíčků ani lockfile. Shell script je zase přímočařejší pro krátkou čistě sekvenční proceduru bez závislostního grafu.

Na co myslet

Pravidlo musí pravdivě popisovat vstupy, výstup i způsob spuštění.

Makefile je produkční kód automatizace. Jeho úspěch má znamenat totéž na vývojářském stroji i v čistém prostředí.

  • použít .PHONY pro akce, které nevytvářejí soubor stejného jména
  • uvést všechny vstupy, které mohou změnit skutečný souborový výstup
  • udržet recipe krátké a přestat je zvětšovat, pokud se z nich stává obtížně testovatelný program
  • ověřit paralelní běh a nepředpokládat pořadí, které není vyjádřeno prerequisites
  • počítat s rozdíly shellu, cest a dostupných programů mezi podporovanými systémy
  • neskrývat selhání příkazů a v CI spouštět cíle v čistém, verzovaně popsaném prostředí

Časté otázky

Make bez častých záměn

Je Make určený jen pro C a C++?

Ne. Historicky je s kompilací těchto jazyků silně spojený, ale recipe mohou spustit libovolné dostupné příkazy a pravidla mohou modelovat jakékoliv souborové výstupy.

Je každý target soubor?

Ne. Target často představuje soubor, ale může pojmenovat i akci. Pro akční cíle jako test nebo analyse se používá .PHONY, aby se neposuzovaly podle stejnojmenného souboru.

Jak se Make liší od shell scriptu?

Shell script typicky popisuje sekvenci příkazů. Make navíc modeluje cíle a jejich prerequisites, rozhoduje, co je zastaralé, a může nezávislou práci spustit paralelně; vlastní recipes ale obvykle stále vykonává shell.

Nahrazuje Make package manager nebo CI/CD?

Ne. Může spustit instalaci nebo kontrolu, ale neřeší správu balíčků, registry, CI runner, oprávnění, secrets ani deployment workflow.

Proč se recipe někdy nespustí?

Souborový target může být podle timestampů aktuální nebo může existovat soubor se jménem akčního targetu. Je potřeba ověřit deklarované prerequisites a u akce správně použít .PHONY.

Jak pracuji s automatizovanými kontrolami

Projektové příkazy mají být opakovatelné a srozumitelné i v CI.

U PHP projektů propojuji testy, statickou analýzu a další quality gates tak, aby vývojář i automatizace spouštěli stejné ověřené kroky.

Zavolejte mi

Zavolám vám následující pracovní den mezi 9:00 a 17:00.

Můžete mi také zavolat rovnou.

+420 605 181 728

Nechte mi telefonní číslo a pošlete žádost o zpětné zavolání.

Odesláním souhlasíte se zpracováním údajů pro vyřízení žádosti.