C Programlama Dili'ne Giriş

  Dersler
* Önsöz

* Giriş
* Veri Tipleri, Değişkenler
* Operatörler
* Temel G/Ç Fonksiyonları
* Temel Kütüphane Fonksiyonları
* Karşılaştırma Deyimleri
* Döngüler
* Fonksiyonlar I
* Fonksiyonlar II
* Diziler
* Gösterici (Pointer) Kavramı
* Katarlar (Stringler)
* Dinamik Bellek Yönetimi
* Gösterici Uygulamaları
* Yapılar ve Birlikler
* Dosya Yönetimi
* Bit Düzeyinde Çalışmak
* Port Denetimi
* Grafik Kullanımı
* C Makroları

* Kısaca C++
* Derleme Seçenekleri
* Tarih-Saat Fonksiyonları
* Monte-Carlo Yöntemleri
* Fortran ve C

* Yararlanılan Kaynaklar

  C/C++ Derleyicileri
* Dev-C++
* Salford (silversoft FTN95)
* GCC
* Turbo C
* Eclipse IDE
* NetBeans IDE

  Dış Bağlantılar
* programlama.com
* C Programcıları Derneği

* C (wikipedia)
* C++ (wikipedia)
* cplusplus.com
* koders.com
* Hot scripts

 

Ders 22: Derleme Seçenekleri

###################- (%95)

En son güncelleme: Wed, 30 Nov 2011 13:22:02 +0200

Giriş

Bazen bir kullanıcı derlemek istediği kaynak C programını başka C programları ile beraber kullanmak, sadece nesne kodu üretmek veya başka bir dilde yazılmış programı, C programı içinde kullanmak isteyebilir. Bir derleyiciye ait derleme seçenekleri ile bu tip işlemleri gerçekleştirmek mümkündür.

Bu kısımda derleme ve bağlama işlemi, derleyicilerin sunduğu bazı derleme seçenekleri ve bunlar yardımıyla birden çok C programının nasıl birleştirileceği anlatılacaktır.


22.1   Çalıştırılabilir Dosya Üretimi

Programlama işlemi, bir programlama diline ait söz dizilimlerini içeren kaynak kodların yazılması ile başlar. Kaynak kod (source code), C, Fortran veya Pascal gibi yüksek seviyedeki dillerin deyimleri barındıran bir düz metin dosyasında (plain text file) saklanır. Bu dosyalar geleneksel uzantılarla birbirinde ayrılabilir, örneğin c programları .c uzantılı, Pascal programları .pas uzantılı dosyalardır.

Derleyici (compiler), bir programlama dilinde yazılmış olan kaynak kodunu başka bir dile (coğukez makine dili) çeviren yazılımdır. Her programlama dile kendi derleyicisine sahiptir. Derleyicinin çevirdiği kaynak kod, hedef kod veya nesne kodu (object code) olarak adlandırılır. Nesne kodu, bilgisayarın mikroişlemcisi (CPU) için gerekli makina kodlarını ve işletim sistemi için gerekli program uygulama arayüzlerini (API: Application Programming Interface) içerir. Nesne kodu çalıştırılabilir bir kod değildir, ama bütün programlama dilleri için aynıdır. Derleyicilerin ürettikleri nesne kodları genellikle .obj veya .o uzantılı dosyalarda saklanır.

Sonraki adım, nesne kodunun özel bir bağlayıcı (linker) ile işlenmesidir. Bağlayıcı, derleyiciler tarafından üretilmiş bir veya daha fazla nesne kodunu birleştirip tek bir çalıştırılabilir dosya oluşturan yazılımdır. Her sistem kendi bağlayıcısına sahiptir. Bağlayıcının ürettiği çalıştırılabilir kod Windows ortamında .exe uzantılı dosyalarda saklanır. Linux ortamında çalıştırılabilir dosyaların çoğunlukla bir uzantısı yoktur.

Kaynak kodunun derlenip çalıştırılabilir dosyanın oluşturulmasına ait işlem basamakları Şekil 22.1'de gösterilmiştir.



Şekil 22.1: Derleme-Bağlama-Çalıştırma işleminin akış diyagramı.

C ve C++ dilleri için iki çeşit kaynak kodu vardır: .c veya .cpp uzantılı ana program ve bazı bildirimlerin bulunduğu .h veya .hpp uzantılı başlık dosyaları (header files).

