12 Mart 2014 Çarşamba

GNU g++, gcc, make dosyası

gcc
gcc GNU ile kullanılan derleyici. Aslında gcc jenerik bir derleyici. Verilen dosya uzantısına göre gerekli olan derleyicisi çağırıyor. Örneğin c++ dosyası verilirse g++ derleyicisini çağırıyor. Bu konu ile ilgili daha detaylı bilgiyi burada bulabilirsiniz.

g++

Bir c++ programını derlerken aslında g++ ile beraber bazen cc1 veya cc1plus isimli bir başka programın daha çalıştığını görüyoruz. cc1plus, g++ tarafından çağırılan gerçek derleyici oluyor.

Bazı gcc seçenekleri
-c
Verilen kaynak dosyayı sadece derler ancak linklemez.

-o
Belirtilen object dosyasını oluşturur ve linker. Örnek:

-c seçeneği yerine direkt -o kullanılırsa, -c işlemini de yerine getirilir.
g++ -o main main.cpp Sum2.cpp
 -dM
Tüm gömülü (built-in) preprocessor macrolarını yazar. Örnek: Windows'ta _WIN32 de gömülü bir macro'dur

-E
Preprocessing aşamasından sonra durur. Böylece preprocessing'den geçmiş kaynak kodu görebilmemizi sağlar.
 
-l
verilen kütüphane ile linkler. Örnek:
gcc -lasound . Dosya sisteminde libasound.a olması gerekir.

Not : gcc ile libc.so (yani c runtime) otomatik olarak linklenir.

-L
Linklenecek kütüphanelerin bulunduğu dizini belirtir. Örnek:
gcc -L.

-pg
Örnekte gprof için kodun instrument edilmesi gösterilmiş.

Linker
Burada verilen bir metodun değiştirmek örneği var.

nm komutu
name list anlamına gelir. Link işlemi sonucunda çıkan .so dosyalarında sembol aramak için nm komutu kullanılabilir. Örnek:

nm -A /usr/lib/libc.so | grep scanf
/lib/libc.so:0000000000042a90 T scanf

PowerPC ve nm
nmppc.exe komutu ile bakılabilir. Aslında nm bir unix komutudur. Ö–rnek:
nmppc.exe lib.a
Aşağıdakine benzer satırlar görülür. D sembolün data segmente yerleşŸtirildiğŸini (değişŸkenin ilklendirildiğini, değŸer atandığını belirtir), B ise bss segmente yerleşŸtirildiğŸini (değişŸkenin ilklendirilmediğŸini, değŸer atanmadığını belirtir) gösterir.

_TERRAIN_PASSABLE                           |00000008|   D  |
_TERRAIN_SOME_WHAT_PASSABLE|00000004|   B  |

make dosyası

make dosyasını renkledirilmiş görmek için Notepad++ içinde Language / Makefile menüsünü tıklamak lazım.

make komutuna dışarıdan parametre girmek
3 yöntem var.
1. ortam değişkenleri make dosyası içinde aynen kullanılabilir.
2. Komut satırından. Örnek:
make target FOO=bar
3. Ana make dosyasından export ederek. Örnek:
# Do like this
CFLAGS=-g
export CFLAGS
target:
$(MAKE) -C target
make ve target
make dosyasında target aşağıdaki gibi verilir.
target : dependencies
            commands

Basit bir örnek:
dependency olarak tüm dosyalar
Aşağıdaki gibi yapabiliriz.
SRC_ROOT := ./src
SRC_FILES := $(notdir $(shell find $(SRC_ROOT) -path "*/.svn" -prune -o -type f -name "*.cpp" -print))

target için dependency
Eğer target'ımızın dependency olarak gördüğü bir başka target, makefile içinde ve diskte yoksa aşağıdaki gibi bir hata alırız. Hatalı durumlarda komut satırına Stop. yazılır.
make: *** No rule to make target `b', needed by `a'.  Stop.

