Merhaba CMake

Bu ve önümüzdeki bir veya iki yazıda CMake aracından bahsetmek istiyorum. İlk yazımda genel olarak CMake nedir, neler sunar ve basit bir kaç örnek üzerinden geçeceğiz. Sonraki yazımda ise daha karmaşık örnekler ile farklı kullanımları inceleyeceğiz.

CMake nedir?

CMake bizlere C++ program oluşturma sürecini işletim sisteminden ve arkada kullanılacak olan derleyiciden bağımsız bir şekilde gerçekleştirmemize olanak sağlayacak olan açık kaynaklı bir sistemdir.

CMake bunu peki nasıl gerçekleştirmekte? CMake, özel olarak geliştirilmiş olan bir betik dil ve oluşturma işleminin gerçekleştirileceği her bir dizine konulan CMakeLists.txt dosyalarını kullanarak her bir platform için gerekli olan oluşturma dosyalarını oluşturuyor. Detaylara inmeden önce CMake ile neler yapabiliriz ona bakalım isterseniz?

  • Statik ve dinamik kütüphanelerin oluşturulması için gerekli dosyaları oluşturabilirsiniz,
  • Çalıştırılabilir kodların oluşturulması için gerekli dosyaları oluşturabilirsiniz,
  • Bu üretilecek olan kütüphane ve çalıştırılabilir kodlar için gerekli ayarları, birbirlerine olan bağımlılıkları tanımlayabilirsiniz,
  • Daha da önemlisi her bir kurulum için kuruluma özel veya diğer özel seçenek ve ayarlamaları kurulum sürecinde kullanıcıya sunulabilmesine olanak sağlar,
  • Tek bir kaynak ağacı (genelde “source tree” olarak geçer) üzerinden birden fazla konfigürasyon için bunların oluşturulmasına olanak sağlar,
  • Ayrıca bazı ara dosyalar oluşturarak geliştirdiğiniz bu CMake kodlarını bir grafiksel kullanıcı arayüzü aracılığı ile kullanılmasına olanak sağlar,
  • Birden fazla ve karmaşık dizinleri içeren kaynak kodların derlenmesini daha kolay hale getirir,
  • Bütün kurulum işlerini tek bir dosyaya toplaması açısında daha derli toplu bir yaklaşım sunar.

CMake kullanarak ayrıca birçok IDE için de gerekli dosyaları (Örneğin: MS Visual Studio, XCode, Eclipse CDT), oluşturma betikleri (Örneğin: Windows için MSBuild ve NMake betikleri, Unix benzeri sistemler için “makefile”) oluşturabilirsiniz.

CMake’i ile yazılım oluşturma süreci iki aşamada gerçekleştiriyor. Öncelikle konfigürasyon dosyalarından standart kurulum dosyaları oluşturuluyor, daha sonra da bu dosyalar platforma ilişkin kurulum araçları da kullanılarak yazılım oluşturuluyor. Burada oluşturma sürecini kontrol eden dosya, kurulum içerisine dahil olan her bir dizin içerisine yerleştirilen CMakeLists.txt, dosyasıdır. Bu dosya içerisinde bulunan her bir komut ile bu süreç gerçekleştiriliyor.

Çoğu açık kaynak proje ve yazılım artık CMake kullanmaya başladı. Aşağıdaki adreste tam listeye ulaşabilirsiniz.
CMake kullanan yazılımlar

Genel Hususlar

