FreshSourcing. Čerstvé nápady. Kreatívne riešenia.

» Domov » Auto Tools » 1. časť

1. časť: Úvod

Vitajte v novom seriáli pre programátorov, pri ktorom sa budeme pravidelne stretávať v niekoľkých najbližších číslach PC Revue. Ako už názov napovedá, bude o programe Make a súboroch Makefile. Po tom, čo si toto všetko preberieme, sa pustíme do programov Automake, Autoconf, Configure a ostatných, ktoré vám uľahčia život.

Čo je to Make?

Make je program, bez ktorého si programátori na (prevažne) unixových systémoch nevedia predstaviť život. Ak pracujete na nejakom čo i len trochu väčšom projekte, pravdepodobne je zložený z viacerých súborov. Ak v niektorom z nich urobíte zmenu, musíte dotyčný súbor prekompilovať, a potom zlinkovať s ostatnými skompilovanými súbormi do výsledného programu. Ak však urobíte zmeny vo viacerých súboroch naraz, musíte si zapamätať, v ktorých súboroch ste zmeny urobili. Ešte väčší zmätok urobia závislosti súborov - jeden súbor vyžaduje pre svoj správny beh nejaký iný (či už hlavičkový, alebo zdrojový), ten vyžaduje tiež nejaký súbor atď. - a na konci tejto reťaze urobíte zmenu. V tomto prípade musíte kompilovať všetky súbory, ktoré vyžadujú zmenený súbor. Máte aj druhú možnosť - zakaždým prekompilovať celý programu. Pokiaľ ide o projekt typu Hello, world!, dalo by sa to zvládnuť, ale koľko je takýchto projektov? Teda tadiaľ nevedie správna cesta. Keďže nie sme prví, ktorí majú takýto problém, riešenie sa už našlo. Ako už isto tušíte, volá sa make. Tento program slúži na volanie kompilátora, linkera a ďalších nástrojov. Riadi sa istým súborom, zvaným Makefile. V ňom sú uložené tzv. pravidlá, podľa ktorých sa zostaví výsledný program. No a práve tvorbe týchto súborov sa budeme venovať v prvých častiach nášho seriálu.

Ako to funguje?

