Compiler voor Linux

Status
Niet open voor verdere reacties.

Voldemort

Gebruiker
Lid geworden
21 jul 2006
Berichten
111
Beste mensen,

Ik wil C++ leren en daarvoor heb ik een compiler nodig. Ik ben een Linux gebruiker en heb dus een compiler die werkt op Linux nodig. GCC doet het hier niet (met Hello world code van verschillende tutorials krijg ik errors). Verder ken ik er niet echt een. Dus mijn vragen:

- Kennen jullie nog goede compilers voor Linux?
- Op Linux is bijna alles Open Source, is het daarom nodig programma's te compilen onder Linux?

Mvg, Voldemort.
 
Vraag 1:

Je zat er wel zo verrekes dicht bij:

GCC wordt onder Linux gebruikt om C code mee te compileren. Als je daar C++ code doorheen haalt is de kans groot dat het mis gaat.... zoals bij jou dus.

Gelukkig bestaat er een afgeleide van GCC die G++ heet (dat is in feite dezelfde compiler alleen dan speciaal voor je c++ code)

Vraag 2:

De meeste aanbieders kiezen ervoor om installatie pakketten te maken van hun programma ( dag, freshmeat zijn enkele goede sites om te zoeken). Het is echter veel werk om voor iedere distributie een versie bij te houden, en daarom kiezen ook veel aanbieders ervoor om alleen de source aan te bieden.

Mijn ervaring is dat na enig zoeken je meestal wel een site met een installatie pakket tegenkomt. Let er wel op dat je het juiste pakket download (het moet voor jouw distributie en processor architectuur geschikt zijn). Dat laatste is trouwens ook een reden om geen pakket te maken: je bent met alleen source niet afhankelijk van een bepaalde distributie.

Succes
 
daget zei:
Vraag 1:

Je zat er wel zo verrekes dicht bij:

GCC wordt onder Linux gebruikt om C code mee te compileren. Als je daar C++ code doorheen haalt is de kans groot dat het mis gaat.... zoals bij jou dus.

Gelukkig bestaat er een afgeleide van GCC die G++ heet (dat is in feite dezelfde compiler alleen dan speciaal voor je c++ code)

Ik zal deze testen: GCC-C++ 4.0.2 (moet eerst even de versie checken).

daget zei:
Vraag 2:

De meeste aanbieders kiezen ervoor om installatie pakketten te maken van hun programma ( dag, freshmeat zijn enkele goede sites om te zoeken). Het is echter veel werk om voor iedere distributie een versie bij te houden, en daarom kiezen ook veel aanbieders ervoor om alleen de source aan te bieden.

Mijn ervaring is dat na enig zoeken je meestal wel een site met een installatie pakket tegenkomt. Let er wel op dat je het juiste pakket download (het moet voor jouw distributie en processor architectuur geschikt zijn). Dat laatste is trouwens ook een reden om geen pakket te maken: je bent met alleen source niet afhankelijk van een bepaalde distributie.

Succes

Dat bedoelde ik niet. Ik bedoelde als ik zelf programma's maak, en ik stel enkel de source beschikbaar, moet ik die dan compilen (de source)? Of doet "Make" bij de user dat? Als ik compile, dan is de source toch niet meer te zien? Of wel? Kan je even uitleggen?
 
Compileren zorgt ervoor dat je sourcecode wordt omgezet naar een executable. De gebruikers kunnen dan inderdaad de sourcecode niet meer achterhalen. Dus als je open source programmatuur wil maken zul je je code sowieso aan moeten bieden.

Make is een programma dat een scriptje uitvoert: de Makefile. In dat script staat hoe jouw code gecomplieerd moet worden -> met g++ dus ;)

Je kunt in die Makefile ook vertellen hoe het geinstalleerd moet worden: make install zal jou al wel bekend voorkomen.

