/*
 * Copyright (c) 2004 Barış ŞİMŞEK.
 * Permission is granted to copy, distribute and/or modify this document
 * under the terms of the GNU Free Documentation License, Version 1.2
 * or any later version published by the Free Software Foundation;
 * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
 * Texts.  A copy of the license is included in the section entitled "GNU
 * Free Documentation License".
 *
 * Bu belgenin telif hakları 'GNU Free Documentation License'
 * lisansı şartları altında Barış ŞİMŞEK'e aittir.
 *
 * Kök: http://www.acikkod.org
 * Sürüm No: 1
 * İlk baskı: 2004-08-18
 * Son güncelleme: 2004-08-18
 *
 */

Kod Geliştirme-1: Program Kütüphaneleri

Program kütüphaneleri, daha sonra yeni yazılacak programlara dahil edilmek üzere saklanan derlenmiş hazır kod ve veri dosyalarıdır. Kütüphane dosyaları, modüler programlama sunarlar.

Statik Kütüphaneler

Statik kütüphaneler, yeniden derlenmeye ihtiyaç duymaksızın programa derleme aşamasında yani çalıştırılmadan önce eklenir. Lib dizinlerindeki “.a” uzantılı dosyalar statik kütüphanelerdir. Derleme zamanını azaltmak için statik kütüphaneler kullanılıyordu. Ancak günümüzün hızlı bilgisayarları için derleme zamanı problem olmaktan çıktı. Bu nedenle statik kütüphaneler artık tercih edilmemektedir. Ancak yine de kütüphane kodlarını açmak istemeyenler için kullanışlıdır.

Statik kütüphane oluşturmak için ar(1) komutu kullanılır.

# ar rc libtest.a test.o util.o  

Bu komut “libtest.a” kütüphanesini oluşturur, test.o ve util.o object dosyalarını bu kütüphaneye ekler. “c” parametresi ile eğer kütüphane yoksa oluşturulması belirtilmiş olunur. Eğer varsa object dosyları bu kütüphaneye ekler. “r” parametresi ile eski object dosyaların yenileri ile değiştirilmesi talep edilir.

Yeni oluşturulan veya değiştirilen bir kütüphane dosyasını yeniden indekslemek gerekir. Bu işlem derleme sırasında derleyicinin sembolleri kontrolünü hızlandırmak içindir. İndeks oluşturmak için ranlib(1) kullanılır.

# ranlib libtest.a  

Derlenecek bir programa daha önce oluşturduğumuz bir kütüphaneyi dahil etmek için gcc(1) ‘ye –l ile kütüphane ismi parametre olarak verilmelidir. Bu işlem için tercih edilmese de doğrudan ld(1) kullanılabilir.

# gcc prog.o –L/home/simsek/libtest –ltest  

-l ile kütüphane ismini verirken dosya isminin başındaki “lib” in kaldırıldığına dikkat edilmeli. –L parametresi gcc'ye kütüphaneleri ararken hangi dizinleri kullanacağını bildirir.

Aşağıda bir kütüphane oluşturma ve kullanma senaryosu mevcut:

# cat main.c
#include <stdio.h>
/* fonksiyonlar external tanimlanmali */
extern void test();
extern void util();
int main() {
  printf("main icinde\n");
  /* Kutuphane icinden fonksiyon cagiralim */
  test();
  util();
  return 0; 
} 
# cat test.c
int test() {
  printf("Test icerisinde\n");
  return 0;
}
# cat util.c
int util() {
  printf("Util icerisinde\n");
  return 0;
}
# gcc -c test.c
# gcc –c util.c
# ar rc libtest.a test.o util.o
# ranlib libtest.a
# gcc -c main.c
# gcc main.o -L /home/simsek -ltest -o testprog

Son satırda kütüphane fonksiyonlarını kullanan program derlenip ‘testprog' isimli çalışabilir dosya derleyici tarafından oluşturuldu. Program çalışıtırıldığında aşağıdaki çıktıyı verecektir:

# ./testprog
main icinde
Test icerisinde
Util icerisinde

Ortak Paylaşılan (Shared) Kütüphaneler

Paylaşılan (shared) kütüphaneler, program çalıştırıldığında programa dahil edilirler. Programın içerisine gerçekten kod eklenmez. Paylaşımlı kütüphaneden bir fonksiyon cağrılan yerlere, kütüphaneye bir referans verilir. Kütüphaneyi kullanan bütün programlar bu şekilde aynı fonksiyon kütüphanesini ortak kullanırlar.

Paylaşımlı her kütüphane “soname” denilen özel isme sahiptir. “soname” isimleri gerçek isimlerine bir linktir. Ayrıca derleyicinin bir kütüphaneyi talep ettiğinde kullandığı linker ismi vardır. Bu, versiyonu olmayan bir soname olarak düşünülebilir.

simsek@mail:/usr/lib$ ls libz*
libz.a libz.so.1@ libz.so.1.2.1.1*

Listede görülen libz.a statik kütüphaneye aittir. libz.so.1 ise libz.so.1.2.1.1 paylaşımlı kütüphanesine link olan soname'dir. Bu kütüphane için linker ismi libz.so'dur.

Programlar içerisinde soname'ler tutulur. Bu sayede kütüphanede bir değişiklik yapıldığında yeni kütüphane kullanıma alınmış olunur.