[LinuxFocus-icon]
Ev  |  Eri�imd�zeni  |  ��indekiler  |  Arama

Duyumlar | Belgelikler | Ba�lant�lar | LF Nedir
Bu makalenin farkl� dillerde bulundu�u adresler: English  Castellano  ChineseGB  Deutsch  Francais  Italiano  Portugues  Russian  Turkce  Arabic  

convert to palmConvert to GutenPalm
or to PalmDoc

[Lorne Bailey]
taraf�ndan Lorne Bailey
<sherm_pbody(at)yahoo.com>

Yazar hakk�nda:

Lorne �ikago da ya��yor ve Oracle veritabanlar�ndan veri alma-girme konusunda uzmanla�m�� bir bilgisayar dan��man�d�r. Unix ortam�nda programlama yapmaya ba�lad���ndan beri, Lorne 'DLL Cehennemi' nden tamam�yla ka��nm��t�r. Halen Bilgisayar Bilimleri'nde y�ksek lisans� i�in �al��maktad�r.



T�rk�e'ye �eviri:
B�lent �ZDEM�R <bulentozdem(at)hotmail.com>

��erik:

 

GCC - her�eyin k�k�

[Illustration]

�zet:

Bu yaz�, sizin C dilinin temellerini bildi�inizi varsayarak derleyici olarak gcc kullan�m�n� size tan�tacakt�r. Basit C kaynak kodlar�n�z i�in derleyiciyi komut sat�r�ndan �a��rabileceksiniz. Daha sonra, asl�nda neler oldu�una ve programlar�n�z�n derlenmesini nas�l denetleyebilece�inize h�zl�ca bir g�z ataca��z. Bu arada hata ay�klay�c�lar�n kullan�m�na da �ok k�sa de�inece�iz.

 

GCC Kurallar�

Serbest bir yaz�l�m�n kapal� ve tescilli bir derleyici ile derlendi�ini d���nebilir misiniz? Program�n�z�n �al��an k�sm�na neler olaca��n� nereden bilebilirsiniz? Herhangi bir 'arka kap�' veya Truva At� vir�s� olabilir. Ken Thompson, t�m zamanlar�n en b�y�k hack lerinden birinde, 'login' program�n�n i�ine bir arka kap� koyan ve derleyici kendisini derlemeye ba�lad���n� anlad��� zaman kendisini koruyan bir derleyici yazm��t�r. Bu t�m zamanlar�n klasi�ini, kendi tan�mlamas�ndan, bu adresten okuyabilirsiniz. �ansl�y�z ki, gcc var. Bir configure; make; make install yapt���n�zda, gcc sahne arkas�nda bir�ok a��r i�i sizin i�in yapmaktad�r. gcc'nin bizim i�in �al��mas�n� nas�l sa�lar�z? Bir kart oyunu yazmaya ba�layaca��z, ancak derleyicinin fonksiyonlar�n� gosterecek kadar�yla yetinece�iz. S�f�rdan ba�layaca��mdan, bir �al��t�r�labilir program yarat�labilmesi i�in derleyicinin neler yapmas� gerekti�ini ve bunlar� hangi s�rada yapt���n� anlamam�z gerekiyor. Bir C program�n�n nas�l derlendi�ine ve gcc'nin bizim istediklerimizi yapmas� i�in gereken se�eneklerine bakaca��z. Ad�mlar (ve bu ad�mlar� ger�ekle�tiren ara�lar) �unlard�r: �n-derleme (gcc -E), Derleme (gcc), Toplama (as), ve Ba�lama (ld).

 

Ba�lang��ta...

�lk �nce, derleyici nas�l �al��t�raca��m�z� bilmeliyiz. T�m zamanlar�n klasi�i olan ilk C program� ile ba�layaca��z. (Deneyimliler beni affetmek zorunda).

#include <stdio.h>

int main()
{ printf("Hello World!\n"); }

