Uygulama İzleme Yazılımı 2 – Başlangıç

Evet dostlar, Uygulama İzleme Yazılımı (Application Monitor Tool, AMT) için artık demir alma vakti geldi, başlangıç hazırlıkları tamamlandı. Şimdi neler yaptığımıza bir göz atalım.

Bildiğiniz üzere daha önce geliştirdiğim ve sizler ile paylaştığım kod parçaları için github’ı kullanıyordum (halen de kullanıyorum). Bu uygulama için ise Gitlab’ı kullanıyor olacağım. Daha önce bir kaç farklı uygulama için gitlab’ı kullanma fırsatım oldu ve genel olarak izlenimlerim olumluydu. Bu uygulama için de, neden onu kullandığımı birazdan sizler ile paylaşacağım.

Yazılarımı çok uzun tutmadan, aktarmak istediğim konuları sizlere aktarıp, detaylar için belki ayrı yazılar yazıyor olabiliriz. Bakalım duruma göre değerlendireceğiz artık. Bu arada bir önceki yazımda değindim mi bilmiyorum ama bu yazı dizinin salt amacı, tasarımsal ya da mimarisel olarak mükemmel bir uygulama ortaya koymak değil (tabi çok da baştan savma olmayacak 🙂 . Bundan ziyade, amaçlanan kabiliyetleri, ilgili teknolojileri kullanarak nasıl geliştirebilirize bakıyor olacağız.

Gelelim bu yazımda değineceğim konulara:

  • Proje dizin yapısı,
    • Örnek bir projeyi nasıl yapılandırabiliriz,
  • Gitlab,
    • Gitlab nedir? Alternatifleri neler? Neden gitlab?
  • CMake,
    • Proje dizin yapısına göre CMake dosyalarının konuşlandırılması. CMake ile ilgili bir takım ipuçları ve 3. parti kütüphaneleri CMake ile nasıl kullanabiliriz.

Proje dizin yapısı ile başlayalım.

Proje Dizin Yapısı

Proje dizin yapısı aslına bakarsanız, çoğu zaman projelere başlarken pek üzerinde düşünülmeyen ama projenin büyüklüğü arttıkça, kendini hissettirmeye başlayan bir konu. Bu noktada da bence en önemli iki kriter, ilgili proje dizin yapsının projenin ilerleyen süreçlerinde de idame edilebilmesi ve geliştiricilerin bu yapıya aşinalığı/kendilerini rahat hissedip/hissetmedikleri. Şunu da ilave etmekte fayda var ki, bütün projeler için tek bir yapı yok, genelde ihtiyaçlar doğrultusunda bu yapı özelleşiyor. Hatta, kullandıkça, geri bildirimler ışığında siz de güncelliyor olabilirsiniz. Buradaki önerim, sizlere iyi bir başlangıç sağlayacağını düşünüyorum.

Elbette bunlar benim kriterlerim, bunların dışında da, internet üzerinde de, bu konuda bir çok kaynak var. Bu ikisinin yanında, aşağıdaki gibi kriterleri de göz önünde bulundurmakta fayda var:

  • Projenin büyüklüğü,
  • Üçüncü parti kütüphaneler,
  • Test kodları,
  • Çoklu platform desteği,
  • Sürekli entegrasyon desteği,
  • Kütüphane/çalıştırılabilir kod konfigürasyonları,
  • Betik dosyaları, vb.

Gelelim bizim AMT için ilk etapta oluşturdum dizin yapısına. Dizin yapısı aşağıdaki gibi (bu arada aşağıdaki gibi bir gösterim için “tree” komutunu kullanabilirsiniz, dosyaları da görmek için /F ekleyebilirsiniz):

Şimdi hızlıca bu dizinlere bir bakalım.

  • binary: çalıştırılabilir kodların (.exe) bulunacağı dizin
  • build: proje ve oluşturma dosyalarının (cmake ile oluşturulan) konuşlanacağı dizin. Açıkçası daha önce, CMake kullanmadan önce, bunun yerine “project” gibi bir dizin kullanıyordum VS dosyaları için
  • data: verilerin konuşlanacağı dizin
  • doc: dokümanların bulunacağı dizin
  • ext: 3. parti dış kütüphanelerin bulunacağı dizin
  • include: başlık dosyalarının bulunacağı dizin. Açıkçası, bu uygulama için başlık ve kaynak dosylarını ayrı dizine koymaya karar verdim. İkisinin dizin yapısı birbirine benziyor olacak
  • src: kaynak dosyalarının bulunacağı dizin
  • test: ilgili birim testlerinin bulunacağı dizin.

Dosyaları tek tek göstermedim. CMake dosyalarına ilgili başlıkta bakacağız. Ayrıca tamamen boş da olmaması için, Utility kütüphanesini ekledim.

Gitlab

Evet, başta da bahsettiğim gibi bu uygulamayı Gitlab üzerinde konuşlandırdım. Sebebini kısaca özetlemem gerekirse, üçüncü parti bir uygulama (daha önce kullandığım appveyor ya da jenkins) kullanmadan sürekli entegrasyon kabiliyetleri sunması ve açık kaynak olması oldu. Elbette alternatif uygulamalar var ama bence en kolaylarından birisi gitlab. Bu başlık altında diğerlerine de çok kısa bakacağız (ör. appveyor, azure devops, vb.).

Daha önce bu tarz yazılımlar kullanmadıysanız en çok karıştırabileceğiniz üç kavram: git, github ve gitlab olacaktır. Bunlar nedir ve farkları ne sorusu ilk sorular olacaktır. Hemen bakalım.

Git temelde, SVN, CVS ve IBM ClearCase gibi bir sürüm kontrol sistemidir. Ücretsiz bir yazılımdır ve Linux çekirdeğini yazan Linus Torvalds tarafından tasarlanmıştır. Bu tarz sürüm kontrol yazılımlarının en temel amaçları:

  • Kodlarınız ve benzeri kalemlerinizi saklayıp, güncelleme geçmişini takip etmenizi sağlamak,
  • Değişiklik yönetimine yardımcı olmak,
  • Birden fazla geliştiricinin aynı kod kümesi üzerinde çalışmasına izin vermek.

Bu yazılımlar genel olarak merkezi ve dağıtık olmak üzere ikiye ayrılabilirler. Merkezi olanlarda, veriler temel bir sunucuda tutulur, erişimler genelde kontrollü olur ve dallanma işlemleri nispeten zordur. Ör. IBM Clearcase, SVN. Dağıtık sürüm kontrol sistemlerinde ise, her geliştirici verilerin bir kopyasını ve geçmiş bilgisini tutar (clone). Performansı, merkezi sistemlere göre genelde daha iyidir ve dallanma/birleştirme işleri çok daah kolaydır. Merkezi sunucuya sürekli bağlı olma kısıtı yoktur. Ör. Git, mercurial. Kaynaklar kısmında bu iki tipe ilişkin bir kaç site ekledim, göz atabilirsiniz. Benzer şekilde git ile ilgili de bir çok kaynak mevcut.

Github ve Gitlab‘a gelecek olursak. Aslında bu ikisi, internet üzerinden sizlere Git tabanlı bir depolama servisi sunan uygulamalardır. Github, hem ücretli (özel) hem de ücretsiz servisler sunarken, gitlab ise hem özel hem de özel olmayan projeler oluşturmanıza olanak sağlamaktadır. Github, bir sürece önce microsoft tarafından satın alındıktan sonra, ilginin gitlab’a kaydığını söylemek yanlış olmaz sanırım. Ama benim açımdan en önemli fark, gitlab’ın sunduğu sürekli entegrasyon (CI) ve sürekli teslimat (CD) servisleri.

Bu ikisinin daha detaylı karşılaştırmaları için kaynak kısmına eklediğim sitelere göz atabilirsiniz. Aşağıda bu kaynaklardan bulduğum bir karşılaştırma tablosunu görebilirsiniz:

ÖzellikleGitLabGitHub
Yayınlanma TarihiEylül 2011Nisan 2008
Kullanım YöntemleriHerkese açık ve özel projeler için sınırsız ve bedavaHerkese açık projeler için bedava
Dahili Devops DesteğiVarYok
Kod Gözden GeçirmeVarVar
WikiyesVar
Hata & Husus TakibiVarVar
Özel Dallanma

Private Branching

VarVar
Oluşturma SistemiVarVar (3. parti servis olarak)
Proje İçeri AlmaVarYok
Proje Dışarı AktarmaVarYok
Zaman TakibiVarYok
Web-hostingVarVar
Self-hostingVarVar (kurumsal plan ile)
Popülerlik546.000+ Proje69.000.000+ Proje,

 

Elbette bu başlığı bitirmeden hemen projemizin bulunduğu gitlab adresini vereyim:

https://gitlab.com/yazilimperver/applicationmonitoringtool

CMake

AMT yazılımı için sabit bir VS projesi eklemektense, CMake dosyalarını oluşturmaya karar verdim. Bu vesile ile daha önceki CMake yazılarımda inceledeğim CMake aracına ilişkin kabiliyetleri, gerçek bir uygulamada nasıl kullanabilirize bakıyor olacağız. Bu sayede sizlere de, benzer durumlar için yardımcı olmayı umut ediyorum. CMake’e ilişkin anlatmak istediklerimi sekme sekme sizlere aktarmaya çalışacağım. Burada, CMake betikleri ile ilgili her şeyi anlatmayacağım.

İlgili kullanım için elbette gitlab’daki dosyaları da inceleyebilirsiniz. Uygulama geliştikçe, CMake dosyalarımız da gelişiyor olacak. Bu arada, CMake’e ilişkin hızlı bir hatırlama için aşağıdaki yazılarıma göz atabilirsiniz:

Merhaba CMake

CMake – II (devam)

Evet şimdi gelelim CMake ile ilgili aktaracaklarıma:

  • Çoklu CMake dosyalarının, proje dizini ile paralel bir şekilde oluşturulması,
    • Bu konuya, yukarıdaki yazılarımda da değinmiştim. Tek bir CMakeLists.txt dosyası ile bütün projeyi idame etmek oldukça zor olabilir.
    • AMT bağlamında ben, aşağıdaki dosyaları oluşturdum ve konumlandırdım:
      • En tepedeki CMakeLists.txt, ilk CMake oluşturmak için kullanacağımız betik dosyası ve diğer betikleri adresler.
      • Bu betik içerisinde tanımlanan değişkenler ve kapsam ile ilgili hemen bir iki kelam edeyim. CMake betikleri arasında, kapsam anlamında alt ağaç konumlarında bulunan betikler, üst taraftan gelen kapsamı alırlar (ör. yukarıda tanımlanan bir değişken alt betiklerde de kullanılabilir). Varsayılan davranış olarak da, alt seviyede yapılan değişiklikler üst seviyeyi etkilemez. Elbette bunu da yapmak isteyebilirsiniz. Bu amaçla da PARENT_SCOPE kullanabilirsiniz. Örneğin, en tepede FOO diye bir değişken tanımlandığını düşünelim, alt seviye CMake betiği içerisinde “set(FOO ilgiliDeğer PARENT_SCOPE)” derseniz, tepedeki değişkeni de güncellemiş olursunuz. Elbette bu tarz bağımlılıkları çok kullanmamakta fayda var.
      • root/ext içerisindeki CMake betiği, 3. parti kütüphaneleri eklemek için kullanacağız,
      • root/src içerisindeki CMake betikleri, kaynak kodları için proje dosyaları oluşturmak için,
      • root/test içerisindeki CMake betikleri, test kodları için proje dosyaları oluşturmak için kullanacağız.
  • CMake kullanarak, bir dosyanın konfigüre edilmesi olayı. Bizim durumumuzda, yazılımın sürüm bilgilerini içeren bir dosyanın oluşturulması.
    • Bu amaçla configure_file komutunu kullanıyoruz,
    • İlk parametresi (“config.h.in“), şablon bir dosyayı temsil eder. Bu dosya içersine konulan ‘${CMAKE_VARIABLE}‘, ‘@CMAKE_VARIABLE@‘ ifadeleri, CMake betiği içerisindeki değişkenlerin değerleri ile değiştirilip, ikinci parametrede gösterilen dosya oluşturulur (include/config.h).
  • CMake betiklerinde kullanabileceğiniz ön tanımlı bir takım değişkenler vardır. Burada bunlardan birisini kullanıyoruz. O da “ApplicationMonitorTool_SOURCE_DIR” değişkeni. Bu değişken, isimlendirilen projenin kaynak dizinini tutar.
  • Bir diğer kullandığım kabiliyet de “use_folders“. Bu, size CMake “target”‘larını (.exe, kütüphane), dizinler aracılığı ile organize etmek için kullanabileceğiniz bir kabiliyet. Visual Studio kullanımında, oluşturulan solution içerisinde “Soluiton Folder”/çözüm dizinleri oluşturmak için de bu kabiliyeti kullanabilirsiniz. Ben bunu, 3. parti kütüphaneleri, kaynak kod projeleri ve test projelerini gruplandırmak için kullanacağım. Gelelim bunu nasıl kullanacağımıza:
    • Öncelikle, “set_property(GLOBAL PROPERTY USE_FOLDERS ON)” ile bu kabiliyeti aktifleştirmeniz gerekiyor,
    • Sonrasında kullanım için, ilgili target’ı nereye ekleyeceğinizi söylemek için de örneğin “root/src/utility” içerisindeki betikte, VS içerisinde “Src/Utility” çözüm dizini oluşturmak için “set_target_properties(Utility PROPERTIES FOLDER Src)” kullanılabilir. Örneğin aşağıda, bu yetenek kullanılarak oluşturulan “Ext, Src, Test” dizinleri buna örnektir.
    • Buradaki betiklerin yansımasını, Gitlab’tan projenin kaynak dosylarını indirip, VS dosyalarını oluşturursanız bunu daha net görebilirsiniz.
  • Yukarıdaki yöntemin yanında, Visual studio içerisindeki “Filtre”‘leri nasıl oluşturabiliriz ona bakalım. Yine, “root/src/utility” içerisindeki betiğe bakalım. Burada “source_group(“Header Files” FILES ${HEADER_FILES})” ile bu filtrelerden birini oluşturuyoruz. Benzer şekilde “Source Files” için de oluşturduğumuzda VS içerisindeki görünüm şu şekilde oluyor:
  • Bir diğer yeni kullanım da, başlık dosyası dizinlerinin eklenmesi yaklaşımı olacaktır. Önceki yazımda bunu “include_directories” dizini ile yapmıştım ama daha sonra okuduğum kaynaklarda artık bu kullanımın tercih edilmediği ve sakıncaları olduğunu gördüm. Bunun yerine önerilen yöntem “target_include_directories” fonksiyonudur. Farkı nedir?
    • include_directories, fonksiyonu kullanıldığında, ilgili başlık dizini bütün projeler ve hedeflere (target) eklenir ve alt dizinlerdeki betiklere de sirayet eder. Ama target_include_directories, sadece ilgili proje/hedefe (target) için bu başlık dizinlerini ekler. Bu fark çok önemli, çünkü ilki daha kontrolsüz bir kullanımdır.
  • En tepe isimdeki CMake betiği içerisindeki enable_testing komutu ile ilgili dizin ve alt dizinlerde test dosyaları dahil edilir.
    • Buna bir sonraki yazımda tekrar döneceğim onun için burada bırakıyorum.
  • En son bahsedeceğim husus da, GoogleTest’in CMake dahil edilmesi.  Aslında bu benzeri kütüphaneler için de referans olabilir.
    • Normalde, bu tarz kütüphaneleri indirip, başlık ve .lib dosyalarını, proje dizini içerisinde barındırırdık ama bu sefer bunu CMake ile nasıl yapabiliriz biraz ona da baktım.
    • Bazı yöntemler internetten indirip kurulmasına dayanıyor ama bu yöntem her platform için uygun olmayabiliyor. Sonuç olarak, VS ve benzeri araçlar aracılığı ile de kullanılabilmesi için, en güzel yöntem bu kütüphaneyi indirip, dizine konulması yöntemidir. GoogleTest de CMake betiği içerdiği için ona atıfta bulunmak yeterli oluyor,
    • Burada dikkat edilmesi gereken iki husus var. Birincisi, dizine bu şekilde eklediğimiz için, kurulum adımını atlatmak. Bunu “set(INSTALL_GTEST OFF)” ile yapıyoruz. Bir diğer sıkıntı ise, özellikle VS ile kullanımda ortaya çıkan çalışma zamanı kütüphane uyumsuzlukları. Bunu da önlemek için “set(gtest_force_shared_crt ON CACHE BOOL “” FORCE)” i ekliyoruz,
    • Peki google testi nasıl ekliyoruz. Çok basit, sadece “add_subdirectory(googletest-master)” diyerek ekliyoruz.
    • GoogleTest kütüphanesini bağlamak için de, “target_link_libraries(Utility_Test gtest gmock Utility)” diyerek bağlıyoruz.

CMake de, oldukça büyüyen gelişen bir uygulama, bu konuda kendini geliştirmek isteyenlere https://cliutils.gitlab.io/modern-cmake/ adresindeki notlara bakmasını tavsiye ediyorum.

Evet arkadaşlar, giriş yazımdan sonra ilk AMT yazımızın sonuna geldik. Umarım hoşunuza gitmiştir. Biraz beklediğimden uzun oldu ama faydalı olacağını inandığım konuları çıkarmaya da elim gitmedi 🙂

Bir sonraki yazımda, aslında mevcut adresde olan kodlardan Utility kütüphanesine ve birim test kabiliyetlerine bir göz atıyor olacağız. O zamana kadar kendinize iyi bakın ve sağlıkla kalın.

Kaynaklar

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.