Operační systém UNIX a jazyk C

Jan Brodský
Luděk Skočovský

SNTL Nakladatelství technické literatury Praha 1989, ISBN 80-03-00049-1

5. Programovací jazyk C


5.8 Kompilace programu

Kompilátory jazyka C existují snad pro všechny počítače a operační systémy, většinou ve více verzích. Přesný postup kompilace závisí jak na počítači, tak na operačním systému, i na variantě kompilátoru. Popíšeme nyní implementaci kompilátoru cc Unixu.

5.8.1 Kompilátor cc

Kompilátor cc (c-compiler) rozeznává několik typů souborů a vyžaduje jejich rozlišení smluvenými příponami jmen (čl. 2.2):

PříponaTyp souboru
.czdrojový program v jazyce C
.hhlavičkový soubor pro #include
.izdrojový program zpracovaný makroprocesorem
.sprogram v asembleru
.osestavovaný modul programu

Program cc v závislosti na požadavcích uživatele vyvolává další programy - součásti kompilátoru. Jsou to makroprocesor, kompilátor (s částí pro analýzu, částí pro generování kódu a volitelným optimalizátorem kódu), asembler a konečně sestavující program (obr. 5.3).

[OBR. 5.3]

Příkazem pro shell


$ cc prog.c
$
zadá uživatel kompilaci zdrojového programu v souboru prog.c. Výsledkem kompilace je soubor s implicitním jménem a.out, který obsahuje program ve výkonné podobě. Jeho provedení si vyžádá příkazem

$ a.out
$
Vyzkoušejte si to např. na programu ze souboru pozdrav.c:
main()
{
#ifdef ENGLISH
printf("Good morning!\n");
#else
printf("Dobry den!\n");
#endif
}

5.8.2 Volby kompilátoru

Kompilátoru lze však zadat řadu voleb, klíčů. Některé z nich způsobí, že se kompilace neprovede úplně, ale skončí v některé fázi. Tak např. klíčem -t si uživatel vyžádá, aby zdrojový text zpracoval jen makroprocesor a výsledek zanechal v souboru prog.i.

Jiné klíče jsou určeny pro sestavující program. Např. -o jméno udává jméno souboru, do něhož bude uložen výkonný program (místo a.out).

Klíčem -D můžeme v etapě kompilace definovat identifikátor; tak např. aktivací kompilátoru


$ cc -DENGLISH -t pozdrav.c
$
získáme soubor pozdrav.i s obsahem
main()
{
printf("Good morning!\n");
}

Příkazem


$ cc -o pozdrav pozdrav.c
$
získáme soubor pozdrav, který aktivován vypíše na obrazovce terminálu

$ pozdrav
Dobry den!
$

Vstupem do každé fáze činnosti kompilátoru může být více souborů. Kompilátor podle přípon jejich jmen pro každý soubor zvolí část kompilátoru, v níž má zpracování souboru zahájit. Začne pak jednotlivé části kompilátoru provádět. Není-li řečeno jinak, vytváří v pracovním adresáři soubor a.out s výkonným programem. Je-li rozsáhlejší program vytvářen z více částí, je nejlepší uchovávat všechny jeho části (a jen je) v jediném adresáři. V kontextu tohoto adresáře lze pak jediným příkazem


$ cc *.c
$
zkompilovat všechny části programu najednou. Výsledný program bude v tomto případě umístěn v souboru a.out. Další diskuse tvorby rozsáhlých programů je v kap. 6.

5.8.3 Sestavující program, aktivace programu

Sestavující program je součástí operačního systému, nikoliv jazyka. Přesto má vliv na programy psané v jazyku C. Platí to zejména o jménech externích objektů (funkcí), která musí vyhovovat konvencím použitého sestavujícího programu. Jde např. o počet znaků identifikátorů a možnost rozlišit mezi velkými a malými písmeny.

Výsledek sestavení, tj. výkonný program, silně závisí na operačním systému. Rovněž způsob předání argumentů, zadávaných při aktivaci programu, se bude v různých systémech lišit. Předávání argumentů v Unixu ukážeme na příkladě programu příkazu echo. Tento příkaz na terminálu opisuje zadané argumenty. Program echo v jazyku C pro Unix může vypadat např. takto:

main(argc, argv)
int argc; char *argv[];
{
	while(--argc)
		printf("%s%c", *++argv, (argc>1)?' ':'\n');
}

V proměnné argc program echo obdrží počet argumentů příkazu, argv je pole ukazatelů na řetězce argumentů. Argument číslo nula vždy podle konvence obsahuje jméno příkazu, tedy argc je vždy alespoň 1. Pro aktivaci

$ echo abcd xyz
abcd xyz
$
je argc = 3, *argv[0] = "echo", *argv[1] = "abcd", *argv[2] = "xyz".