Bu dosyay� game.c olarak kayded�n. Program�, komut sat�r�nda: yazarak derleyebilirsiniz. C derleyicisi, benimsenmi� olarak, a.out isimli �al��t�r�labilir program olu�turur. Bunu, ��yle �al��t�rabilirsiniz:

a.out
Hello World
Her derleme yapt���n�zda yeni a.out eskisinin �zerine yaz�lacakt�r. Bu y�zden, a.out dosyas�n� hangi program�n olu�turdu�unu bilemezsiniz. Bu problem�, gcc'ye �al��t�r�labilir ismini -o se�ene�i ile s�yleyerek ��zebiliriz. Bu program� game olarak adland�raca��z, ama, C, Java gibi isimlendirme s�n�rlamas� gerektirmedi�inden herhangi bir isim de verebiliriz.
gcc -o game game.c
game
Hello World

Bu noktada, �ok faydal� bir programa sahip olmaktan hayli uza��z. Bunun k�t� bir�ey oldu�unu d���n�yorsan�z, derlenmi� ve �al��an bir program�m�z oldu�u ger�e�ini an�msayabilirsiniz. Bu programa k���k k���k eklemeler yapt�k�a, program�n hala �al���r oldu�undan emin olmak isteyece�iz. �yle g�r�n�yor ki, her yeni ba�layan programc� 1,000 sat�rl�k kaynak kod yaz�p tek seferde d�zeltmeleri yapmak ister. Kimse, evet kimse, bunu yapamaz. �al��an k�c�k bir program yazars�n�z, de�i�iklikleri yapars�n�z ve tekrar �al��abilir hale getirirsiniz. Bu, tek seferde d�zeltmeniz gereken hata say�s�n� s�n�rlar. Art�, son olarak ne yapt���n�z� bildi�inizden, �al��mama durumunda nereye odaklanaca��n�z� bilirsiniz. Bu �al��aca��n� sizin d���nd���n�z, derlenen, ama �al��mayan bir�ey yapmaktan sizi al�koyar. Hat�rlay�n, derlenebilir olmas� dogru oldu�u anlam�na gelmez.

Bir sonraki ad�m�m�z oyunumuz i�in bir ba�l�k dosyas� olu�turmak. Bir ba�l�k dosyas� tek bir yerde, veri tipleri ve fonksiyon tan�mlamalar� i�in kullan�l�r. Bu veri yap�lar�n�n tutarl� bir �ekilde tan�mlanmas�n� sa�lar ki, b�ylece program�n her k�sm� her�eyi ayn� �ekilde tan�r.

#ifndef DECK_H
#define DECK_H

#define DECKSIZE 52

typedef struct deck_t
{
  int card[DECKSIZE];
  /* number of cards used */
  int dealt;
}deck_t;

#endif /* DECK_H */

Bu dosyay� deck.h olarak kaydedin. Sadece .c dosyalar� derlenebilir, bu y�zden game.c program�m�z� de�i�tirece�iz. game.c dosyas�n�n ikinci sat�r�na, #include "deck.h" yaz�n. Be�inci sat�ra, deck_t deck; yaz�n. Herhangi bir yanl�� yapmad���m�zdan emin olmak i�in yeniden derleyin.

gcc -o game game.c

Hata yok, problem yok. Derlenmezse, derlenene kadar uzerinde �al���n.

 

�n-derleme

Derleyici deck_t tipini nereden biliyor? ��nk� �n-derleme s�ras�nda, "deck.h" dosyas� "game.c" dosyas�na kopyalan�r. Kaynak kodun i�erisinde �nderleyici komutlar�n�n �n�ne # konulur. gcc'yi -E anahtar� ile kullanarak �n-derleyiciyi �a��rabilirsiniz.

gcc -E -o game_precompile.txt game.c
wc -l game_precompile.txt
  3199 game_precompile.txt