C (ve C++) dilinde derleme işlemi iki adım adımda yapılır. Birinci adımıda, derleme öncesi özel bir ön işlemci (preprocessor) programı devreye girer. Ana programdaki veya başlık dosyalarındaki diyez ('#') işareti ile başlayan satırlar aslında C (veya C++) diline ait olmayıp ön işlemci dilidir. Ön işlemci, bu satırlardaki deyimlere bakarak, bir katarı (string) alıp başka bir katarla değiştir. Örneğin:

  #include <stdio.h>
satırı ile stdio.h dosyasının metin içeriği programa dahil edilir. Ön işlemci deyimlerinin tamamı Bölüm 20'de anlatılatılmıştır.

Ön işlemci programı, .c ve .h uzantılı düz metin (text) halindeki kaynak dosyasını okur, ve çıktı olarak başka bir düz metin dosyası üretir. Bu yeni dosya hiçbir ön işlemci deyimi içermeyen C (veya C++) derleyicisi tarafından işlenmeye hazır bir dosyadır. İkinci adımda bu dosya ile kaynak kodaları beraber derlenip sırasıyla nesne kodu ve çalıştırılabilir kod üretilir. Bu işlemlem Şekil 22.2 de özetlenmiştir.



Şekil 22.2: C ve C++ dilleri için, Ön işlemci-Derleme-Bağlama-Çalıştırma işleminin akış diyagramı.


22.2   Turbo C Derleme Seçenekleri

Turbo C derleyicisinin sunduğu derleme seçeneklerini görmek için, komut satırında tcc yazmak yeterlidir. TCC'nin sunduğu derleme seçenekleri Şekil 22.2'de listelenmiştir.



Şekil 22.2: Turbo C'nin derleme seçenekleri.

Seçenekler incelendiğinde standart bir derleme işleminden daha fazlasının yapılabileceği anlaşılır. Birkaç örnekle seçenekleri anlamaya çalışalım.

Program 22.1, 1 den n ye kadar olan tam sayıların toplamını hesaplayıp ekrana yazar.

Program 22.1: 1 den n ye kadar olan tam sayıların toplamını hesaplar
01: 
02: 
03: 
04: 
05: 
06: 
07: 
08: 
09: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
/* 22prg01.c: 1 den n=10 a kadar olan tam sayıların toplamını ekrana yazar */

#include <stdio.h>

int s(int);

int main()
{
   int n = 10;
   printf("1 + 2 + ... + %d = %d\n",n,s(n) );
   return 0;
}

/* 1 + 2 + ... + n toplamını hesaplar */
int s(int m){
  int i,top=0;

  for (i=1;i<=m;i++)
    top += i;

  return top;
}
Standart derleme işlemi:

  C:\TC> tcc 22prg01.c

Bu işlemle 22prg01.exe adlı bir çalıştırılabilir dosya ve 22prg01.obj adlı bir nesne dosyası üretilir. Dosyalar listelenirse bu yeni dosyalar görülecektir.

  C:\TC> dir /w 22prg01.*
  22prg01.c  22prg01.exe  22prg01.obj
22prg01.exe dosyasını çalıştırmak için, dosyanın adını yazmak yeterlidir.
 C:\TC> 22prg01
 1 + 2 + ... + 10 = 55
Sadece asm uzantılı assembly kodu üretmek istendiğinde -S seçeneği kullanılır.
  C:\TC> tcc -S 22prg01.c
  C:\TC> dir /w 22prg01.*
  22prg01.asm  22prg01.c  22prg01.exe  22prg01.obj
Sadece obj uzantılı nesne dosyası üretmek için -c seçeneği kullanılır.
  C:\TC> tcc -c 22prg01.c
  C:\TC> dir /w 22prg01.*
  22prg01.asm  22prg01.c  22prg01.exe  22prg01.obj
Çalıştırılabilir dosyanın adını değiştirmek için -exxx seçeneği kullanılır.
  C:\TC> tcc -eyeni 22prg01.c
  C:\TC> dir /w yeni*
  yeni.exe
  C:\TC> yeni
  1 + 2 + ... + 10 = 55

Büyük uygulamalarda alt progroramlar başka dosyalarda saklanır ve ana program ile beraber komut satırında derlenebilir. Aşağıdaki gibi aynı dizin içerisinde bululan herbiri ayrı dosyalarda saklanan dört fonksiyona ve bir ana programama sahip olduğumuzu varsayalım.

 /* topla.c: iki sayinin toplamini hesaplar */
 int topla(int a,int b)
 {
   return (a+b);
 }
 
 /* fark.c: iki sayinin farkini hesaplar */
 int fark(int a,int b)
 {
   return (a-b);
 }
 
 /* carp.c: iki sayinin carpimini hesaplar */
 int carp(int a,int b)
 {
   return (a*b);
 }
 
 /* iki sayinin oranini hesaplar */
 int bol(int a,int b)
 {
   if(b) return (a/b);
   return 0;
 }
 