Je kunt een Makefile schrijven en die samen met je source aan de gebruikers geven zodat ze eenvoudiger hun eigen executable kunnen bakken. Of je compileert zelf een aantal smaken van je programma ( met gcc kun je bijvoorbeeld ook voor de ARM processor compileren, zelfs al werk je zelf op een Intel), en geeft die samen met de source.

Veel aanbieders kiezen voor een mengeling. Tis maar een kwestie van smaak en het hangt natuurlijk ook van je gebruikers af: zijn ze onervaren of zijn het hardcore hackers die gewend zijn aan compileren?

Ik zou zelf beginnen met het maken van een goed make script en misschien een versie van je executable voor bijvoorbeeld Intel. Uitbreiden kan altijd nog.
 
Ik neem aan dat programma's zoals Firefox, Thunderbird, Kaffeine, Gaim, etc gewoon source zijn die de gebruiker moet omzetten? Of hoe levert men die programma's? Puur de source of een executable? Of anders?
 
Laatst bewerkt:
Op de firefox site is de "normale" installatie link een voorgecompileerde executable die netjes in een installer verpakt is. Een installer is een executable die de directories aanmaakt en de executable naar de juiste plek kopieert.

Op de ftp site van mozilla kun je ook bij de source komen (zie de directory Source):

http://releases.mozilla.org/pub/mozilla.org/firefox/releases/2.0b1/

Het is aan de gebruikers of ze de makkelijke route van "klikkie klakkie installeren" willen nemen, of dat ze de source zelf willen omzetten naar een executable.
99% van de firefox gebruikers zal het eerste willen.

Ik zou zeggen: begin eerst eens met het maken van een goed werkende applicatie. Als je programma zover af is dat mensen het ook kunnen & willen gebruiken kun je je altijd nog afvragen hoe je het gaat aanbieden.
 
Als ik enkel programma's voor Linux wil gaan maken, daar heb je toch altijd de source? Op de Firefox site zie ik geen .rpm ofzo staan hoor. Dus wat je bedoelt met executable versta ik niet echt? Ik krijg na compilen altijd een .out bestand, ik heb nog geen .out bestanden gezien. Enkel .sh, zijn het die dan?
 
Bij veel programma's voor Linux bestaat de *mogelijkheid* om de source op te vragen. Dit komt doordat veel programmeurs voor een open source licentie kiezen.
Je kunt ook voor een gesloten licentie kiezen en dan heeft de eindgebruiker die mogelijkheid niet.

Dat staat echter los van de manier waarop je je applicatie aanbiedt. Ook al ben je open source, dan nog kun je installatie pakketten aanbieden:

http://dag.wieers.com/packages/firefox/

Hier staan bijvoorbeeld .rpm packages met alleen binaries erin. Er staan ook packages met src die de sourcecode bevatten.

G++ maakt standaard altijd het a.out bestand aan als output. Je kunt zelf een andere naam opgeven met de optie -o
Onder linux heb je geen bestandsextensie nodig. Je kunt iedere file executable maken door de rechten aan te passen.
 
Als ik voor de open source licentie kies en men mag m'n source bekijken en ik wil geen .rpm bestanden ofzo aanbieden, moet ik dan gewoon de .cpp bestanden in een .tar.gz (of ander archief) steken? Of werkt het anders?
 
In dat geval is een tarfile met daarin je *.cpp en je *.h files inderdaad het beste.

Het is nog mooier als je er dan ook een handleiding bij doet hoe iemand je programma moet compileren.

Tegen de tijd dat je handleiding groter wordt dan 1 pagina, dan wordt het interessant om met Makefiles te gaan werken:

http://www.gnu.org/software/make/manual/html_node/index.html

Met een Makefile definieer je in een bestand een aantal zogenaamde Targets. In feite komt het er op neer dat je een of meer scripts in een tekstbestand stopt en bij ieder script een naam (Target) zet. Als je dan "make naam" doet zorgt make ervoor dat het scriptje uitgevoerd wordt. Volgens conventie zorgt een lege naam voor het compileren, en de naam install voor alles wat er moet gebeuren voor de installatie.