Hemen hemen 3200 sat�r ��kt�! B�y�k �o�unlu�u stdio.h include dosyas�, fakat bakt���n�zda, bizim tan�mlamalar�m�z da orada. E�er -o anahtar� ile bir ��kt� dosyas� belirtmezseniz , ��kt�lar konsola yaz�l�r. �n-derleme i�lemi u� temel amac� ger�ekle�tirerek kaynak koda b�y�k esneklik verir:
  1. Derlenecek kaynak dosyas�na "#include" dosyalar�n� kopyalar.
  2. "#define" sat�rlar�n� ger�ek de�erleri ile de�i�tirir.
  3. �a��r�ld�g� yerlerdeki makrolar� yerine koyar.
Bu, size kaynak kodda kulland���n�z isimlendirilmi� sabitlerini (s�zgelimi DECKSIZE destedeki ka��t say�s�n� belirtir) bir yerde tan�mlaman�z� ve sabitlerin de�erini de�i�tirdi�inizde heryerde otamatik olarak g�ncellenmesi sa�lar. Pratikte -E anahtar�n� hemen hemen hi� kullanmazs�n�z, ama b�rak�n ��kt�s�n� derleyiciye aktars�n.

 

Derleme

Bir ara ad�m olarak, gcc kodunuzu Assembly diline �evirir. Bunu yapmak i�in, kodunuzu parse ederek ne yapmaya �al��t���nuzu ortaya ��karmas� gerekir. E�er bir yaz�m(syntax) hatas� yapm�� iseniz, bunu size s�yler ve derleme durur. �nsanlar, hatal� olarak, bu ad�m� b�t�n i�lemin kendisi gibi alg�larlar. Ancak, gcc'nin daha yapaca�� �ok i� vard�r.

 

Toplama

as Assembly kodunu nesne koduna �evirir. Nesne kodu asl�nda CPU taraf�ndan �al��t�r�lamaz, ama �al��t���lmaya olduk�a yak�nd�r. -c derleyici anahtar� .c dosyas�n� .o uzant�l� bir nesne dosyas�na donu�turur. E�er

gcc -c game.c
komutunu cal��t�r�rsak otamatik olarak game.o isimli bir dosya elde ederiz. Burada �nemli bir noktada dural�m. Herhangi bir .c dosyas�n� alarak bir nesne dosyas� olu�turabiliriz. A�a��da g�rece�imiz gibi, bu nesne dosyalar�n� Ba�lama ad�m� ile �al��abilir bir dosyaya toplayabiliriz. �rne�imizle devam edelim. Bir kart oyunu programl�yoruz ve ka��t destesini deck_t ile tan�mlad�k, �imdi ka��tlar� kar��t�racak bir fonksiyon yazaca��z. Bu fonksiyon, deste tipine bir i�aret�i alacak ve onu, rastgele bir say� k�mesi ile dolduracak. Hangi kartlar�n daha �nce kullanildi�ini 'drawn' dizisi ile takip edecek. Bu dizi DECKSIZE �yelerinden birini iki kez kullanmam�z� engelliyecek.

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "deck.h"

static time_t seed = 0;

void shuffle(deck_t *pdeck)
{
  /* Keeps track of what numbers have been used */
  int drawn[DECKSIZE] = {0};
  int i;

  /* One time initialization of rand */
  if(0 == seed)
  {
    seed = time(NULL);
    srand(seed);
  }
  for(i = 0; i < DECKSIZE; i++)
  {
    int value = -1;
    do
    {
      value = rand() % DECKSIZE;
    }
    while(drawn[value] != 0);

    /* mark value as used */
    drawn[value] = 1;

    /* debug statement */
    printf("%i\n", value);
    pdeck->card[i] = value;
  }
  pdeck->dealt = 0;
  return;
}

