plazma - amatör bilgisayar kültürü

Gnu Make ve Makefile Kullanımı

Emirhan (Ragnor) Bayyurt

Make Unix türevi işletim sistemlerinde sıkça kullanılan popüler bir otomatik yazılım derleme aracıdır. Makefile adı verilen dosyalardaki ayarları kullanarak tek komutla projelerin derlenmesini sağlar. Bu dosyalarda sizin ayarlayacağınız parametrelerle projenizin derlenmesi, kurulması, sistemden kaldırılması ya da derlenmiş dosyaların silinmesi gibi işlemler tek komut ile kolayca halledilebilecek hale gelir.

En basit kullanım şekli sadece 'make' komutunun konsolda yazılmasıyladır. Sıklıkla kullanılan diğer parametreler, 'make install', 'make clean' dir. 'make' komutu projeyi derler, 'make install' derlenen projenin sisteme kurulmasına ve 'make clean' de derlenmiş olan proje dosyalarının silinmesine yarar. Siz bu parametre isimlerini kullanmak zorunda değilsiniz ya da parametrelerinizi bunlarla sınırlamak durumunda da değilsiniz ama belli başlı görevler için (kurulum, silme vs.) en fazla kullanılan parametreler bunlardır.

Konsolda 'make' komutunu verdiğinizde make programı o an içinde bulunduğunuz klasörde bir makefile dosyası arar. Bu dosyanın sadece adı 'Makefile' ya da 'makefile' olabilir. Başka bir isme sahip bir makefile dosyası kullanmak istiyorsanız bunu -f parametresi ile make programına bildirmeniz gerekir.

make -f makefile.win

Üstteki örnekte make programı 'makefile' ya da 'Makefile' adında bir dosya aramak yerine sadece 'makefile.win' adında bir dosya arayacaktır.

Bir makefile dosyasının yapısı şu şekildedir.

hedef: gereklilikler
[tab] komutlar

Oldukça basit bir makefile örneği de şöyle olabilir.

all: proje_adi

proje_adi: main.c
       gcc -o projem main.c

clean: 
       rm -rf *.o
       rm -rf projem

Herhangi bir parametre olmadan 'make' komutu verildiğinde çalıştırılan parametre 'all' parametresi olur. 'all' parametresi 'proje_adi' parametresini çalıştırır. O parametrede de main.c dosyası derlenerek projem dosyası oluşturulur. Eğer 'make clean' komutu verilirse klasörde bulunan bütün .o uzantılı dosyalar ve projem dosyası silinir. '.o' uzantılı dosyalar gcc tarafından oluşturulan obje dosyalarıdır. Make'in bir avantajı da bu dosyalarda bir değişiklik yapılmamışsa makefile'da o dosyaya ait olan derleme komutlarını atlar. Bu sayede tekrar tekrar derlemeler yaptığınız projelerinizde derleme zamanları oldukça kısalır.

Makefile dosyalarında sık sık tekrar ettiğimiz komutları bir değişkene atayıp o değişkeni çağırma şansımız vardır. Bu özellik sıklıklar derleyici adı, kütüphane dosyaları, proje dosyaları gibi tekrar eden metinler için kullanılır.

LIBS=-L"/usr/lib" -lSDL -lGL

Yukarıdaki şekilde tanımladığımız değişkeni makefile içinde kullanmanın yolu ise $(LIBS) şeklinde yazmaktır.

Örnek olarak şöyle bir makefile yazabiliriz.

CC=gcc

LIBS=-L"/usr/lib" -lSDL
EXE=projem

all: proje

proje: main.c
       $(CC) -o $(EXE) main.c $(LIBS)

Üstte yazdığımız örnek çok basit kaçmış olabilir ama sadece bir kaynak dosyası yerine 5 ya da daha fazla kaynak dosyanız olduğunu, projede 4-5 farklı kütüphane de kullandığınızı hayal edin. İşte o zaman bu özellik işleri oldukça kolaylaştırıyor.

Bunların dışında makefile'ınız içinde açıklama satırı yazmak için satırın başına '#' karakterini koymanız yeterlidir. Uzun satırları bölmek için '\' karakterini kullanıp, alt satırdan yazmaya devam edebilirsiniz. $@ değişkeni o anda kullanılan hedefin adını belirtir, aynı şekilde $< değişkeni de kullanıldığı andaki girdi dosyasını belirtir. Son olarak dikkat etmeniz gereken şey ise en başta makefile yapısını gösterir verdiğim örnekte de yazdığı gibi hedef'in altındaki komutları yazarken başına boşluk bırakmayacaksınız, orada kullanmanız gereken şey 'tab' karakteridir. Boşluk bırakırsanız make programı hata verip sonlanacaktır.

Son olarak size projelerinizde kullanmanız için ufak ama etkili bir makefile örneği verip yazımı burada sonlandırıyorum.

# projenizde kullanacaginiz derleyiciler
CPP  = g++
CC   = gcc

OBJ=$(SOURCES:.cpp=.o)

# projenizde kullandiginiz kutuphaneler 
# bu ornekte ben sdl kitapliklari kullaniyorum
LIBS =  -L"/usr/lib" -lSDLmain -lSDL \
              -lSDL_mixer -lSDL_ttf

# projede kullandiginiz kutuphanelerin .h 
# dosyalarinin bulundugu klasorler
INCS =  -I"/usr/include" -I"/usr/include/SDL"
CXXINCS =  -I"/usr/include" 
CXXFLAGS = $(CXXINCS)  
CFLAGS = -c $(INCS)  

# sources degiskenine projenizdeki 
# kaynak kod dosyalarini (.c yada .cpp)
# aralarinda bir bosluk birakarak yazin, 
# en basta main dosyaniz olsun
SOURCES= main.cpp

# buraya projeniz derlendiginde cikacak 
# executable dosyanin adi yazilacak
BIN  = proje_adi
RM = rm -f

all: $(SOURCES) $(BIN)

$(BIN): $(OBJ)
    $(CC) $(OBJ) -o $(BIN) $(LIBS)

.cpp.o:
    $(CC) $(CFLAGS) $< -o $@

clean: 
    ${RM} $(OBJ) $(BIN)

Hepsi bu kadar. Umarım yazım size faydalı olmuştur.

plazma - 2008