Makefiles zorgen er ook voor dat je niet steeds die hele riedel van G++ hoeft in te typen.

Om nog even terug te komen op je vraag van gisteravond:

.sh bestanden zijn shell scripts. In windowstermen: een batchfile. Het is een tekstbestandje waarin een aantal commando's staan. En met executables bedoel ik gecompileerde bestanden, die uitgevoerd kunnen worden door het operating systeem. Je kunt ze herkennen door in linux in je window manager eens een keer de rechten van een bestand te bekijken. Daar waar een vinkje staat bij 'executable' betekend het dat je het mag uitvoeren (nu kun je ieder bestand zo instellen, dus alleen aanvinken betekend niet automatisch dat je van iedere file een executable kunt maken).

Ik ben bezig met het verzinnen van een voorbeeld van programma distributie en wat daar nou bij komt kijken. Even geduld nog. Ik wil het je graag in 1 posting goed uitleggen.

Daget
 
Laatst bewerkt:
Ok, ik denk dat ik zo een aardig voorbeeld heb voor je:

Stel dat ik een programma maak dat "hello" heet. Geheel
buiten verwachting om print het programma de tekst "hello"
als je het uitvoert.

Dat programma bestaat uit 2 files:
- hello.cpp
- hello.h

Voor mij is het programma relatief eenvoudig te compileren:

g++ -I/usr/include -c hello.cpp -o hello

Het resultaat is een uitvoerbaar bestand genaamd hello.
Als je ls -a doet, zie je dat de rechten voor dit bestand
inderdaad op executeerbaar staan.

Het bestand is gemakkelijk uit te voeren door:

./hello

Op zich gaat dat goed, maar het begint me te vervelen dat
ik iedere keer als ik iets wijzig de g++ regel in moet
tikken om het te compileren.

Om dat op te lossen maak ik een Makefile (gewoon in een
teksteditor), die de volgende inhoud heeft

compileer:
g++ -I/usr/include -c hello.cpp -o hello

Let er op dat je een tab zet voor de g++. Als ik nu
in mijn sourcecode directory make compileer in type,
dan wordt mijn programma netjes gecompileerd.

Als ik nou hello.cpp, hello.h en Makefile in een tar
file stop kan ik het aan jou geven. Jij hoeft alleen
te weten dat je na het uitpakken make compileer moet
doen om het programma te kunnen maken.

Nu vind ik dat mijn programma zo geweldig hello print,
dat ik het ook door anderen op mijn systeem wil kunnen
laten gebruiken.
Als ik het in mijn home directory laat staan dan gaat
dat niet. Het zal dus na compilatie gekopieerd moeten
worden naar de /usr/local/bin directory.

Om dit voor elkaar te krijgen breid ik de makefile uit:

compileer:
g++ -I/usr/include -c hello.cpp -o hello

installeer:
su -
cp ./hello /usr/local/bin

De su zorgt ervoor dat degene die het installeert, dat
ook mag ( Substitute User zonder naam maakt je root ).

We hebben nu 2 stappen nodig om mijn programma te
installeren:

- make compileer
- make installeer

Tot zover iedereen tevreden. Totdat ik een nieuwe versie
uitbreng en jij de oude moet deinstalleren. Ik kan je
vragen om het uit /usr/local/bin te halen, maar inmiddels
heb ik vanalles en nog wat veranderd zodat je de volgende
keer nog meer moet doen om het te deinstalleren.

Dus ik pas de Makefile nog een keer aan:

compileer:
g++ -I/usr/include -c hello.cpp -o hello

installeer:
su -
mkdir /usr/local/bin/hello
cp ./hello /usr/local/bin/hello
ln -s /usr/local/bin/hello /usr/local/bin/hello/hello

deinstalleer:
su -
rm -rf /usr/local/bin/hello