/* ana.c: Ana program */
#include <stdio.h>

int topla(int, int);
int  fark(int, int);
int  carp(int, int);
int   bol(int, int);

int main()
{
  int x=33, y=22;

  printf("topla(%d,%d) = %d\n",x,y,topla(x,y));
  printf(" fark(%d,%d) = %d\n",x,y,fark(x,y));  
  printf(" carp(%d,%d) = %d\n",x,y,carp(x,y));  
  printf("  bol(%d,%d) = %d\n",x,y,bol(x,y));  

  return 0;
}

Sadece ana.c dosyası derlendiğinde aşağıdaki gibi bir topla, fark, carp ve bol fonksiyonlarının tanımsız olduğuna dair hata mesajı ekranda basılır:

 C:\TC> tcc ana.c
 Turbo C  Version 2.01  Copyright (c) 1987, 1988 Borland International
 ana.c:
 Turbo Link  Version 2.0  Copyright (c) 1987, 1988 Borland International
 Undefined symbol '_bol' in module ana.c
 Undefined symbol '_carp' in module ana.c
 Undefined symbol '_fark' in module ana.c
 Undefined symbol '_topla' in module ana.c
Fakat derleme şu şekilde yapıldığında hata mesajı ortadan kalkar.
 C:\TC> tcc ana.c topla.c fark.c carp.c bol.c

Bu işlemin sonucunda derleyici ana.exe, ana.obj ve topla.obj, fark.obj, carp.obj, bol.obj dosyalarını üretir. Tabiki tek çalıştırılabilir dosya ana.exe dir. Bu, bütün dosyaların ayrı ayrı derlenmiş olduğu anlamına gelir. ana.exe dosyası çalıştırıldığında program çıktısı şöyle olacaktır:

 C:\TC> ana
 topla(33,22) = 55
  fark(33,22) = 11
  carp(33,22) = 726
   bol(33,22) = 1

Alt programlar çok büyük ve karmaşık işlemler yaptığında, bu şekilde derleme yapmak pek sağlıklı değildir. Bunun yerine alt programların bulunduğu dosyalar bir kez -c seçeneği ile derlendiğinde üretilen obj uzantılı dosyalar başka programlar tarafından kullanılabilir. Şöyleki:

 C:\TC> tcc -c topla.c
 C:\TC> tcc -c fark.c
 C:\TC> tcc -c carp.c
 C:\TC> tcc -c bol.c
Ana programla beraber derleme işlemi bize aynı sonucu verecektir:
 C:\TC> tcc ana.c topla.obj fark.obj carp.obj bol.obj
Bu sayede ana programda bir değişiklik yapılsa bile alt programrın bir daha derlenmesine gerek kalmaz. Örneğin ana program şu şekilde bir satır ekleyelim:
/* ana.c: Ana program */
#include <stdio.h>

int topla(int, int);
int  fark(int, int);
int  carp(int, int);
int   bol(int, int);

int main()
{
  int x=33, y=22;

  printf("topla(%d,%d) = %d\n",x,y,topla(x,y));
  printf(" fark(%d,%d) = %d\n",x,y,fark(x,y));  
  printf(" carp(%d,%d) = %d\n",x,y,carp(x,y));  
  printf("  bol(%d,%d) = %d\n",x,y,bol(x,y));  

  printf("    ortalama = %f\n",topla(x,y)/2.0);

  return 0;
}
Derleme aşağıdaki gibi yapıldığında:
 C:\TC> tcc ana.c topla.obj fark.obj carp.obj bol.obj
program çıktısı şöyle olur:
 C:\TC> ana
 topla(33,22) = 55
  fark(33,22) = 11
  carp(33,22) = 726
   bol(33,22) = 1
     ortalama = 27.500000
 C:\TC>
Özetle bir fonksiyon birkez derlenip ona ait obj dosyası üretildiğinde, artık o kod bütün programlar tarafından kullanılabilir demektir. Aşağıdaki derleme işlemi ile obj dosyaları ana programa bağlanmıştır diyebiliriz:
 C:\TC> tcc ana.c topla.obj fark.obj carp.obj bol.obj
Bu durum Şekil 22.3 de tasvir edilmiştir.



Şekil 22.3: Birden çok dosyanın derlenmesi ve birleştirilmesi.


22.3   GCC Derleme Seçenekleri