Bu dosyay� shuffle.c olarak kaydedin. Kodun i�erisine bir hata ay�klama sat�r� koyduk, �yle ki, program �al��t�r�ld��� zaman, bu sat�r �retilen kart numaralar�n� yazacak. Bu program�n fonksiyona litesine herhangi bir katk� da bulunmayacak, ama neler oldu�unu g�rmek a��s�ndan �nemli. Hen�z oyunumuza yeni ba�lad���m�zdan fonksiyonumuzun �al���p �al��mad���n� anlamak i�in ba�ka yolumuz yok. printf sat�r� sayesinde �u anda tam olark ne oldu�unu anlayabiliriz, b�ylece destemizin do�ru da��t�ld���ndan emin olarak bir sonraki ad�ma ge�ebiliriz. �al��t���ndan iyice emin olduktan sonra, hata ay�klama sat�r�n� programdan ��kartabiliriz. Bu hata ay�klama tekni�i �ok ham g�r�nebilir, ama �ok k���k bir hareketle amac�m�za ula��yoruz. Daha geli�mi� hata ay�klay�c�lar� daha sonra tart��aca��z.

�ki �eye dikkat edin:
  1. Bir parametreyi adresi ile fonksiyona gectik ki, bunu '&' (address of) operatoru sayesinde anlayabilirsiniz. Bu, fonksiyona de�i�kenin haf�zadaki adresini g�nderir, b�ylece fonksiyon de�i�kenin de�erini de�i�tirebilir. Evrensel de�i�kenleri de kullanabilirdik, ancak global de�i�kenler �ok nadir kullan�lmal�d�r. I�aret�iler C dilinin �nemli bir par�as�d�r, bu y�zden onlar� iyi anlaman�z gerekir.
  2. Yeni bir .c doayas�ndan bir fonksiyon ca��r�m� yapiyoruz. ��letim sistemi herzaman 'main' isimli fonksiyonu arar ve program� �al��t�rmaya oradan ba�lar. shuffle.c dosyas�nda 'main' fonsiyonu olmad���ndan bu program� �al��t�ramay�z. Bu dosyay�, i�erisinde 'main' fonksiyonu olan ve 'shuffle' fonksiyonu �a��r�m� yapan ba�ka bir program ile birle�tirmeliyiz.

gcc -c shuffle.c
komutunu �al��t�r�n ve shuffle.o dosyas� olu�tu�undan emin olun. game.c dosyas�n� a��n, ve 7. sat�rda, deck de�i�keni i�in yap�lan deck_t tan�mlamas�ndan sonra,
shuffle(&deck);
sat�r�n� ekleyin. �imdi, daha �nce yapt���m�z gibi �al��an program olu�turmaya �al��t���m�z zaman, hata mesaj� alaca��z:
gcc -o game game.c

/tmp/ccmiHnJX.o: In function `main':
/tmp/ccmiHnJX.o(.text+0xf): undefined reference to `shuffle'
collect2: ld returned 1 exit status
Derleme ba�ar�l� oldu, cunku yazim hatam�z yoktu. Ba�lama ad�m� ba�ar�s�z oldu, ��nk� derleyiciye 'shuffle' fonksiyonunun nerede oldu�unu soylemedik. Ba�lama nedir ve derleyiciye bu fonksiyonu nerede bulaca��n� nas�l s�yleyece�iz?

 

Ba�lama

Ba�lay�c�,ld, daha once as ile olu�turulmu� nesne kodunu al�r ve onu

gcc -o game game.o shuffle.o
komutuyla �al��abilir hale getirir. Bu iki nesneyi biraraya getirir ve game isimli cal��abilir dosyay� olu�turur.

Ba�lay�c� shuffle fonksiyonunu shuffle.o nesnesinden bulur ve �al���r dosyaya ekler. Nesne dosyalar�n�n g�zel taraf�, fonksiyonu tekrar kullanmak istedi�imizde, t�m yapmamiz gereken "deck.h" dosyas�n� eklemek ve shuffle.o nesne dosyas�n� yeni �al���r dosyan�n i�ine koymaktan ibarettir.