Ziezo, nu kan iedereen die het wil mijn tar file downloaden
en mijn programma compileren en installeren. En tegen de
tijd dat ze genoeg "hello" voorbij hebben zien komen kunnen
ze met een make deinstalleer het programma weer verwijderen.

D'r zitten wel een paar nadelen aan mijn systeem:

1.
Ik ga er vanuit dat mensen een compiler en Gnu Make geinstalleerd
hebben en snappen wat een Makefile is.

2.
Ik ga er ook vanuit dat mensen mijn Makefile die bij deze versie
hoort ook op hun systeem houden. Anders kunnen ze het nooit meer
deinstalleren. Een nieuwere versie van de Makefile kan andere
instructies bij deinstalleer hebben staan dan deze versie.

Vooral dat 2e nadeel is nogal wat gevraagd van mijn gebruikers,
dus als laatste maak ik een installatie package aan zodat het
package door rpm beheerd kan worden. Mensen kunnen dan op ieder
moment mijn programma installeren en deinstalleren zonder dat
ze daar de versie van hoeven bijhouden.
Dat doet de packagemanager voor ze.

Natuurlijk geef ik zowel de package als de source op mijn website
zodat mensen met een linux versie zonder RPM zelf een eigen
package kunnen maken.

Ziezo, ik hoop dat ik zo een aardig voorbeeldje gemaakt heb.
 
Een make file, hoe heet dat? Gewoon make.txt ofzo? En moet er in die make file deinstalleer staan ofzo, Nederlands? En als men dan een Engels systeem gebruikt? Voor het installeren, wat moet de gebruiker dan doen?

su
(root pass)
tar
cd (getarde map)
./configure
make
make install

Dat is wat de gebruiker moet doen? En als ik wil dat de gebruiker ook --prefix kan gebruiken, moet ik dan het makefile aanpassen? Als die boel gecompileerd en geïnstalleerd is, is alles dan 1 .out bestand of blijven de bestandsnamen behouden?
 
Dat zijn een hoop vraagtekens in 1 posting. :)

Ik ga ze 1 voor 1 af:

- Een make file, hoe heet dat?
Het bestand heet Makefile
Dat is de naam die make automatisch herkent.

-Gewoon make.txt ofzo?
Onder linux heb je geen extensies nodig. Dus .txt is iets typisch van windows. Onder linux heeft een bestand 3 soorten rechten: lezen, schrijven en uitvoeren. Die rechten kun je weer op 3 niveau's toekennen: de eigenaar, de groep, iedereen. Een Makefile is dus een bestand dat je aanmaakt met een teksteditor en waaraan je de rechten lezen + schrijven voor de eigenaar toekent.

- En moet er in die make file deinstalleer staan ofzo, Nederlands?
De namen die ik gebruik zijn zogenaamde Targets. Het is slechts een naam waarop make gaat zoeken in je Makefile. Als ie de naam gevonden heeft gaat ie het script uitvoeren dat je erbij gezet hebt. Kijk a.u.b. in de Gnu Make handleiding waarvan ik je de link gegeven heb.

- En als men dan een Engels systeem gebruikt?
Het maakt dus niet uit. Je mag zelfs een afrikaans systeem gebruiken wat make betreft.

- Voor het installeren, wat moet de gebruiker dan doen?
Zoals in mijn vorige post staat moet de gebruiker dan make installeer doen. In het scriptje dat daarbij staat zie je dat dan eerst de opdracht su - aangeroepen wordt en vervolgens het bestand hello gekopieerd wordt naar /usr/local/bin.

- Dat is wat de gebruiker moet doen?
./configure wil niets anders zeggen dan: voor het script genaamd configure uit dat in de huidige directory staat. Zo'n script wordt meestal gebruikt om controles uit te voeren als: heeft deze gebruiker wel g++ geinstalleerd staan?
In jouw geval bestaat dat script niet, dus de gebruiker hoeft dat niet te doen.

