GCC, GNU Projesi tarafından üretilen ve çeşitli programlama dillerini, donanım mimarilerini ve işletim sistemlerini destekleyen bir optimize edici derleyicidir.

GCC, GNU araç takımının önemli bir bileşeni ve hem GNU hem de Linux çekirdeğiyle ilgili çoğu proje için standart derleyicidir. GNU/Linux dağıtımlarının birçoğunun çekirdeği ve bu dağıtımların üzerinde çalışan uygulamaların neredeyse hepsi GCC ile derlenir ve kullanıma hazır hale getirilir. GCC, hem bir araç hem de ilham verici bir örnek olarak özgür yazılımın büyümesinde önemli bir rol oynamıştır.

1987’de Richard Stallman tarafından 1.0 sürümü yayımlandığında yalnızca C programlama dilini desteklediği için GNU C Compiler olarak adlandırıldı. GCC, aynı yılın Aralık ayında C++’ı derlemek için de genişletildi. Daha sonraları Objective-C, Objective-C++, Fortran, Ada, D, Go ve daha birçok dil için de önyüzler geliştirildi.

GCC, herhangi başka bir derleyiciden daha çok platforma ve komut seti mimarisine aktarılmıştır ve hem özgür yazılım hem de kapalı kaynak yazılım geliştirilmesinde yaygın olarak kullanılmaktadır. GCC, ARM tabanlı ve Power ISA tabanlı yongalar dahil olmak üzere birçok gömülü sistem için de mevcuttur.

GCC’nin tarihçesi

1983’ün sonlarında Richard Stallman, GNU işletim sistemini geliştirirken Amsterdam Compiler Kit’in geliştiricisi Andrew S. Tanenbaum‘dan bu yazılımı GNU için kullanma izni istedi.

Tanenbaum ona derleyicinin sadece üniversitede kullanımının ücretsiz olduğunu söylediğinde Stallman farklı bir derleyici üzerinde çalışmaya karar verdi. İlk planı, Len Tower ve birkaç kişiden daha biraz yardım alarak Lawrence Livermore Ulusal Laboratuvarı’ndaki Pascal’ın genişletilmiş bir sürümü olan Pastel ile yazılmış mevcut bir derleyiciyi C’de yeniden yazmaktı.

Stallman, Livermore derleyicisi için yeni bir C ön ucu yazdı, ancak bunun megabaytlarca yığın alanı gerektirdiğini ve sadece 64 KB’lık 68000 Unix sisteminde çalışmasının imkansız olduğunu fark etti. Bunun üzerine sıfırdan yeni bir derleyici yazmak zorunda kalacağı sonucuna vardı. Stallman, yazdığı C önyüzünü daha sonra kullansa da Pastel derleyici kodunun hiçbir bölümü GCC’de yer almadı.

GCC, ilk olarak 22 Mart 1987’de MIT’den FTP aracılığıyla yayımlandı. Stallman geliştirici olarak listelenmiş, ancak katkılarından dolayı başkalarına da atıfta bulunmuştur: RTL’yi bir ara dil olarak kullanma fikri için Jack Davidson ve Christopher Fraser, önişlemcinin çoğunu yazdığı için Paul Rubin ve ayrıştırıcının bazı parçaları, RTL oluşturucu, RTL tanımlamaları ve Vax makine açıklamaları için Leonard Tower bu isimler arasındaydı.

Peter H. Salus tarafından “ilk özgür yazılım başarısı” olarak tanımlanan GNU derleyicisi, Sun Microsystems’in geliştirme araçlarını işletim sisteminden ayırdığı ve önceki birleşik paketin fiyatının çok daha üstüne ayrı ayrı satmaya başladığı sırada ortaya çıkmıştı. Bu durum Sun’ın birçok kullanıcısının Sun Microsystems’in araçları yerine GCC’ye geçmesine neden oldu.

Stallman, 1990’da GNU Emacs’i ana projesi olarak açıklarken GCC, 13 farklı bilgisayar mimarisine destek vermeye, ancak satın alınarak kullanılabilecek birkaç derleyiciden daha iyi performans göstermeye başlamış ve birkaç şirket tarafından ticari olarak kullanılmaya başlanmıştır.

GCC günümüzde çok çeşitli komut seti mimarilerine aktarılmış ve hem özgür hem de kapalı kaynak yazılımların geliştirilmesinde önemli bir araç olarak yaygın olarak kullanılmaktadır. GCC, ARM tabanlı ve Power ISA tabanlı yongalar dahil olmak üzere birçok gömülü sistem için de mevcuttur. Derleyici, PlayStation 2, PlayStation 3’ün Cell SPE’si ve Dreamcast gibi video oyun konsolları da dahil olmak üzere çok çeşitli platformları hedefleyebilir. GCC, diğer tüm derleyicilerden daha çok türde işlemciye ve işletim sistemine aktarılmıştır.

GCC’nin desteklediği diller