GCC (GNU Compiler Collection) daha çok Linux ve MAC ortamında kullanılan bir komut satırı derleyicisidir. GCC'nin Windows ortamında çalıştırılabilen sürümü de mevcuttur, bkz. gcc.gnu.org. Bu kısımda GCC'nin Linux ortamındaki kullanımından bahsedilecektir. Ancak bütün işlemler Windows işletim sisteminde de geçerlidir.

GCC derleme seçeneklerini komut satırından görmek için iki yol vardır. Bunlar:

 $ man gcc
veya
 $ gcc --help
Burada $ işareti Linux komut hazır işaretidir (command prompt). Bu komutlardan birincisi oldukça büyük, ayrıntılı ve yardım niteliğindedir, örneğin bkz: www.hmug.org/man/1/gcc.php. İkincisinin sonucu Şekil 22.4 deki gibidir.



Şekil 22.4: GCC'nin derleme seçenekleri.

GCC ile 22prg01.c kaynak kodu şöyle derlenebilir:

 $ gcc 22prg01.c
Bu işlem neticesinde sadece a.out adlı çalıştırılabilir bir dosya üretilir. Bu programı çalıştırmak için:
 $ ./a.out
 1 + 2 + ... + 10 = 55
Çalıştırılabilir dosyanın adını değiştirmek için -o <file> seçeneği kullanılır.
 $ gcc 22prg01.c -o 22prg01
 $ ./22prg01
 1 + 2 + ... + 10 = 55
Sadece derleme yapmak için (Turbo C'de olduğu gibi) -c seçeneği kullanılır.
 $ gcc -c 22prg01.c
Bu işlemin sonucunda 22prg01.o adlı nesne dosyası üretilir. Bu dosya, dosyalar listelendiğinde görülebilir:
 $ ls 22prg01*
 22prg01.c  22prg01.o  22prg01*

Bir C kaynak kodu <math.h> kütüphanesinden bir fonksiyon içeriyorsa, GCC ile bu tür programlar -lm seçenği ile derlenmelidir. Program 22prg02.c, ilk 10 pozitif tam sayının on tabanındaki logaritmalarını ve doğal logaritmalarını ekrana gösterir. Program içerisinde <math.h> kütüphanesindeki log ve log10 fonkiyonları kullanılmıştır.

Program 22.2: 1 den 10 a kadar olan tam sayıların logaritmaları
01: 
02: 
03: 
04: 
05: 
06: 
07: 
08: 
09: 
10: 
11: 
12: 
13: 
14: 
/* 22prg02.c: 1 den n=10 a kadar olan tam sayıların logaritmalarını ekrana yazar */

#include <stdio.h>
#include <math.h>

int main()
{
   int i;

   for(i=1; i<=10; i++)
     printf("%2d %10.5lf %10.5lf\n",i,log(i),log10(i) );

   return 0;
}

Derleme işlemi aşağıdaki gibi yapıldığında bir hata mesajı ile karşılaşılır:

 $ gcc 22prg02.c -o 22prg02
 22prg02.c: In function `main':
 22prg02.c:10: warning: implicit declaration of function `log'
 22prg02.c:10: warning: implicit declaration of function `log10'
Fakat -lm seçeneği eklendiğinde hata mesajı ortadan kalkar:
 $ gcc 22prg02.c -o 22prg02 -lm
 $ ./22prg02
 1    0.00000    0.00000
 2    0.69315    0.30103
 3    1.09861    0.47712
 4    1.38629    0.60206
 5    1.60944    0.69897
 6    1.79176    0.77815
 7    1.94591    0.84510
 8    2.07944    0.90309
 9    2.19722    0.95424
10    2.30259    1.00000
Turbo C'de olduğu gibi, GCC ile birden cok C programı birleştirilebilir. Daha önce önce üzerinde çalıştığımız ana.c, topla.c, fark.c, carp.c ve bol.c programları aynı mantıkla aşağıdaki gibi derlenebilir: Bütün dosyaların derlenmesi:
 $ gcc ana.c topla.c fark.c carp.c bol.c -o ana
 $ ./ana
 topla(33,22) = 55
  fark(33,22) = 11
  carp(33,22) = 726
   bol(33,22) = 1
     ortalama = 27.500000
 $
Sadece alt programların derlenmesi:
 $ gcc -c topla.c 
 $ gcc -c fark.c 
 $ gcc -c carp.c
 $ gcc -c bol.c 
Derlenmiş alt programların ana program ile birleştirlmesi
 $ gcc ana.c topla.o fark.o carp.o bol.o -o ana
 $ ./ana
 topla(33,22) = 55
  fark(33,22) = 11
  carp(33,22) = 726
   bol(33,22) = 1
     ortalama = 27.500000
 $


Powered by PHP