- En als ik wil dat de gebruiker ook --prefix kan gebruiken, moet ik dan het makefile aanpassen?
Dan zul je er voor moeten zorgen dat het script zogenaamde invoer variabelen accepteerd. Je kunt ook aan de gebruiker vragen een omgevingsvariabele te exporteren zodat je die kunt gebruiken. Voor meer informatie over omgevingsvariabelen doe je: man export

- Als die boel gecompileerd en geïnstalleerd is, is alles dan 1 .out bestand of blijven de bestandsnamen behouden?

Met de -o optie kun je je bestand tot iedere naam laten compileren die je maar wil. Dus je zit helemaal niet vast aan .out. Het installeren is in dit geval niets meer dan het kopieeren van het bestand hello naar de directory /usr/local/bin. Als je dat per se zou willen kun je bij het kopieeren het doelbestand ook een andere naam geven: cp ./hello /usr/local/bin/hello2

Ik denk dat ik je nu genoeg verwijzingen heb gegeven om voorlopig vooruit te kunnen. Als je van de Gnu Make handleiding de eerste 70 pagina's leest kun je al prima scripts schrijven voor alles wat je voorlopig nodig hebt.

Succes, Daget
 
Is er geen Nederlandse handleiding van make want ik ben niet echt een krak in Engels (lees: kent te weinig Engels om zoiets te begrijpen)?
 
hmm.. niet dat ik weet. Misschien dat er wel tutorials in het nederlands te vinden zijn. Je zou ook eens kunnen proberen bij de lokale boekhandel.

Helaas zijn vrijwel alle boeken over linux / unix in het engels, dus ik ben bang dat er niets anders op zit dan je engels bij te spijkeren.
 
Wel lastig dat het enkel Engels is.

Ik wil wat met messagebox proberen en ik include daarvoor windows.h, alleen zegt g++ dan:

messagebox.cpp:2:21: error: windows.h: Onbekend bestand of map

Welke moet ik dan wel aanroepen?
 
Je g++ kan het bestand windows.h niet vinden. Je zult hem moeten vertellen waar het staat doormiddel van een -I (hoofdletter i) optie. Daarmee kun je de compiler vertellen welke directories hij moet "includen" (helaas weer een engelse term). Gelukkig pikt die optie ook alle onderliggende directories mee als je een directory meegeeft.

In jouw geval zul je dus moeten zoeken waar dat bestand staat (waarschijnlijk in /usr/include) en bijvoorbeeld het volgende aanroepen:

g++ -I/usr/include -c hello.cpp -o hello

Misschien pik je je engels juist op door te gaan lezen over onderwerpen die je interesseren? Ik heb mijn meeste engels geleerd door het lezen van handleidingen en natuurlijk het spelen van de nodige adventure spellen (monkey island 1 is nog steeds kei leuk)
 
windows.h zit bij mij in /usr/include/directfb-internal/core/

Als ik dan compileer, dan krijg ik dit:

