De c compiler
We
zullen beginnen met het compileren van de simpele versie van het
historische algoritme van "B. W. Kernighan and D. M.
Ritchie" gepubliceerd in "The C Programming
Language"
#include <stdio.h>
int main (int argc, char *argv[]) {
printf ("Hello world\n");
return (0);
}
We kunnen hier een programma van maken met behulp van de C
compiler. Die zorgt er dan voor dat deze door mensen leesbare tekst
omgezet wordt in computer instructies die met een redelijk grote
efficientie uit gevoerd kunnen worden. Het commando daar voor is
"cc -o hello hello.c
". Hierna hebben we een programma
dat we kunnen draaien.
Eigenlijk pakken we hier zelfs 2 stappen samen. Wat we
eigenlijk doen met deze opdracht is het compileren van
"hello.c
tot een objectfile. Daarna gebruiken we de
link editor ld om de initialisatie code, de libaries en
onze code aan elkaar te plakken tot een programma.
Grote programma's worden vaak verdeeld over
meerdere c files. Deze c files kunnen dan afzonderlijk
gecompileerd worden en later aan elkaar gelinkt worden.
Binnen de taal C
kunnen we een hoop functies aanroepen die we gelijk kunnnen
gebruiken zonder dat we hoeven te vertellen wat er in die
functies moet gebeuren. Dat komt omdat er een hoop functies in de
diverse libries zitten. De standaard librie libc wordt
altijd mee gelinkt. Daar zitten functies zoals
printf
in die tekst naar het scherm schrijven.
Een groot aantal libries worden echter niet automatisch mee
gelinkt. Als je gebruik van die libries wilt maken dan moet je
dat expleciet opgeven. Het gaat daarbij bij voorbeeld om libaries
die iets doen met X zoals libX11. Je kunt deze extra libries mee
linken tijdens de link slag.
Omdat de
c compiler moet weten welke functies er in een librarie
zitten worden deze beschreven in de zogenaamde header files. In
deze header files staan de beschrijvingen van de functies die
gebruikt kunnen worden binnen een librarie. Voor de rest worden
er macro's en constanten gedefineerd die het gebruik van de
librarie gemakelijk moeten maken.
Bij
compileren worden de C files om gezet in zogenaamde object files.
Het compileren van afzonderlijke 'c' files gaat via de
-c optie van de meeste compilers.
In de eerste slag van de compilatie word de pre processing
gedaan. Dat wil zeggen dat de 'c' files samengevoegt worden met
de header files en eventueele extra defines. Daarna worden de
defines ingevult en de macros geexpandeerd.
In dit stadium wordt vaak de selectie gemaakt welk stuk code
tussen de diverse #ifdef doorlopen worden. Een voorbeeld
hiervan is:
#ifdef LINUX
printf ("Yep it's linux\n");
#else
printf ("Nop it's some stupid OS\n");
#endif
Als nu ergens in de header files (of op de commandline met
-DLINUX) linux gedefineerd wordt dan zal deze code braaf
"Yep it's linux" printen. Op deze manier wordt vaak os
depend code effient opgelost want de overige code wordt gewoon
genegeerd.
In de link slag
worden alle object files samen gevoegt met de libries tot een
programma. Het kan zowel om shared als archive libries gaan. De
default is om de shared libries te gebruiken. Dat wil zeggen dat
het programma runtime de functies haalt uit librarie die dan op
het systeem staat. Het voordeel hiervan is dat die librarie dan
maar een keer in het geheugen hoeft te zitten voor alle
programma's.
De archive libries zijn libries waar alle functies in zitten
die vervolgens tijdens het linken naar het programma gecopieerd
worden. Hierdoor wordt het programma aanzienlijk groter (zowel op
disk als tijdens het draaien). Het heeft echter als voordeel dat
het programma niet afhankelijk is van de aanwezigheid van
correcte shared libries.
Hier
zien we hoe eerst een c file gecompileerd wordt waarna dit c file
gelinkt wordt aan de diverse X Libries.
# gcc -O -c Xexit.c
# gcc -o Xexit Xexit.o -L/usr/X11R6/lib -lXt -lXaw -lX11
Uiteraard is het mogenlijk om eerst meerdere c files te
compileren en dan op de link regel ook meerdere object files aan
elkaar te linken.
De compilatie vlaggen
- -g
- Compileer debug informatie mee. Hierdoor kun je het
programma eventueel regel voor regel tracen met b.v. gcc.
- -O[0-6]
- Optimaliseer de c code. Met deze optie wordt geprobeerd Het
programma sneller te laten lopen door het te
optimaliseren.
- -D<MACRO>=<WAARDE>
- Defineer dat een macro een bepaalde waarde heeft. Vaak
wordt Dit gebruikt om aan te geven welk systeem het is. Dan zie
je b.v. -DLINUX. Daarmee is linux gedefineerd en loopt de
compilatie goed door de diverse #ifdef.
- -I<path>
- Zoek in het opgegeven path naar de include files.
De link vlaggen
- -l<librarie naam>
- Link deze librarie mee
- -L<path>
- Zoek in het opgegeven path naar de libries.