Bu başlık altında CMake’e ilişkin bir takım hususları sekme sekme inceleyelim:

  • CMake betiği yazarken yorumlar eklemek için # kullanabilirsiniz,
  • Oluşturma dosyalarına dahil olacak her dizin içerisinde muhakkak CMakeLists.txt dosyası olmalı,
  • CMake betikleri komutlar ile oluşturulmakta ve her bir komut liste olarak bir takım parametreler almakta. Detaylı komutlar için https://cmake.org/cmake/help/latest/manual/cmake-commands.7.html sayfasına erişebilirsiniz. Örnekler ile bu komutları  açıklayacak olsam da en çok kullanılan komutlara burada kısaca değinelim:
    • message: Girilen mesaj gösterilir
    • cmake_minimum_required: İhtiyaç duyulan minimum CMake sürümü
    • add_executable: Verilen isim ile çalıştırılabilir hedef uygulama ekler
    • add_library: Verilen isim ile hedef kütüphane oluşturulur
    • add_subdirectory: Alt dizin kurulum sürecine eklenir
      Bunların yanında süreç esnasında çeşitli mantıkları gerçeklemek adına (koşul, döngü, vs) komutlar da bulunuyor. Bunlar belirtilen çiftler halinde kullanılıyor:
    •  if, endif
      elif, endif
      while, endwhile
      foreach, endforeach
      list
      return
      set
  • CMake betikleri içerisinde değişkenler tanımlayabilirsiniz. Bunlar alfanumerik ve sadece “_” kullanabilirsiniz. Daha sonra bu değişkenlere erişim için “${DEGISKEN_ISMI}” kullanımı takip ediliyor. Basitçe bir değişken tanımlamak için aşağıdaki örneği referans alabilirsiniz:

    Daha detaylı bilgi için https://cmake.org/cmake/help/v3.0/manual/cmake-language.7.html#variables
  • Kullanıcı tarafından tanımlanan değişkenler yanında bir takım “predefined” yani önceden tanımlanmış değişkenler de bulunmakta. Bunlardan en önemlileri ve açıklamaları aşağıdaki gibidir:
    • CMAKE_BINARY_DIR: Oluşturma ağacının tepesi ve çıktının konulacağı dizin.
    • CMAKE_HOME_DIRECTORY: Kaynak ağacının dizini.
    • CMAKE_SOURCE_DIR: Kaynak ağacına olan tam dizin.
    • CMAKE_INCLUDE_PATH: find_file ve find_path komutları tarafından araştırılan dizinler.
  • Komutlar büyük/küçük harf duyarsız, fakat değişkenler büyük/küçük harf duyarlı çalışıyor
  • CMake’in en önemli özelliklerinden birisi de farklı platformlar için oluşturma sürecini sunması. Peki bu anlamda bize sağlanan değişkenler neler:
    • CMAKE_SYSTEM: Tam sistem isimleri ör. “Linux-2.4.22”, “FreeBSD-5.4-RELEASE”, “Windows 5.1”
    • CMAKE_SYSTEM_NAME: Oluşturma süreci ile hedeflenen sistem ismi. Üç temel değer: “Windows”, “Darwin”, “Android”, “FreeBSD” ve “Linux”. Ayrıca diğer gömülü sistemler “Generic” olarak isimlendiriliyor.
    • CMAKE_SYSTEM_VERSION: İşletim sistemi sürümü.
    • CMAKE_SYSTEM_PROCESSOR: İşlemci ismi (ör. “Intel(R) Pentium(R) M processor 2.00GHz”)
    • CMAKE_HOST_SYSTEM_NAME: Kurulum gerçekleştirilen ev sahibi sistem.
    • Gördüğünüz üzere bu değişkenleri kullanarak oluşturma dosyalarını rahatlıkla uyarlayabilirsiniz. Yazımın sonuna mevcut platforma ilişkin bilgileri gösteren örnek bir kod ta ekliyorum.
  • Ayrıca CMake ile makrolar da tanımlatabilirsiniz. Bunun için “add_definition” komutu kullanılıyor. En sona bunun ile ilgili de bir örnek kod ekliyorum.

CMake ile ilgili olan hususların hepsi bunlar mı peki? Elbette değil. Daha fazlası için ilgili kaynaklara bakabilirsiniz. Şimdilik bir örnek üzerinden CMake yazımıza devam edelim.

İlk Örnek

En temel CMake örneğine bakacak olursak (bir nevi “hello world”) örneği. Aşağıdaki gibi bir kod bizi karşılayacak:

Peki bunlar ne anlama geliyor.

İlk satırda bu dosyayı oluşturmak için ihtiyaç duyulacak olan minimum sürüm numarası tanımlanıyor (numaraları büyüterek aksi durumda ne olduğunu görebilirsiniz :).
İkinci satırdaki “project()” komutu ile bu projeye bir isim vermiş oluyoruz. Bu ne anlama geliyor sorusunun çıkmasını bekliyorum 🙂 Hemen https://cmake.org/cmake/help/latest/command/project.html sayfasına bir göz atarak çok detaylı bilgi alabileceğiniz gibi temel olarak bu komut ile bütün oluşturulacak olan yazılıma bir isim (“Visual Studio solution” ismi gibi yoksa bir “solution” altında birden fazla proje bulunabilir), sürüm, dil veya daha detaylı açıklama vb. bilgileri atayabilirsiniz. Bu arada aşağıda CMake’e ilişkin yardım sayfasında bu komutun nasıl ifade edildiğini görebilirsiniz:

Üçüncü ve son komut ise “add_executable” komutu. Bu komut kendisine verilen parametreler ile çalıştırılabilir kod üretilmesine ilişkin oluşturma dosyalarındaki komutları ayarlıyor. İlk parametre çalışabilir kodun ismi ikincisi ise kullanılacak olan kaynak kod. Burada ince bir nokta var. Çoğu diğer kaynakta burada sadece .cpp dosyalarının eklendiğini görebilirsiniz ve gerçekten de aslında derleme için cpp dosyasının verilmesi yeterlidir. Burada “header” dosyasının özellikle eklememizin sebebi VS gibi IDE’lerde de bu dosyaların bizlere eklenerek, sunulması. Ha bana ne be ya “header” dosyalarından diyorsanız, o dosyaları eklemezseniz de oluşturma işlemi başarı ile gerçekleştirilecektir.

Evet bu üç satır ile artık bir çok platform ve c++ derleyicisi ile helloworld uygulaması hazırlama zahmetinden kurtulmuş olduk. Bu arada windows işletim sistemi ile visual studio kullanan yazılımperver dostlar. VS ile de CMake projeleri oluşturabiliyorsunuz. Aslında githuba koyduğum örnekleri VS ile hazırladım.

Gelelim ilgili oluşturma dosyalarını oluşturmaya. Bunları ben komut satırı üzerinden yapacağım.
Genelde CMake ile oluşturulacak bu dosyaları kaynak kodtan farklı bir yere oluşturmanızı önereceğim. Genelde kullanılan dizin “build” oluyor. Şimdi ilgili dizini oluşturalım ve içerisine girelim.

Bundan sonra ilgili dosyaları “build” dizini içerisine oluşturmak için yapmanız gereken tek şey “cmake ..” komutunu çağırmak. Eğer her şey yolunda gider ise aşağıdaki gibi bir çıktı görmeniz gerekiyor. Eğer problem yaşıyor iseniz, öncelikle CMake’in kurulu ve ilgili komutların komut satırından çağrılabildiğini doğrulayın (“cmake -version“).

Yukarıdaki satırlar ne olaki. Bu satırlar arkadaşlar mevcut komut satırı ışığında CMake’in oluşturma dosyaları için elde ettiği derleyici ve benzeri bilgiler. Bu arada bu daha detaylı bilgiye CMakeCache.txt dosyası içerisinden ulaşabilirsiniz. Mevcut derleyici için CMake PATH ortam değişkenine bakıyor. Eğer bilgisayarınızda VS kurulu olmasaydı veya farklı bir platformda bu komutu çağırsaydınız muhtemelen aşağıdaki gibi bir hata ile karşılaşacaksınız. Örneğin “Unix Makefiles” oluşturmak için aynı komut satırında “cmake .. -G “Unix Makefiles” ” komutunu çağırır iseniz aşağıdaki gibi hata almanız muhtemel.

Ve ilk dosyalarımızı oluşturduk. Aşağıda CMake’in bizlere VS için “build” dizini içerisine oluşturmuş olduğu dosyaları görebiliriz.

 

Artık ilgili .sln dosyasını açarak ya da “cmake –build .” komutunu çağırarak ilgili çalışabilir kodu oluşturabilirsiniz.

Diğer Örnekler:

Platform görüntülemesine ilişkin örnek CMake kodu:

Şimdi makro tanımlanmasına ilişkin bir örneğe bakalım. Öncelikle CMake koduna bakalım:

Aşağıda yukarıdaki CMake tanımlamalarının kullanımına ilişkin kodu bulabilirsiniz:

Kaynaklar:

Elbette bu yazımda da bir çok kaynaktan faydalandım. Bunlara erişerek bilgilerinizi pekiştirebilirsiniz.

2 Comments Merhaba CMake

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.