GCC’nin 11.1 sürümü, C (gcc), C++ (g++), Objective-C, Fortran (gfortran), Ada (GNAT), Go (gccgo) ve D programlama dilleri için önyüzler içerir. OpenMP ve OpenACC paralel dil uzantıları GCC 5.1’den beri desteklenir.

Ayrıca GCC 7 öncesi sürümler Java’yı (gcj) destekleyerek Java’nın yerel makine koduna derlenmesine olanak tanır. Özgür Java araç takımı geliştirilmesi çoğunlukla OpenJDK içinde gerçekleştirildiğinden Java desteği 30 Eylül 2016’da GCC’den kaldırıldı.

Pascal (gpc), Modula-2, Modula-3 ve VHDL (GHDL) gibi birçok dil için üçüncü taraf önyüzler de mevcuttur. Rust ve Unified Parallel C için GCC UPC derleyicisi gibi ek dilleri destekleyen birkaç deneysel kaynak kod dalı da mevcuttur.

GCC’nin tasarımı

GCC’nin harici arayüzü Unix kurallarını takip eder. Kullanıcılar, komut argümanlarını yorumlayan, gerçek derleyiciyi çağıran, çıktıda assembler’ı çalıştıran ve ardından duruma bağlı olarak, eksiksiz bir çalıştırılabilir ikilik dosya oluşturmak için bağlayıcıyı çalıştıran, dile özgü bir sürücü programını, örneğin C için gcc’i, C++ için g++’ı kullanır.

Dil derleyicilerinin her biri, kaynak kodunu okuyan ve makine koduna dönüştüren ayrı bir programdır. Hepsinin ortak bir iç yapısı vardır. Dil başına bir önyüz, kaynak kodunu o dilde ayrıştırır ve bir soyut sözdizimi ağacı üretir.

Bun ağaçlar, gerekirse GENERIC form adı verilen orta ucun girdi temsiline dönüştürülür. Orta uç daha sonra programı kademeli olarak nihai biçimine dönüştürür. Derleyici optimizasyonları ve statik kod analiz teknikleri koda uygulanır. Optimizasyonlar, çoğunlukla mimariden bağımsız GIMPLE gösterimi ve mimariye bağlı RTL gösterimi olmak üzere çoklu gösterimler üzerinde çalışır. Son olarak, makine kodu, Jack Davidson ve Chris Fraser’ın bir algoritmasına dayanan mimariye özgü desen eşleştirmesi kullanılarak üretilir.

GCC, Ada önyüzünün bileşenleri haricinde çoğunlukla C ile yazılmıştır. GCC paketleri genellikle Ada ve C++ standart kütüphanelerini de içerir. Bazı platformlarda paketler ayrıca, hedef işlemcinin doğrudan gerçekleştiremeyeceği aritmetik işlemleri işlemek için tasarlanmış, makineden bağımsız C ve işlemciye özgü makine kodunun bir kombinasyonuyla yazılmış, düşük düzeyli bir çalışma zamanı kitaplığı olan libgcc’yi de içerir.

GCC’nin kullanımı

GCC’yi kısaca tanıdıktan ve tarihçesine göz attıktan sonra şimdi onu nasıl kullanabileceğimize yoğunlaşabiliriz. Bir bütünleşik geliştirme ortamı kullanıyorsanız büyük ihtimalle hiçbir ek işlem yapmadan halihazırda GCC’yi arka planda kullanıyorsunuzdur. Biz şimdi burada GCC’nin terminal üzerinde elle nasıl kullanılacağını temel düzeyde inceleyeceğiz.

Sisteminizde gcc derleyicisinin hangi sürümünün yüklü olduğunu kontrol etmek için terminalde aşağıdaki komutu kullanabilirsiniz:

gcc --version

Temel GCC sözdizimiyse şu şekilde ifade edilebilir:

gcc [seçenekler] [kaynak_kod_dosyaları] [nesne_dosyaları] [-o çıktı_dosyası]

Basit bir C programı yazıp bunu Pardus’ta GCC’nin yardımıyla nasıl çalışmaya hazır hale getirebileceğimize bakalım şimdi de. Bir C programını çalıştırılabilir hale getirmek için üç temel işlem adımını takip etmemiz gerekir:

  • Yazım: Derlenmek istenen C programının yazımı.
  • Derleme: Programda herhangi bir hata olup olmadığı kontrol edilir ve çalıştırılabilir hale getirilir.
  • Çalıştırma: Programın çıktısını görmek için açılması.

Yukarıdaki bu işlem adımlarını aşağıdaki örneklerle detaylandıralım ama bunu yapmadan önce farklı programlama dillerini derlerken kullanılabilecek seçeneklerden birkaçına göz atalım:

  • gcc -c: Kaynak dosyaları, başka nesne dosyalarına bağlanmaksızın nesne dosyalarına derler.
  • gcc -Idir: Tanımlanmamış veya öntanımlı dizinlerde yer almayan başlık dosyalarının dizinlerini içerir.
  • gcc -llib: Çıktı dosyasını kütüphane dosyalarına bağlar.
  • gcc -o çıktı_dosyası: Çıktı dosyasının hangi adla oluşturulacağını tanımlar.
  • gcc -W: Derleme sırasında tüm uyarı mesajlarını devre dışı bırakır.
  • gcc -Wall: Derleme sırasında tüm uyarı mesajlarını etkinleştirir.
  • gcc -Wextra: Derleme sırasında ekstra uyarı mesajlarını etkinleştirir.