g++ -I/usr/include/directfb-internal/core/ message
box.cpp
In file included from /usr/include/c++/4.0.2/backward/iostream.h:31,
from messagebox.cpp:1:
/usr/include/c++/4.0.2/backward/backward_warning.h:32:2: warning: #warning This
file includes at least one deprecated or antiquated header. Please consider usin
g one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples
include substituting the <X> header for the <X.h> header for C++ includes, or <i
ostream> instead of the deprecated header <iostream.h>. To disable this warning
use -Wno-deprecated.
In file included from messagebox.cpp:2:
/usr/include/directfb-internal/core/windows.h:31:22: error: directfb.h: Onbekend
bestand of map
/usr/include/directfb-internal/core/windows.h:33:27: error: core/coredefs.h: Onb
ekend bestand of map
/usr/include/directfb-internal/core/windows.h:34:28: error: core/coretypes.h: On
bekend bestand of map
/usr/include/directfb-internal/core/windows.h:36:27: error: fusion/object.h: Onb
ekend bestand of map
/usr/include/directfb-internal/core/windows.h:76: error: ‘DFBRectangle’ does not
name a type
/usr/include/directfb-internal/core/windows.h:78: error: ‘DFBWindowStackingClass
’ does not name a type
/usr/include/directfb-internal/core/windows.h:79: error: ‘DFBWindowOptions’ does
not name a type
/usr/include/directfb-internal/core/windows.h:80: error: ‘DFBWindowEventType’ do
es not name a type
/usr/include/directfb-internal/core/windows.h:81: error: ‘__u32’ does not name a
type
/usr/include/directfb-internal/core/windows.h:82: error: ‘DFBRegion’ does not na
me a type
/usr/include/directfb-internal/core/windows.h:96: error: expected constructor, d
estructor, or type conversion before ‘*’ token
/usr/include/directfb-internal/core/windows.h:101: error: expected constructor,
destructor, or type conversion before ‘(’ token
/usr/include/directfb-internal/core/windows.h:121: error: variable or field ‘dfb
_window_destroy’ declared void
/usr/include/directfb-internal/core/windows.h:121: error: ‘CoreWindow’ was not d
eclared in this scope
/usr/include/directfb-internal/core/windows.h:121: error: ‘window’ was not decla
red in this scope
/usr/include/directfb-internal/core/windows.h:126: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:135: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:143: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:150: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:156: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:162: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:168: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:174: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:181: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:188: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:195: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:202: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:210: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:217: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:225: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:233: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:236: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:237: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:238: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:239: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:240: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:243: error: ‘DFBResult’ does not n
ame a type
/usr/include/directfb-internal/core/windows.h:247: error: variable or field ‘dfb _window_post_event’ declared void
/usr/include/directfb-internal/core/windows.h:247: error: ‘CoreWindow’ was not d eclared in this scope
/usr/include/directfb-internal/core/windows.h:247: error: ‘window’ was not decla red in this scope
/usr/include/directfb-internal/core/windows.h:247: error: ‘DFBWindowEvent’ was n ot declared in this scope
/usr/include/directfb-internal/core/windows.h:247: error: ‘event’ was not declar ed in this scope
/usr/include/directfb-internal/core/windows.h:247: error: initializer expression list treated as compound expression
/usr/include/directfb-internal/core/windows.h:249: error: ‘DFBResult’ does not n ame a type
/usr/include/directfb-internal/core/windows.h:251: error: ‘DFBWindowID’ does not name a type
/usr/include/directfb-internal/core/windows.h:253: error: expected constructor, destructor, or type conversion before ‘*’ token
messagebox.cpp: In function ‘int main()’:
messagebox.cpp:9: error: ‘MB_YESNO’ was not declared in this scope
messagebox.cpp:9: error: ‘MessageBox’ was not declared in this scope
messagebox.cpp:11: error: ‘IDYES’ was not declared in this scope
 
Ik ben niet bekend met de library die je nu wilt gebruiken, maar aan de errors te zien is het niet de juiste manier waarop je die library moet gebruiken (het woordje deprecated betekend verouderd, dus dan moet er al een waarschuwingslamp gaan branden).

Ik zou voor deze vraag een nieuwe thread aanmaken als ik jou was, want dit heeft niets meer met je originele vraag te maken. Je hebt nu het onderwerp "windows tekenen" verdeeld staan over twee threads, dus zelfs al zou iemand op het forum komen die er wel meer vanaf weet, dan zal ie je vraag niet vinden.

Wel heb ik ander goed nieuws voor je:

In mijn boekenkast stond nog een nederlands boek over programmeren onder Linux, genaamd Linux Programming het complete handboek (origineel: Linux Programming Bible). Hierin staan alle aspecten ( make, gcc, de gtk library) netjes in het Nederlands uitgelegd.

Mijn versie is al iets verouderd, maar dan heb je in ieder geval een titel waarop je kunt zoeken. Het is geschreven / vertaald door John Goerzen, en het isbn is: 395 16073 (uitgegeven door Academic Service)
 
Laatst bewerkt:
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan