Programmeringssproget C og UNIX har traditionelt været tæt knyttet til hinanden, og dette gælder i høj grad også for Linux. Kernen og langt de fleste applikationer er skrevet i C.
GNU C/C++ er en af de allerbedste oversættere på markedet i dag. I modsætning til Windows-verdenen er oversætteren ikke indkapslet i en grafisk brugergrænseflade. Det giver større frihed for den enkelte til at sammensætte et personligt udviklingsmiljø - enten grafisk eller tekstbaseret. Med lidt tilvænning er det også hurtigt at anvende, specielt hvis der skal oversættes meget kode per gang. Der er også den store fordel, at det er standard inden for UNIX-verdenen, hvorfor kode og kompileringsfiler (makefiles) uden problemer kan flyttes, oversættes og eksekveres på andre typer af UNIX-systemer.
Per tradition er HelloWorld-programmet det første C-program, man skal få til at virke. Programmet skriver en kort tekst (normalt "Hello World", men i dette tilfælde en lidt mere relevant besked) ud på skærmen og afslutter. Indtast følgende (brug emacs, pico eller vi), og gem det som hello.c.
#include <stdio.h> int main(void) { printf("Linux er sjovt\n"); return 0; } |
I kataloget, hvor filen er gemt, kan programmet nu oversættes ved at skrive
[daisy@linus daisy]$ gcc -o hello hello.c |
C-oversætteren hedder gcc. Den skal her lave en eksekverbar fil med navnet hello, og den skal oversætte og linke ud fra kildeteksten i hello.c.
Det oversatte C-program hello køres ved at skrive navnet i en xterm. For dem, som har C-erfaring, kommer der et par tips nu. En lille sjov ordre er at skrive
[daisy@linus daisy]$ nm hello |
[daisy@linus daisy]$ ldd hello libc.so.6 => /lib/libc.so.6 (0x40003000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00000000) |
At den eksterne funktion printf rent faktisk kommer fra libc, kan ses ved at skrive
[daisy@linus daisy]$ nm /lib/libc.so.6 | grep "printf" |
Det var lidt om dynamisk link. Ideen er, at programmet kun indeholder de nødvendige dele. Under udførelsen af programmet bruges nogle af de nævnte eksterne biblioteker. Koden kan også oversættes med alle eksterne funktioner - linket statisk ind.
[daisy@linus daisy]$ gcc -o hello hello.c -static |
Bemærk ændringen i filstørrelsen (fra ca. 4 kbytes til over 400 kbytes). Nu vil ldd hello vise, at der ikke er eksterne biblioteker nødvendige for at køre programmet. Nu tilbage til lidt mere simple eksempler.
I følgende enkle eksempel ønskes et program, der indlæser to tal, finder det største af de to og skriver dette ud. Omkring C/C++ programmering kan henvises til en af de mange standardbøger om C og C++. Koden er ikke det primære, men kunne se således ud.
#include <iostream.h> void read2(int&,int&); void writeMax(int); int main() { int val1,val2,maxVal; read2(val1,val2); maxVal = (val1>val2)?val1:val2; writeMax(maxVal); return 0; } void read2(int& v1,int& v2) { cout << "Indtast to heltal "; cin >> v1 >> v2; } void writeMax(int val) { cout << val << " er det største tal\n"; } |
Oversættelse kan ske med en såkaldt makefile, men her sker det ved direkte at kalde oversætteren.
[daisy@linus daisy]$ g++ eks1.c++ -o eks1 |
[daisy@linus daisy]$ echo "g++ $1.c++ -g -lm -o $1" > mycompile |
[daisy@linus daisy]$ chmod a+x mycompile |
[daisy@linus daisy]$ mycompile FILNAVN |
Det antages, at kildefilen hedder FILNAVN.c++, og den eksekverbare fil kommer til at hedde FILNAVN.
Næste eksempel er to filer, hvor den ene kalder funktioner i den anden. I eksemplet, der er C-kode, er det igen det største af to tal, der skal findes og skrives ud.
Følgende fil kan gemmes som ceks2.c.
#include <stdio.h> #include <math.h> float v1,v2,retval; float max(float,float); int main(void) { v1=sin(2.34); v2=tan(4.4); retval=max(v1,v2); printf("Af %f og %f er %f stoerst\n",v1,v2,retval); return 0; } |
Følgende fil kan gemmes som cfkt.c.
float max(float f1,float f2) { float f3; if (f1>f2) f3=f1; else f3=f2; return f3; } |
Koden kan oversættes ved hjælp af GNU C-oversætteren gcc. Brug man gcc for at få hjælp de mange muligheder.
[daisy@linus daisy]$ gcc -o ceks2 ceks2.c cfkt.c -lm |
En langt mere elegant metode er at lave en makefile. Herefter skrives blot make, og C-oversætteren vil kun oversætte de filer, der er nye i forhold til objektfilerne. Makefiles kan også anvendes til at styre oversættelse generelt såsom af LaTeX-kode. En makefile (med navnet Makefile) kunne være følgende.
# Makefile til GNU C-oversætteren - dette er en kommentar # I dette eksempel oversættes to filer. # ceks2.c og cfkt.c oversættes til exefilen ceks2 # Navn paa oversaetter = gcc CC = gcc # Navn paa eksekverbar fil OUTPUT = ceks2 # Kilde fil navne sources = ceks2.c \ cfkt.c # Automatisk navngivning af objektfiler, hvor .c bliver til .o OBJS = $(sources:.c=.o) # Compilerflag: Maximal optimering -O2 og debug information -g CFLAGS = -O2 -g #Linkerflag: Inkluderer math-bibliotek med -lm !!!! LDFLAGS = -lm # Foelgende linje checker om en .o fil er nyere end den eksekverbare fil. Hvis # dette er tilfaeldet, linkes disse. Dvs. kun nye elementer oversættes. $(OUTPUT): $(OBJS) $(CC) $(CFLAGS) -o $(OUTPUT) $(OBJS) $(LDFLAGS) |
Bemærk, at der skal stå en tabulator foran de linjer, der skal eksekveres, såsom den sidste. Der må ikke anvendes mellemrum.
Når makefilen er skrevet, kan programmet oversættes ved at skrive
[daisy@linus daisy]$ make |
Til GNU C/C++ findes en tekst-baseret debugger (gdb), som virker fint sammen med oversætteren. Hvis alle filer er oversat med flaget -g, kan man kalde debuggeren ved at skrive gdb FILNAVN, hvor FILNAVN er navnet på den eksekverbare fil.
Man kan vise (display) enkelte variable eller strukturer. Du kan sætte breakpoints og meget andet, men det hele er tekstbaseret. Programmet gdb kan med fordel kaldes fra editoren Emacs ved at skrive Meta-x gdb (Meta=Alt). Så fås en delt skærm med debugger og kode, der kører sammen. Du kan i en xterm skrive man gdb for at få muligheder for debuggeren. Ved fejl kan det anbefales at oversætte kode uden optimering, dvs. fjern -O2 ved oversættelse, idet man således ikke får fjernet overflødige variable og lignende, som så ikke kan vises med debuggeren.
Ønsker du at anvende en grafisk debugger, kan du med fordel installere ddd, der anvender gdb, men giver en fuldt professionel grafisk brugerflade til debugging af C, C++, Java og Fortran kode. Specielt lækkert er, at man nemt kan følge indholdet af strukturer, tabeller og simple variable. DDD kan downloades fra http://www.cs.tu-bs.de/softech/ddd
Der er ved at komme integrerede udviklingsmiljøer til Linux, som det kendes fra f.eks. Visual C++ til Windows. Man kan købe Code Warrior til Linux og projekter Code Crusader er også godt på vej (men Code Crusader er ikke så godt designet).
Et spændende helt nyt program er KDevelop til KDE.
Ambitionsniveauet er meget højt, og til trods for at det er den første beta version, som er blevet testet her, så ser det positivt ud.Som det ses på Figur 8-3, så er der der ligheder med Visual C++ fra Microsoft. Man kan nemt overskue alle filer, klasser, strukturer og variable i projektet. Der er god support for at oversætte, debugge (ser det ud til), og revisionskontrol er direkte integreret. Dette er baseret på CVS. Der er mulighed for integreret dokumentationsmuligheder baseret på SGML.
En ting, som er et meget stort plus ved KDevelop i forhold til Visual C++ er at alle projekt filer er tekst-baserede, dvs. man kan se alt med en almindelig tekst-editor og rette hvis man har noget specielt, der skal ind. KDevelop laver i øvrigt selv standard makefiles, så man kan oversætte programmerne udenfor GUI miljøet. Med andre ord, så er KDevelop en naturlig overbygning på GNU værktøjerne, uden at disse erstattes. KDevelop følger ikke med f.eks. Red Hat endnu, men kan downloades fra projektets hjemmeside http://www.kdevelop.org.
Der findes mange bøger om C-programmering på UNIX-systemer. Vi nøjes her med at nævne et par stykker, som vi synes er gode:
Michael K. Johnson & Erik W. Troan: Linux Application Development, Addison Wesley, ISBN 0-201-30821-5, 538 sider.
En god og klar indføring i C-programmering under Linux. Lidt dyr, men lækkert udført og med den fordel, at den er skrevet specifikt til Linux.
David A. Curry: UNIX Systems Programming, O'Reilly & Associates, Inc., ISBN 1-56592-163-1, 596 sider.
Denne glimrende bog handler i høj grad om de samme emner, som behandles i den førnævnte Linux Application Development, men kommer lidt mere ud i hjørnerne af stoffet og beskriver forskellene mellem forskellige kommercielle UNIX-varianter. Linux nævnes ikke, men så godt som alle forklaringer og eksempler kan bruges uændret under Linux
W. Richard Stevens: Advanced Programming in the UNIX Environment, Addison Wesley, ISBN 0-201-56317-7, 742 sider.
Dette er bestemt ikke en begynderbog (hvad titlen heller ikke på nogen måde kan siges at antyde), men hvis du har lyst til at lære en masse om, hvordan et UNIX-system fungerer og programmeres, kan vi kun anbefale denne bog på det varmeste. Den kommer gennem alle relevante emner på en meget grundig måde og binder til sidst i bogen det hele sammen i et par større eksempler, der gennemgås ganske grundigt.
Fælles for de tre nævnte bøger er, at de henvender sig til læsere, der allerede er godt inde i C som programmeringssprog. Hvis du har brug for at lære C fra grunden, findes der utroligt mange bøger at vælge mellem. Prøv som udgangspunkt at tage et kig på disse to (den første er en klassiker):
Brian W. Kernighan & Dennis M. Ritchie: The C Programming Language (2nd Edition), Prentice Hall, ISBN 0-131-10362-8, 272 sider.
Steve Oualline: Practical C Programming, O'Reilly & Associates, Inc., ISBN 1-565-92306-5, 454 sider.