Bunun gibi kodun yeniden kullan�m� herzaman kar��la��lan bir durumdur. Hata ay�klama sat�r� olarak kulland���m�z printf fonksiyonunu kendimizin yazmamamyzyn sebebi, ba�lay�c� bu fonksiyonun tan�mlamas�n� #include <stdlib.h> dosyas�nda bulur ve (/lib/libc.so.6) C k�t�phanesinde bulunan nesne koduna ba�lar. Bu yolla, ba�kas�n�n yazd��� �al��an bir fonksiyonu kullan�p kendi problemlerimizi ��zmekle u�ra�abiliriz. Ba�l�k dosyalar�n�n sadece veri ve fonksiyon tan�mlamalar�n� i�ermesinin sebebi de budur. Normalde, nesne dosyalar�n� veya k�t�phanelerini ba�lay�c�n�n �al���r dosyaya koymas� i�in yarat�r�z. Kodumuzla ilgili bir problem olu�abilir, ��nk� ba�l�k dosyam�za herhangi bir fonksiyon tan�mlamas� koymadik.

 

�ki �nemli Anahtar Daha

-Wall anahtari, butun dil yaz�m ikazlar�n�, kodumuzun do�ru ve m�mk�n oldu�u kadar ta��nabilir oldu�undan emin olmamiz i�in etkin hale getirir. Bu anahtar� kullanarak kodumuzu derledi�imizde, �unun gibi bir�ey g�r�r�z:

game.c:9: warning: implicit declaration of function `shuffle'
Bu, biraz daha i�imizin oldu�unu bize bildirir. shuffle fonksiyonunun nerede oldu�unu derleyiciye bildirmek i�in header dosyas�na bir sat�r eklememiz gerekiyor, b�ylece derleyici ihtiya� duydu�u b�t�n denetimleri yapabilir. Biraz garip g�z�k�yor, ama bu bize tan�mlamalar� ger�ekle�tirim k�sm�ndan ay�rmam�z� ve fonksiyonumuzu, sadece yeni ba�l�k dosyas�na koyup nesne dosyas�n� birle�tirerek istedi�imiz yerde kullanmam�z� sa�l�yor. �u tek sat�r� deck.h dosyas�na koyaca��z.
void shuffle(deck_t *pdeck);
Bu b�t�n ikaz mesajlar�n� etkisiz hale getirecek.

Yayg�n olarak kullan�lan ikinci bir derleyici se�ene�i optimizasyondur. -O# (i.e. -O2). Bu derleyiciye hangi seviyede optimizasyon yapaca��m�z� s�yler. Derleyici, kodun daha h�zl� �al��abilmesi i�in bir �ok h�nere sahiptir. Bizimki gibi minik bir program i�in fark� anlamayabiliriz, ama b�y�k programlar�n farkedilir �ekilde h�zl� �al��mas�n� sa�layabilir. Buna heryerde rastlayabilisiniz, o y�zden ne anlama geldi�ini bilmeniz gerekiyor.

 

Hata Ay�klama

Hepimizin bildi�i gibi, program�m�z�n derlenebiliyor olams�, onun istedi�imiz �ekilde �ali�aca�i anlam�na gelmez. B�t�n numaralar�n bir kez kullan�ld���ndan emin olmak i�in:

game | sort - n | less
komutunu �al��t�r�p, eksik bir�ey olmad���n� denetleriz. Bir problem varsa ne yapaca��z? Nas�l �rt�n�n alt�na bak�p, hatalar�m�z� bulaca��z?

Kodunuzu bir hata ay�klay�c� ile kontrol edebilirsiniz. Bir�ok s�r�m klasik hata ay�klay�c� gdb'yi sa�lar. Komut sat�r� se�enekleri benim gibi sizi de mutsuz ediyorsa, KDE'nin KDbg adresinde sundu�u g�zel bir �ny�z� kullanabilirsiniz. Birbirine �ok benzeyen ba�ka �ny�zler de vardir. Hata ay�klamaya ba�lamak i�in File->Executable se�in ve game program�n� bulun. F5 e bastiginizda ya da menuden Execution->Run se�ti�inizde, ��kt�y� ayr� bir pencerede g�rmelisiniz. Ne oldu? Pencerede hi�bir�ey g�remediniz mi? Tela�lanmay�n, KDbg'ye bir�ey olmad�. Problemin kayna��, bizim �al��abilir dosyaya herhangi bir hata ay�klama bilgisi koymam�� olmam�z, bu y�zden KDbg i�eride neler oldu�unu s�yleyemez. -g anahtar� gerekli bilgiyi nesne dosyalar�na koyar. Nesne dosyalar�n�z� (.o uzant�l�) bu anahtar ile derlemelisiniz, �imdi komut:
gcc -g -c shuffle.c game.c
gcc -g -o game game.o shuffle.o
oldu. Bu, �al��abilir dosyan�za gdb ve KDbg neler oldu�unu anlamas�n� sa�layan �engeller koyar. Hata ay�klama �nemli bir yetenektir, bir tanesini iyi bilmeye zaman ay�rman�za de�er. Hata ay�klay�c�lar�n programc�lara yard�m edebilmesini sa�layan �ey kaynak kodda 'Breakpoint' koyabilmesidir. �imdi, shuffle fonksiyonunu �a��ran sat�ra bir tane eklemeyi deneyin. K���k bir k�rm�z� halkan�n sat�r�n yan�nda belirmesi laz�m. �imdi, F5'e bast���n�zda program o sat�rda duracakt�r. F8 basarak shuffle fonksiyonunun i�erisine bir ad�m at�n. Hey, �imdi shuffle.c dosyas�n�n koduna bak�yoruz! Program�n �al��mas�n� ad�m ad�m takip ederek neler oldu�unu g�rebiliriz. Farenin i�aret�isini bir yerel de�i�kenin �st�ne getirdi�inizde hangi de�ere sahip oldu�unu g�rebilirsiniz. �irin. printf sat�rlar�ndan daha iyi de�il mi?

 

�zet

Bu makale, sizlere, C programlar�n�n derlenmesi ve hatalar�n�n ay�klanmas� konusunda k�sa bir tur sundu. Derleyicinin ge�ti�i ad�mlar� ve bu ad�mlar�n ger�ekle�mesi i�in gcc'ye verilen anahtarlar� inceledik. Payla��lan k�t�phanelerin ba�lanmas�na bak�p, hata ay�klay�c�lara bir giri�le bitirdik. Ne yapt���n�z� o�renmek i�in daha �ok �al��maya gereksinim var, ama �mit ederim bu makale do�ru ad�mla ba�lanmas�na hizmet eder. Daha geni� bilgiyi, gcc, as ve ld nin man ve info sayfalar�ndan bulabilirsiniz.

En �ok �eyi, kod yazarken o�renirsiniz. Pratik i�in, bu makaledeki kart program�n� kullanarak bir blackjack oyunu yazabilirsiniz. Hata ay�klay�c� kullan�m� o�renmek i�in biraz zaman ay�r�n. KDbg gibi bir GUI ile ba�lamak daha kolayd�r. Her seferinde biraz fonksiyonalite eklerseniz, o�renme i�ini halletmi� olursunuz. Hat�rlatma, program�n�z� daima �al���r halde tutun.

Tam bir oyun yazmak i�in gereksiniminiz olan �eylerden baz�lar�n�n listesi.

 

Referanslar

 

Bu yaz� i�in g�r�� bildiriminde bulunabilirsiniz

Her yaz� kendi g�r�� bildirim sayfas�na sahiptir. Bu sayfaya yorumlar�n�z� yazabilir ve di�er okuyucular�n yorumlar�na bakabilirsiniz.
 talkback page 

G�rsely�re sayfalar�n�n bak�m�, LinuxFocus Edit�rleri taraf�ndan yap�lmaktad�r
© Lorne Bailey, FDL
LinuxFocus.org

Buray� klikleyerek hatalar� rapor edebilir ya da yorumlar�n�z� LinuxFocus'a g�nderebilirsiniz
�eviri bilgisi:
en --> -- : Lorne Bailey <sherm_pbody(at)yahoo.com>
en --> tr: B�lent �ZDEM�R <bulentozdem(at)hotmail.com>

2002-03-04, generated by lfparser version 2.27