Eğer target'ımız bir önceki make komutundan sonra değişmemiş ise, aşağıdaki Nothing to be done ile başlayan cümleyi alırız.
make: Nothing to be done for `all'.

target için komutu
Target için örnek command
fileClient:
    $(CC) $(CFLAGS) $(LDFLAGS) src/main.c -o fileClient

default target
Default target makefile içindeki ilk tanımlı target'tır. makefile target ismi verilmeden çağırılırsa default target çalışır.


.phony target
phony kelime anlamı olarak sahte demek. target'ımızın başına .phony gelirse target'ımı ile aynı isimde bir başka dosya olsa bile, komutumuz çalışır. Örnek''te gösterildiği gibi, "make clean" yapılırsa clean isimli bir dosya olsa bile komut çalışır.
.phony : clean
clean :
         rm -rf *.o
Bir başka örnek:

değişken tanımlama ve ekleme örneği
Makefile içinde anladığım kadarıyla iki çeşit değişken var. İlki değişken := değer şeklinde tanımlanıyor ve değişkenin değeri, makefile ilk defa okunurken bir kereliğine hesaplanıyor. Diğeri ise macro gibi ve değişken = değer şeklinde tanımlanıyor. Bu tür ise değişkenin geçtiği her yere değerinin yapıştırılması gibi düşünülebilir.

Değeri Hemen Hesaplanan Değişken
Örnekler:

LDDIRS := -L$(ORACLE_LIB)
LDDIRS += -L$(ORACLE_LIB)


Macro Değişken

Makefile işlenirken $(Değişken İsmi) şeklinde metinler aynı C'deki #define ile tanımlanan macro gibi metin açılımına uğrarlar. Yani değişken ismi yerine değişkenin değeri varmış gibi işlem yapılır.

default değişkenler
makefile'daki CC default bir değişkendir ve sistemdeki C derleyicisini belirtir.

Bir başka dosyadaki değişkenleri dahil etmek
Aşağıdaki gibi yapılabilir.
include $(DIR)/make/Makefile.vars

if koşulu

ifeq($(Variable),0)
  DIRECTORY := ./debug
else
  DIRECTORY := ./release
endif


Include Path Tanımlama
INCLUDES := -I../../include\
                         -I../../src
şeklinde çok satıra tanımlanabilir

Make İçindeki Komutlar
başka make dosyasının çağırılması
Genelde tüm projeleri derleyen en üstte bir make dosyası bulunur. Tepedeki make dosyasından başka make dosyalarını çağırmak için make -C komutu kullanılabilir. Kendi değişkenimizi, diğer make dosyasına da aşağıdaki gibi geçebiliriz.
Örnek:
subsystem:
         $(MAKE) -C subdir CPU=$(CPU)
cp
all :
 $(CP) ./debug/*.exe $(OUTPUT)

mkdir
Eğer bir dizin yoksa yaratmak için kullanılır
if [! -d "$(DIR)"]; then mkdir -p "$(DIR)";fi

notdir
SRC_FILES := $(notdir $(foreach dir; $(DIRS), $(wildcard $(DIR)/*.c $(DIR)/*.cpp) ) )

rm
clean :
     $(RM) $(OUTPUT)

subst
Windows dizinini, Unix dizinine çevirir
HOME := $(subst \,/, $(HOME))

Shell ile çalıştırılan komutlar
mkdir
Aşağıdaki örnekte değişken okunurken, dizin yaratma gösterilmiş
find
Örnek:
HEADER = $(shell find . -name '*.h')

make clean
Bu komutla make'in yarattığı her şey temizlenir.

make distclean
Bu komutla make dosyası dahil ./configure ile yaratılan her şey silinir.

make file çıktısı
make komutu errror ve warningleri stderr akımına veriyor. Bu akımı da stdout'a yönlendirmek ve çıktı içinde hata aramayı kolaylaştırmak için aşağıdaki komut kullanılabilir.

make 2>@1 | grep warning -A 2 -B 2

-A 2 -B 2 seçenekleri warning içeren satırın 2 üst (above) ve 2 alt (below) satırını da gösterir ki hatayı daha rahat görebilelim.

Hiç yorum yok:

Yorum Gönder