Ak chceme používať program make, musíme v adresári projektu vyvoriť súbor makefile, prípadne Makefile, do ktorého uložíme riadiace príkazy - pravidlá. My budeme dávať prednosť názvu s veľkým písmenom. Výhoda je zrejmá: pri výpise obsahu adresára sa súbor nachádza na začiatku - pri iných dôležitých súboroch, napr. README, INSTALL, COPYING, AUTHORS, ChangeLog a NEWS. Keď máme tento súbor vytvorený, tak vždy, keď chceme skompilovať program, stačí napísať príkaz make. Ak používate editor ViM (http://www.vim.org), stačí v príkazovom móde zadať :make. ViM spustí program make, preparsuje jeho výstup, a v prípade chýb vás automaticky presunie v chybnom súbore na chybný riadok. Každý zmenený zdrojový súbor sa prekompiluje. Ak sa zmenil hlavičkový súbor (.h), prekompilujú sa zdrojáky, ktoré ho vkladajú (#include "subor.h"). Tieto udalosti však závisia od súboru Makefile. No a nakoniec, ak bol prekompilovaný ľubovoľný súbor, zlinkujú sa všetky objektové súbory dohromady (objektový súbor je výstupným produktom kompilátora). A ako vie make zistiť, či bol súbor zmenený? Využije čas poslednej zmeny, ktorý porovnáva s časom kompilácie. To však je len hrubý náčrt, ako make funguje. Nemusíme však len kompilovať. Program make sa môže rovnako dobre postarať o dokumentáciu. Ak píšete nejaký text, nech už je vstupným formátom TeX, SGML či Texinfo, môžete si pomôcť pri vytváraní výstuných súborov. Všetko však závisí od spomínaných pravidiel, ktoré sa nachádzajú v danom Makefile.

Pravidlá

V predchádzajúcich riadkoch som viackrát spomenul termín pravidlo. Čo to je? Pravidlo je text, podľa ktorého sa make správa v danej situácii. Pravidlá sa skladajú z cieľa, zdroja a príkazu. V jednom pravidle môže byť naraz viac cieľov, zdrojov, ale aj príkazov. Pravidlo môže vyzerať takto:

cieľ ... : zdroj ...
príkaz
...
Cieľ je súbor, ktorý sa daným pravidlom vytvorí, napríklad výsledná binárka, alebo spomínaný objektový súbor. Zdroj je súbor (súbory), z ktorých sa daný cieľ zostaví. V prípade objektových súborov bude zdrojom samotný zdrojový súbor, napríklad .c. Príkaz je príkaz shellu, ktorý sa spustí za účelom vytvorenia cieľa z daných zdrojov. Musí sa začať znakom "tab"! (to by sa žiadalo zo trikrát podčiarknuť, pretože to zvykne byť častým zdrojom chýb začínajúcich programátorov). Iba tak je možné rozlíšiť cieľ od príkazu. Cieľ má ešte jednu pozoruhodnú vlastnosť: ak by sme spustili program make takýmto spôsobom:
make CIEĽ 
automaticky sa začne pravidlom, ktoré má vytvoriť CIEĽ. Ak ste už niekedy niečo kompilovali, zrejme ste zadali aj príkaz make install. Práve tam sa (okrem iných prípadov) používa spomínaná vlastnosť. Možno vás napadlo, ktorým pravidlom sa začne, ak explicitne nezadáme žiadne pravidlo. Nuž, každý správny Makefile má pravidlo zvané all. Väčšinou sa ním začne samotná kompilácia. Cieľ install má na svedomí kopírovanie súborov, programov atď.

Premenné

Text môže obsahovať aj tzv. premenné, známe z bežných programovacích jazykov. Definujú sa podobne ako v shelli:

PREMENNÁ = hodnota
Používajú sa však mierne odlišne:
$(PREMENNÁ)
Ak sa v súbore bude nachádzať takýto text, bude nahradený jeho hodnotou. Je to veľmi používaná vlastnosť. Pomocou premenných môžete napríklad definovať kompilátor, linkovač atď. Ďalej použijete iba premennú. Ak budete chcieť zmeniť prekladač, stačí ho zmeniť raz (v definícii premennej), ostatné za vás urobí make. Okrem klasických premenných však existujú aj špeciálne premenné, ktoré majú špecifický obsah a zvláštne meno. Používajú sa hlavne pri tvorbe všeobecných pravidiel. Viac si o tom povieme v niektorej z nasledujúcich častí.

Komentáre

Používajú sa podobne ako v shell skriptoch: každý riadok, začínajúci sa znakom #, bude jednoducho ignorovaný. Niekedy sa zíde robiť si poznámky priamo na mieste činu. Ak sa po dlhšom čase vrátite k zložitejšiemu súboru, môže sa stať, že si jednoducho nebudete pamätať, prečo ste daný problém riešili práve tak. A čo ak by mal daný súbor editovať niekto iný? Kým by sa v ňom zorientoval, stihol by napísať aj nový.

Ahoj, svet!

Nedočkavci už iste netrpezlivo čakajú na nejaký príklad. Začneme teda klasickým programom "Ahoj, svet!", ktorý vypíše spomínaný text. Bude sa skladať zo zdrojového súboru ahoj.c a súboru Makefile.

ahoj.c:

#include <iostream>

using namespace std;

int main()
{
cout << "Ahoj, svet!" << endl;
return 0;
}
Dúfam, že nikomu netreba bližšie priblížiť daný súbor. Ťažšie to bude s druhým súborom. Najprv si ho ukážme.
Makefile:

### Nastavenia (kompilátor, linkovač, nastavenia...)

# Kompilátor jazyka C
CC = gcc

### Nastavenia pre samotný projekt

# Názov programu
TARGET = ahoj

# Zdrojové súbory
SRC = ahoj.c

### Pravidlá

# Hlavné pravidlo - skok na pravidlo "ahoj"
all: $(TARGET)

# Pravidlo "ahoj" zostaví program zo zdrojových súborov.
# Závisí, samozrejme, od zdrojových súborov.
$(TARGET): $(SRC)
$(CC) -o $(TARGET) $(SRC)
Ták, to je náš prvý Makefile. Myslíte, že "ručne", teda spustením gcc -o ahoj ahoj.c by to bolo kratšie a rýchlejšie? Máte pravdu, ale iba pokiaľ ide o náš jednoduchý príklad. Už pri dvoch - troch súboroch oceníte výhody make! Teraz si riadok po riadku vysvetlíme význam obsahu súboru Makefile. V prvom riadku nastavíme prekladač ktorý práve používame. Je ním gcc. Skratka CC znamená C Compiler. V ďalšom riadku nastavíme názov výsledného programu. V treťom riadku vymenujeme všetky zdrojové súbory (SRC je skratka slova source(s)). Potom nasledujú pravidlá. Prvé má takýto význam: ak spustíte make bez parametrov, je to to isté, ako keby ste spustili make ahoj. Ďalší riadok zaistí, aby sa program prekompiloval vždy, ak zmeníme niektorý zo zdrojových súborov. V nasledujúcej časti nášho seriálu si ukážeme, ako prikázať programu make, aby prekompiloval iba zmenené súbory a potom ich zlinkoval s ostatnými objektami. V nasledujúcom riadku sa použije definovaný kompilátor, skompiluje všetky zdroje a spojí ich do výsledného súboru ahoj. Tu si môžeme všimnúť výhody použitia premennej SRC namiesto vymenovania súborov - ak pridáme nejaké nové súbory, stačí zmeniť jediný riadok (SRC = ...). Ak zmeníme kompilátor, stačí zmeniť prvý riadok.

Záver

To by bolo nateraz všetko. Nabudúce si preberieme okrem iného aj tvorbu projektov, ktoré sa skladajú z viac ako jedného zdrojového súboru a parametre programu make, ktorými môžete ovplyvniť jeho správanie.


Oto Komiňák


Článok bol uverejnený v magazíne PC Revue 01/2002.