Sevdiğiniz bir terminal tabanlı veya grafik arayüzlü metin düzenleyiciyi kullanarak aşağıdaki C ile yazılmış Merhaba Dünya kaynak kodunu bilgisayarınızdaki bir dizine merhaba.c ismiyle kaydedin:

#include <stdio.h>
int main(void)
{
double i = 'a';
printf("\n Merhaba Dünya [%d]\n", i);
return 0;
}

Daha sonra terminali açarak bu dizine geçin ve aşağıdaki komutu çalıştırın:

gcc merhaba

Yukarıdaki komutla derleme işlemini yaptığınızda çıktı dosyası a.out adıyla oluşacaktır. Derlenirken özel bir isim verilmezse oluşturulan dosyalar için öntanımlı isim Linux tabanlı sistemlerde a.out, Windows tabanlı sistemlerde a.exe‘dir.

Oluşturulan dosyayı çalıştırmak için de terminalde dosyanın yolunu ve adını yazmak yeterlidir:

./a.out

Seçenek olarak -o kullanarak çıktı dosyasının adını açıkça belirtmeyi de seçebiliriz:

gcc merhaba.c -o merhaba

Bir C programını derlerken uyarıları görmek için -Wall seçeneğini kullanmamız gerekiyor. Önceki kodumuzu aşağıdaki gibi değiştirip kaydedelim:

#include <stdio.h>
int main(void)
{
double i = 'a';
printf("\nMerhaba Dünya [%d]\n", i);
return 0;
}

Bu sefer derlemek için de şu komutu kullanalım:

gcc -Wall merhaba.c -o merhaba

-Wall seçeneğini kullandığımız için kodumuzda oluşabilecek uyarıları görebiliriz. Yukarıdaki kod tam olarak doğru olmadığı için burada %d biçiminin int türünde bir argüman beklerken double türde bir argüman aldığıyla ilgili bir uyarı görürüz.

Önişlenmiş çıktı dosyası incelenmek isteniyorsa -E seçeneği kullanılabilir. Öntanımlı çıktı stdout’ta üretileceği için çıktımızı başka bir dosyaya yönlendirmek iyi bir fikir olacaktır:

gcc -E merhaba.c > merhaba.i

Derleme sırasında oluşturulan ve derleme işlemi sonunda otomatik olarak silinen tüm ara dosyaları derlemenin yapıldı dizinde tutmak için --save-temps seçeneği kullanılabilir:

gcc --save-temps merhaba.c

Bu komut sonrasında a.out haricinde a-merhaba.i, a-merhaba.o ve a-merhaba.s dosyaları da derleme dizininde kalacaktır.

.i uzantılı dosyanın önişlenmiş kodları tuttuğunu zaten az önce öğrenmiştik. Tahmin edilebileceği gibi .s uzantılı dosya programın Assembly karşılığını içerir, .o uzantılı dosya da kaynak koddan oluşturulan nesne dosyasıdır.

Şimdi kısaca birkaç seçeneğe daha göz atalım:

-lm: math.h kütüphanesini kaynak dosyamıza bağlar, -l seçeneği, belirli bir kütüphaneyi bağlamak için kullanılır, math.h için ise -lm kullanırız. Örneğin programımız Xlib grafik rutinlerini içeriyor olsaydı -lX11 kullanmamız gerekirdi. Örnek bir kullanımı şöyle düşünebiliriz:

gcc faktoriyel-hesaplama.c -o faktoriyel -lm

-std=c17: Bu seçenek, kaynak kodunu derlemek için standartların c17 sürümünün kullanılmasını sağlayacaktır. Daha eski bir standart sürümünü kullanmak isterseniz -std=c17 seçeneğini kullanabilirsiniz. Daha yeni bir standart sürümünü kullanmak isterseniz de -std=c2x seçeneğini kullanabilirsiniz. Sondaki x harfinden de anlaşılabileceği gibi standardın bu sürümü henüz son halini almamıştır.

Elbette tek bir yazıda GCC hakkında her şeyden bahsetmemiz mümkün değil ne yazık ki. Bununla birlikte GCC hakkında temel bilgi sahibi olduk ve öğrendiklerimiz sayesinde farklı kullanım seneryoları için yapacaklarımızı da kolayca keşfedebiliriz.

Gördüğünüz gibi GCC’nin kullanımı çok kolaydır ve GNU/Linux işletim sisteminde C programlarını çalışır hale getirmek için bize birçok seçenek verir. Pardus’ta ilgili tüm paketlerin kurulu olduğundan emin olduktan sonra C, C++, Ada ve daha birçok dilde geliştirme yapmaya başlayabilirsiniz.

Kaynaklar

Ek Okumalar