FreeBSD'de temel sistemle birlikte gelen hatta bütün Unix , Linux vb. sistemlerde ortak kabul edilebilecek GNU C ve C++ derleyicisiccyadagcckomutları ile çalıştırılabilir.
Şaheserinizi yazıp tamaladığınızda yapacağınız iş onu FreeBSD altında çalışacak bir program haline getirmenizdir. Bu iş için her biri ayrı bir program tarfından yürütülen aşağıdaki adımlar izlenir.
1. İlk önce kodunuz ön işleme tabii olur. Burada yorumlar silinir , makrolar (derleyicinin çalışmasını yöneten komutlar) işlenir.
2. Söz diziminin doğruluğu denetlenir. Dilin kurallarına uymuyorsa hata mesajı gönderilir.
3. Program assembly diline çevrilir. Bu dil makina diline daha yakındır .Ama teorikte insanın anlayabileceği şekildedir.
4.Assembly kodu makina diline çevrilerek makinanın anlayacağı 0 lar ve 1 ler cinsinden kodlanır.
5.Kullanılan fonksiyonlar , değişkenler kuralına uygun kullanılmış mı diye kontrol edilir değilse hata mesajı ile programcıya bildirilir.
6.Eğer birden fazla kaynak kodundan derleme yapılıyorsa bunların bir araya getirilmesi sağlanır.
7.Hafızaya yüklenme sırasında gerçekleşecek işlemlerin tanımı eklenir.
8.En son çalıştırılabilir dosyayı dosya sistemine kaydeder.
Derleme kelimesi 1-4 adımlarını ifade eder. Geri kalan kısımlar bağlama(linking) ile ifade edilir. Özel olarak birinci adım önişlem(pre-processing) olarak adlandırılır.
Şansızımıza cc bütün bu işlemleri bizim için gerçekleştiren bir program. Arka planda diğer programları çağırsa da programcının işini oldukça kolaylaştırıyor.Aşağıdaki kodlar gibi girilerek programın çalıştırılabilir hali elde edilebilir.
% cc deneme.c
Bu komutu yazmanız yukarıdaki bütün işlemleri gerçekleştirmeye yetecektir. Birden fazla dosya derlemek için
% cc deneme1.c deneme2.c
şeklinde ardışık olarak yazmanız yeterlidir.
Burada söz dizimi kontrolü sadece yalın olarak söz dizimi kontrolü değil ayrıca sonsuz dögü kontrolleri , tip uyuşmazlıkları vb. hataları da içerir.
man cc komutu ile bütün kullanım detaylarını görebilirsiniz.Önemli olan birkaç tanesine burada değinelim.
-o filename
Bu komut çalıştırılabilir dosyanın ismini atamak için kullanılır. Bu seçenek kullanılmadığı zamana.outdosyasına çıktı verilir.
% cc deneme.ca.out isminde çalıştırabilir dosya yapar.
% cc -o deneme deneme.cdeneme isminde çıktı üretir.
-c
Dosyanın sadece derlenmesini sağlar. Bağlama işlemini gerçekleştirmez. Eğer söz dizimi kontrolü yada Makefile kullanırken obje dosyası gerekli ise kullanılabilir.
% cc -c deneme.c
Bu komut deneme.obj isimli obje dosyası oluşturmayı sağlar. Çalıştırılabilir hale getirmek için gerekli diğer dosyalarla bağlanması (linking) gereklidir.
-g
Programınızın debug versiyonunu oluşturmak için kullanabilirsiniz. Bu şekilde derlendiği zaman hangi fonksiyon çağrısının hangi satırda yaptığının bilgisi saklanır , böylece hataların tespiti kolaylaşır.Debugger programı bu bilgileri kullanarak satır satır işleme yapabilir , fonksiyonların parametrelerini değiştirebilir . Ama bu şekilde derlemenin zararı programımızın çok fazla yer kaplaması olacaktır. Programı geliştirirken -g seçeneğini kullandıktan sonra; sonuca ulaşmış , hatası ayıklanmış programınızı -g yi kullanmadan derlemeniz en mantıklı yöntem olacaktır.
% cc -g deneme.c
Programınızın hata ayıklama (debug) versiyonunu oluşturur.
-O
Programınızı optimize ederek derler. Böylece programınız daha hızlı çalıştırılır. İsterseniz optimizasyon seviyesini belirlemek için -O dan sonra bir rakam girebilirsiniz ama bazen hatalara neden olabileceği için özel amaçlar dışında kullanılması tavsiye edilmez. Mesela FreeBSD 2.1 sürümü -O2 de istenmeyen kodlara yol açabiliyor.
Optimizasyon genellikle son aşamada yani relase versiyonunda yapılır
% cc -O -o deneme deneme.c
Bu kod deneme programımızın optimize edilmiş sürümünü oluşturacaktır.
Şimdi vereceğimiz ayar ekleri ANSI yada ISO standartı ile ilgilidir.
-Wall
Bu bütün işe yarar uyarıları (warning) açar. Ama ismine rağmen cc nin içinde bulunan bütün uyarıları açmaz.
-ansi
Çoğu ansi dışı programlama özelliklerini kapatır. Yine de bazı ansi standartının dışında kodlamaları kabul edebilir.
-pedantic
Katı bir şekilde bütün ansi standartı dışı özellikleri kapatır.
Bu satırları kullanmadan derlenen bir kod standart dışı özellikler içerebilir. Bazen böyle özellikler çok kullanışlı olmalarına rağmen diğer derleyicilerde çalışmayabilirler. Zaten standart belirlemenin asıl amacı yazılan koda bir çok ortamda destek sağlamaktır. Biz bunu taşınabilirlik olarak isimlendiriyoruz.
Bu yüzden yazdığınız kodu olabildiğince taşınabilir yazın yoksa bir kaç yıl sonra derleyici programları değiştiğinde programınız çalışmayabilir ve kodunuzu baştan yazmanız gerekir.
% cc -Wall -ansi -pedantic -o deneme deneme.c
Bu kod size tamamen standartlara uyan ve hataları ona göre kontrol eden bir program yazmanıza yardımcı olur.
-llibrary
Bağlama zamanında kullanılacak fonksiyon kütüphanesini belirtir.
Ayrılmış , programınızdan bağımsız kütüphaneleri kullanırken programınızın içine kütüphaneyi de eklemek için bu kodu kullanmanız gerekmektedir. Çok klasik bir örnek olarak eğer siz matematik fonksiyonunlarını kullanmak istiyorsanız bu komutu kullanmak zorundasınız.
Kütüphaneler genellikle libxxxx.a şeklinde bulunur ve bunu derleme işlemine eklmek için -lxxxx şeklinde yazarız. Mesala matematk kütüphanesi libm.a dır bunu eklemek için -lm şeklinde girilir.
% cc -o -lm deneme deneme.c
Matematik kütüphanesini ekler.
Eğer siz bir C++ kodu derliyorsanız FreeBSD 2.2 yada daha eski sistemler için -lg++ veya -lstdc++ komutunu eklemek zorundasınız. Diğer bir yöntem derleme programı cc yerine g++ kullanabilirsiniz.
% cc -o deneme deneme.c -lg++(FreeBSD 2.2 ve öncesi)
% cc -o deneme deneme.c -lstdc++(FreeBSD 2.2 den sonraları)
% c++ -o deneme denem.cc
Her biri aynı deneme programını oluşturur. C++ kodu .cc uzantısı ile birlikte verilmiştir. UNIX sistemlerinde C++ kodları
.C
      .cxxveya.ccuzantıları alabilir , MS-DOS® da bu .cpp şeklinde alınıyordu.Yine de gcc .cpp uzantılı dosyaların çalışmasına da izin verecektir.
