next up previous
Next: Make Up: Programarea in Unix/Linux Previous: vi

GCC (GNU C Compiler, GNU Compiler Collection)

gcc este compilatorul implicit in distributiile de Linux; provine din efortul FSF de a genera un sistem Unix complet liber (free software); initial un compilator de C, acestuia i-au fost adaugate multe alte front-end-uri si este capabil acum sa compileze multe alte limbaje: C++, Objective C, Ada, Fortran, Pascal.

GCC are un numar impresionant de optiuni; multe dintre ele sunt optiuni referitoare la optimizarea codului, iar multe altele sunt optiuni specifice unei anumite arhitecturi. GCC este actualmente unul dintre cele mai portabile si portate compilatoare.

Pentru a urmari unele optiuni ale compilatorului, vom prezenta pe scurt etapele parcurse, de la un program scris in limbaj de nivel inalt la un executabil:

  1. prima etapa este cea de preprocesare; in cazul unui fisier C aceasta presupune inlocuirea macrodefinitiilor si a directivelor #include;
  2. a doua etapa este compilarea propriu-zisa care genereaza cod in limbaj de asamblare cu registrele si modurile de adresare specifice resursei (arhitecturii) in cauza;
  3. urmatoarea etapa este asamblarea; asamblorul este cel care transforma codul scris in limbajul de asamblare de la punctul precedent in cod obiect;
  4. linking (link-editing) insemna legarea mai multor module obiect si biblioteci intr-un executabil.
In mod normal, gcc este responsabil cu rezolvarea primilor 2 pasi; pasul 3 este realizat de asamblorul de la GNU (gas), iar pasul 4 este realizat de linker-ul implicit (in mod normal ld). Totusi comanda gcc actioneaza ca un front-end deasupra celor trei elemente amintite.

Astfel in lipsa unor alte optiuni comanda gcc realizeaza preprocesarea, compilarea, asamblarea si editarea de legaturi; din pagina de manual de la gcc:

When you invoke GCC, it normally does preprocessing, compilation, assembly and linking.
Deci comanda

$ gcc test.c 
va realiza toate operatiile de mai sus asupra fisierului test.c rezultand executabilul implicit a.out.

Cateva optiuni ale GCC permit oprirea acestuia la una din fazele intermediare:

   $ gcc -E test.c  ; oprire dupa faza de preprocesare (la iesire test.E -
                      fisier preprocesat)
   $ gcc -S test.c  ; oprire dupa faza de compilare (la iesire test.s -
                      fisier in limbaj de asamblaer)
   $ gcc -c test.c  ; oprire dupa faza de asamblare (la iesire test.o -
                      fisier in cod obiect)

Putem folosi optiunea -o pentru a specifica numele fisierului de iesire:

    $ gcc -E -o test_preproc.E test.c ; iesirea va fi acum test_preproc.E
    $ gcc -S -o test_assem.s test.c   ; iesirea va fi test_assem.s
    $ gcc -c -o test_obj.o test.c     ; iesirea va fi test_obj.o
    $ gcc -o test test.c              ; executabilul va avea numele test (in
                                        locul numelui implicit a.out)

O optiune care nu trebuie NICIODATA omisa este -Wall. Aceasta afiseaza toate mesajele de avertizare (Warnings All). Optiunea este extrem de utila pentru ca sintaxa extrem de relaxata a C-ului permite conversii de tipuri de diferite, operatii intre intregi si pointeri, declaratii de functii implicite.

Daca dorim sa avem cod compatibil cu standardul ANSI (ISO C90) se foloseste optiunea -ansi, de obicei impreuna cu -pedantic. Daca dorim sa avem cod compatibil cu standardul ISO C99 folosim optiunea -std=c99 (pentru -ansi aveam optiunea echivalenta -std=c90). Standardul ISO C99 aduce multe imbunatatiri printre care stilul C++ de comentare, tipul long long int, tipul complex.

Alte cateva optiuni utile sunt:

   -D nume=definitie - predefineste macro-ul 'nume' cu definitia 'definitie'
   -I cale           - precizeaza o cale suplimentara unde se gasesc unele
                       headere incluse in fisierele sursa
   -L cale           - precizeaza o cale suplimentara unde sa gasesc unele
                       biblioteci folosite la legare
   -l biblioteca     - foloseste biblioteca 'biblioteca' la legare

Diferite exemple de utilizare a GCC:

razvan@ragnarok:~$ gcc -Wall -pedantic -ansi -o exec main.c

creeaza executabilul exec prin compilarea si link-area fisierului main.c

razvan@ragnarok:~$ gcc -Wall -pedantic -ansi -o server server.c sock.c handler.c

creeaza executabilul server prin compilarea si link-area fisierelor server.c, sock.c, handler.c.

Intotdeauna cand se doreste generarea unui fisier executabil, un singur fisier si numai unul trebuie sa contina functia ``main''.

razvan@ragnarok:~$ gcc -Wall -pedantic -ansi -c server.c
razvan@ragnarok:~$ gcc -Wall -pedantic -ansi -c sock.c
razvan@ragnarok:~$ gcc -Wall -pedantic -ansi -c handler.c
razvan@ragnarok:~$ gcc -g -o server server.o sock.o handler.o

aici se obtine un executabil prin obtinerea in prealabil a modulelor obiect si apoi legarea acestora. Optiunea -g este utila pentru pastrarea diferitelor simboluri pentru debugging.

razvan@ragnarok:~$ gcc -I. -I.. -Wall -o server server.c sock.c handler.c

aici se cauta in plus fata de caile implicite headere in directorul curent si directorul parinte.

razvan@ragnarok:~$ gcc -L. -o server server.o sock.o handler.o -lm -lmylib

la caile implicite de cautare a bibliotecilor se cauta si directorul curent; pe langa modulele obiect se mai face legarea cu biblioteca matematica (-lm) si o biblioteca locala (-lmylib).


next up previous
Next: Make Up: Programarea in Unix/Linux Previous: vi
Razvan Adrian Deaconescu 2005-10-01