
Bu yazımızda Cross-Compile ile ARM tabanlı sistemler için derleme yapmayı ve derlenen dosyayı cihaz üzerinde nasıl çalıştırıldığını anlatacağız. Compile ve cross-compile arasındaki farklar, ne amaçla kullanıldıkları ve nasıl fayda sağladıkları üzerine değinilecektir. CodeSourcery firmasının ARM derleyicisinin kurulumu anlatılacaktır.
Cross-Compile Nedir?
Cross-Compile bir işlemci üzerinde başka bir işlemcide çalışacak şekilde dosyanın derlenmesidir diyebiliriz. Mesela kullandığımız laptop x86 intel serisi olup, beagle board ARM serisi kullanmaktadır. Fakat biz intel üzerinde ARM çekirdeği için dosya derleyebiliriz işte bu olaya cross-compile denir. Normal derlemeden tek farkı budur. Haliyle birde hedef işlemcinin derleyicisini bilgisayarımıza yüklememiz gerekir.
Neden Cross-Compile?
Aklımıza neden buna ihtiyaç duyayım hangi işlemcide çalıştıracaksam onun üzerinde derlerim gibi bir soru gelebilir. Fakat cross-compile olayının bir çok artısı vardır.
Hız:
Bilgisayarımızı ele alalım üzerinde ortalama 2.5 Ghz işlemci olan hızlı bir cihazdır. Kodumuzu derleme süresi belki saniyeler sürecektir. Fakat diğer taraftan ARM tabanlı bir sistemi ele alalım mesela beagle board. Beagle board bile uç bir örnektir fakat üzerindeki 720Mhz işlemci ile kodumuzu bazen 10-15 dk da derleyebilir. Haliyle çok daha karmaşık sistemleri düşündüğümüzde mesela kernel derleme gibi, ARM tabanlı sistem üzerinde bu kerneli derleseydik kurulumu belki 1 günden fazla sürebilirdi. Kerneli bilgisayarımızda beagle board için derlediğimizde ise yaklaşık 20-30 dk arasında derlemeyi bitirebiliyoruz. Buda hız faktörünün önemli bir etken olduğunu gösteriyor. Derleme sonrasında oluşan .o uzantılı dosya windows kullanıcıları için sanki .exe gibi sayılabilir. Yani çalışmaya hazır dosyadır.
Yetenek:
Derleme işlemi kaynak dosyalara çok fazla ihtiyaç duyar. Mesela basit bir hello.c dosyasını derleyeceğimizi düşünelim. İçerisinde kullanacağımız kütüphaneler ve onların kullandığı kütüphaneleri düşünün. Basit bir printf fonksiyonunun arka planda neler çalıştırdığını düşünün. Ya da yine aynı şekilde bir kernel derlediğimizi var sayalım yüzlerce .c dosyası derliyorsunuz ve bunlarında arkasında çağırdığı binlerce kütüphane var. Gelmek istediğim nokta hedef cihazınızın hafızası ve yeterliliği bu kütüphaneleri kaldıramayabilir. Fakat derleme sonrası oluşan dosyayı çalıştırabilir. Diğer yönden bilgisayarımız hafıza konusunda ve yeterlilik konusunda gayet üst seviyededir. Bu yüzden yetenek konusu da büyük bir avantaj sağlar diyebiliriz.
Kolaylık:
Kendi bilgisayarımızı kullandığımızda kullanıcı ara yüzüne sahip kolayca hataları bulabilen çeşitli derleyici programlar yardımıyla debug yapabilen bir sisteme sahip oluyoruz. Aksine hedef cihazda bu iş biraz daha komplike ve uğraştırıcı olacaktır. Bu yüzden kolaylık açısından da cross-compile bir avantaj sağlar diyebiliriz.
İlk olarak compile işlemini gerçekleştireceğimiz bir örnek yapacağız ardından cross-compile işlemini anlatacağız böylelikle aralarındaki farkı daha iyi anlayabiliriz.
Compile Operasyonu
Gerekli Dosyalar:
Uygulamaya geçmeden önce compile işlemi için gerekli dosyaların bilgisayarımızda yüklü olduğundan emin olmalıyız. Eğer yüklü değilse terminal üzerinden gerekli paketleri yüklememiz gerekiyor.
[codesyntax lang=”text”]
sudo apt-get install gcc
sudo apt-get install build-essential
sudo apt-get update
[/codesyntax]
Uygulama:
Bir hello world uygulaması ile compile olayını anlatmaya çalışacağız.
[codesyntax lang=”c” title=”hello.c”]
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int a = 4711;
printf("Merhaba dünya: %d\n", a);
return(EXIT_SUCCESS);
}
[/codesyntax]
Bu kodu oluşturduğumuz boş bir dosyanın içine kopyalıyor ve dosyayı hello.c olarak kaydediyoruz.
Daha sonra terminal üzerinden dosyanın bulunduğu dizine gelmemiz gerekiyor. Şu an benim dosyam masa üstünde olduğu için terminal üzerinden masa üstüne geliyorum. (cd /home/<kullanıcı adı>/Desktop) Ardından derleme işlemini yapıyorum. (gcc hello.c -o hello) Burada yaptığım şey hello.c dosyasını derleyerek .o uzantılı derlenmiş bir dosya elde ediyorum. Sistemim için çalıştırılmaya hazır bir dosya oluşuyor da denilebilir. Terminal üzerinde uygulamayı yapalım.
[codesyntax lang=”text”]
cd /home/tess/Desktop
gcc hello.c -o hello
./hello
[/codesyntax]
Derleme işlemini tamamladıktan sonra .o uzantılı dosyayı ./ uzantısı ile kolayca çalıştırabiliriz. Terminalde merhaba dünya yazısını görüyoruz. Şu an yüklü olan gcc intel mimarisi üzerine yüklendiği için derlemeyi de yine bu mimari için yapmaktadır. Bu yüzden oluşan .o uzantılı dosyayı kendi bilgisayarımızda rahatça çalıştırabiliyoruz. Aynı şekilde Eğer bilgisayarımızın işlemcisi ARM olsaydı yine aynı yöntemle derleme işlemini yapacaktık. Çünkü o zaman yüklü olan gcc ARM mimarisi üzerinde çalıştığı için derlemeyi ona göre yapacaktı. Cross-compile olayında ise iki farklı işlemci söz konusu oluyor.
Makefile Oluşturma
Diyelim ki kodumuzu güncelledik ve for döngüsü ekledik. Bu sefer bir makefile yazacağız.
[codesyntax lang=”text” title=”hello.c”]
#include <stdlib.h> #include <stdio.h> int main(int argc, char **argv) { int i; for(i=0; i<10; i++) { printf("merhaba dünya: %d\n", i); } return(EXIT_SUCCESS); }
[/codesyntax]
[codesyntax lang=”c” title=”makefile”]
hello: hello.c
gcc hello.c -o hello
[/codesyntax]
Makefile yazarken gcc ile başlayan satırdan önce mutlaka tab olmalıdır.
Daha sonra terminal üzerinden makefile dosyamızı çalıştırıyoruz.
[codesyntax lang=”text”]
make
[/codesyntax]
Böylelikle makefile kullanımını da kavramış oluyoruz.
Cross-Compile Operasyonu
Burada da yapacağımız şey çok farklı olmayacak fakat bu sefer oluşturduğumuz .o dosyası kendi sistemimizde çalışmayacaktır. Çünkü başka bir sistem için oluşturulmaktadır.
Gerekli Malzemeler:
Örneğimizi ARM işlemciler için yapacağımız için ARM derleyici indirmemiz gerekiyor. Öncelikle gerekli derleyiciyiindiriyoruz. IA32 GNU/Linux Installer dosyasını indirip kurulumu onun üzerine yaptım. Yazının devamında da bu şekilde bir anlatım olacaktır.
İndirdikten sonra /home/<kullanıcı adı> dizinine getiriyoruz ve terminal üzerinden programı ./<dosyanın ismi>şeklinde çalıştırıyoruz. Karşımıza bir yükleme ekranı geliyor. Daha sonra adımları takip ediyoruz. tess olarak yazılan kısım benim kullanıcı adımdır. Sizde faklı olacaktır.
Böylelikle tess isminde bir dizin oluşturarak içerisine derleyiciyi kurmuş olduk. derleyici kurulumundan sonra eğer uzantısını yola eklerseniz daha sonradan tüm uzantıyı yazmaya gerek kalmadan çağırma imkanınız olabiliyor. Onun için terminal üzerinden ayarlamaları yapmak gerekiyor.
[codesyntax lang=”text”]
export PATH=/tess/CodeSourcery/Sourcery_G++_Lite/bin:$PATH
[/codesyntax]
Uygulama
Aynı şekilde hello.c dosyamızı ARM işlemci üzerinde çalışacak şekilde derleyelim. önce ilk oluşturduğumuz makefile içerisine giriyoruz ve güncelliyoruz.
[codesyntax lang=”text” title=”makefile”]
CC=$(CROSS_COMPILE)gcc
hello_world: hello.c
${CC} -g hello.c -o hello
[/codesyntax]
Aslında burada kullanacağımız derleyiciyi biz seçiyoruz da denebilir. O yüzden bu şekilde bir güncelleme yapıyoruz. Önemli bir hatırlatma, ${CC} komutundan önce bir kez tab tuşuna basılmalıdır. Terminale gelerek kodumuzu derliyoruz.
[codesyntax lang=”text”]
make CROSS_COMPILE=/tess/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-linux-gnueabi-
[/codesyntax]
Aslında burada make CROSS_COMPILE=arm-linux-gnueabi- kodunuda kullanabilirdik çünkü path üzerinde tanımladık. Fakat bazen bu path tanımlamalarını sistem görmeyebiliyor. O durumlarda ise tam yolu yazmak gerekiyor. Mesela yukarıdaki gibi. bu şekilde kodumuzu ARM işlemcisi için derlemiş olduk. Oluşturduğumuz .o uzantılı dosya ARM üzerinde çalışacak fakat İntel üzerinde çalışmayacaktır.
.o uzantılı dosyayı ARM işlemcisi üzerinde taşıdığımızda ./<dosya ismi> ile rahatça çalıştırabiliriz. Böylelikle cross-compile olayını tamamlıyoruz.