1. sin() fonksiyonunu kullanan bir program yazmıştım şöyle bir hata alıyorum , ne manaya geliyor ?
/var/tmp/cc0143941.o: Undefined symbol ‘_sin’ referenced
        from text segmentCEVAP : Eğer matematik fonksiyonlarını kullanıyorsanız derleme sırasında matematik kütüphanesini de eklemelisiniz. Mesela :
% cc -o -lm deneme deneme.c
2. Tamam -lm kullanarak aşağıdaki programı yazdım ve derledim.
#include <stdio.h> int main() { float f; f = pow(2.1, 6); printf("2.1 ^ 6 = %f\n", f); return 0; }programı çalıştırdığımda
% ./a.out 2.1 ^ 6 = 1023.000000
sonucunu veriyor ki bu bu sonuç yanlış. Niçin böyle yanlış sonuç veriyor.
CEVAP : Derleme işlemi gerçekleştirirken bir fonksiyon gördüğünde protatipi yoksa standart olarak 'int' tipinde döndüğünü var sayıyor. Bu da farklı sonuçlar vermesine neden oluyor.
3. Peki nasıl çözeriz bu problemi ?
CEVAP : Programa başlarken matematik fonksiyonlarının protatiplerini içeren "math.h " dosyasını eklemelisin. Şu satırları eklemen yeterli olacaktır.
#include <math.h>
... // Burada senin kodların devam ediyor
Programı derledikten sonra
% ./a.out 2.1 ^ 6 = 85.766121
Eğer matematik fonksiyonlarını kullanıyorsan "math.h" dosyasını mutlaka eklemelisin.
4. Deneme.c adlı bir programı derledim ama ./deneme ile çalışmıyor. Öyle bir dosya sistemimde oluşmamış. Nereye gitmiş olabilir ?
CEVAP : Programı derlerken eğer belirtmediyseniz programınız a.out dosyasına çıktı verir. Dosya ismini belirtmek için aşağıdaki kodu girebilirsiniz.
% cc -o deneme deneme.c
5. Tamam derledim ,
'ls' i çalıştırdığımda dosyamın oluştuğunu görebiliyorum ama komut satırına
'deneme'yazınca böyle bir dosyanın olmadığını ('No such file') söylüyor. Dosyayı neden bulamıyor ?
CEVAP : UNIX MS-DOS'tan farklı olarak bulunduğunuz dizin içindeki çalıştırılabilir dosyaları doğrudan görmez. Bu problemi çözmek için isterseniz
'./deneme' yazarak çalıştırabilir yada komut satırına PATH yazdığınızda çıkan dizinlerin birinin altına atıp belirttiğiniz şekilde çalıştırabilirsiniz.Yada PATH değerini dizininizi içerecek şekilde değiştirebilirsiniz.Örnek bir PATH değişkeni
bin:/usr/bin:/usr/local/bin:.
En sondaki nokta eğer bunların içinde bulamıyorsan bulunduğun dizine bak demektir.
6. Programımı yazdım test ismi ile derledim ama çalıştırdığımda hiç bir şey olmadı. Niçin böyle olmuş olabilir ?
CEVAP : /usr/bin altında test isimli başka bir program olduğu için onu çalıştırıyor. Kendi programınızı çalıştırmak için aşağıdaki gibi komut verebilirsiniz.
% ./test
yada daha programınız için daha iyi bir isim seçebilirsiniz.
7. Programımı derledim başta çalışıyordu sonra bir hata oldu "core dumped" uyarısı vererek programdan çıktı. Bu ne demektir ?
CEVAP : Core dump UNIX'in çok eskilerine dayanır. Eğer sizin programınız hata verdi ise hafızadaki bilgileri core file olarak isimledirilen bir dosya içine atar ki hataları tespit etmede kullanılabilir.
8. Tamam faydalı birşey gibi görünüyor ama şimdi ne yapmam lazım ?
CEVAP : Core dosyasını analiz etmek için "gdb" yi kullanabilirsin. (Bölüm 2.6)
9. Program bu hatadan başka "segmentation fault" hatası veriyor. Bu ne manaya geliyor ?
Bu demektir ki ;siz geçerli olmayan bir hafıza işlemi gerçekleştiriyorsunuz. UNIX işletim sistemini kötü niyetli yazılımlardan korumak için geliştirilmiştir.Bu yüzden bir programın kendi adres alanı dışındaki adreslere ulaşmasına izin vermez.Çokça rastlanan problemler şu şekilde olabilir.
NULL pointer a referans vermiş olabilirsiniz.
char* p = NULL;
strcpy(p,"bang!");
Başlangıç değeri atanmamış bir işaretçi(pointer) kullanmış olabilirsiniz.
char* p; strcpy(p,"bang!");
Burada işaretçi(pointer) rastgele bir değer ile başlayacak ve eğer gösterdiği yer uygun olmayan bir hafıza ünitesine işaret ediyorsa işletim sistemi erişime izin vermeyecek.
Tanımladığınız bir dizide geçerli olmayan bir elemana ulaşmaya çalışıyor olabilirsiniz
int dizi[20];
dizi[27] = 7;
Sadece okunabilir bir alana veri kaydetmek istiyor olabilirsiniz.
char* c = "yazıyazıyazı" ; strcpy(c,"bang!");
genellikle bu şekilde tanımlanmış string ler yalnızca okunabilir olarak ayarlanır.
malloc() , free() gibi fonksiyonları yanlış kullanmış olabilirsiniz.
char bar[80];
free(bar);
yada
char* p = malloc(27);
free(p);
free(p);
Bu hataları yapmak her zaman programın çalışmasını durdurmayabilir. Ama her halükarda kötüdür. Bazı sistemlerde bu gibi hatalara karşı duyarlılık fazla iken bazılarında olmayabilir.
10. Bazen core dosyası oluşturduğunda "bus error" hatası veriyor. UNIX kitabına baktım donanım problemi olduğunu söylüyor oysa bilgisayarım hala çalışıyor.Bu doğru mu ?
CEVAP: Eğer gerçekten bir donanım probleminiz yoksa yine hafızanın olmayan bir bölümüne erişmeye çalışmışsınız demektir.
11. Bu core dosyası çok kullanışlı gibi duruyor , acaba hata olmadan da hafızanın içeriğini core dosyasına almam mümkün değil mi ?
CEVAP : Bunu gerçekleştirmek için farklı bir konsola geçin
% ps
burada çalışan programların numaraları görülecek sizin programınızın numarasını bulun
% kill -ABRT pid
pid programınızın numarasını ifade eder.
Bu komut eğer programınız sonsuz döngüye girmişse de işe yarayacaktır.
Alternatif olarak core dosyası oluşturmak için programınızın içinde abort() fonksiyonunu çağırabilirsiniz. Daha detaylı bilgi için "man abort" komutunu kullanabilirsiniz.
Programınızı sonlandırmadan bir core dosyası oluşturmak için gcore programını kullanabilirsiniz. Yine bu programın detayı için man page ' ini okuyabilirsiniz.