CMake’te Property Kullanımı

CMake değişkenleri, CMake’in çalışma akışı ile ilgili durumları baştan belirlemek için kullanılan oldukça kullanışlı araçlardır. Değişkenler ile projenizi derleyecek kişilere istedikleri şartlarda ve ayarlarda özgürce derleme yapma imkanı tanıyabilirsiniz. Ancak CMake’in çalışmasını etkileyebileceğiniz tek araç değişkenler değildir. CMake’te Property adı verilen bir kavram da bulunur ve bu kavram sıklıkla değişken kavramı ile karışıtılır. Bu yazıda CMake’teki Property kavramı üzerinde duracağız.

Öncelikle tanımdan başlayalım. CMake’te Property (Özellik, Nitelik), bütün Build sürecinin herhangi bir aşamasında meydana gelecek olayların durumlarını ayarlamak için kullanılan bir CMake özelliğidir. Kendisini bu ve sonraki yazılarda çevirmeyi düşünmüyorum. Çünkü henüz onu tam olarak karşılayacak Türkçe kelimeden emin değilim. Genellikle programlama dillerinde de karşımıza çıkan “property” kelimesi, Türkçe’de bilgisayar bilimlerinde “özellik” veya “nitelik” olarak karşımıza çıkmaktadır. Şimdilik “Property” olarak kullanmaya devam edeceğim.

Property kavramı değişkenler ile sıklıkla karıştırılır. Temelde görevleri durum değiştirmek olan bu iki kavramı ayıran çok ince bir çizgi vardır. Değişkenler genel durumları değiştirmek için kullanılırken, Property’ler belli bir varlığın durumlarını değiştirmek için kullanılır. Haliyle CMake’te önceden tanımlı değişkenler gibi birçok önceden tanımlı Property de bulunmaktadır. Bu önceden tanımlı Property’ler ile Build sürecinde kaynak kodların derlenmesi kısmından, çalıştırılabilir dosyaların sisteme yüklenmesine kadar her aşamada değişiklik yapmamız mümkündür. Bunları zamanı geldiğinde açıklayacağız.

Dediğimiz gibi değişkenler belli bir varlığa bağlanıp onun durumlarını değiştirmezler, ancak Property’ler bunu yaparlar. Property’ler de CMake değişkenleri gibi iyi dokümante edilmişlerdir. Ayrıca Property’leri işleyebileceğiniz (değerini alıp değiştirebileceğiniz) komutlar, değişkenler ile ilgili komutlardan biraz farklıdır. Öncelikle Property’lerin bağlandığı “varlık (entity)” kavramını biraz açalım. CMake’te Property’lerin bağlanabileceği temelde 7 varlık bulunur. Bunlar şu şekildedir:

  • GLOBAL
  • DIRECTORY
  • TARGET
  • SOURCE
  • INSTALL
  • TEST
  • CACHE

Property’ler bu yedi varlığa bağlanarak onların özelliklerini değiştirebilirler. Elbette her bir varlığa özel Property’lerin isimleri de değişiklik gösterir. Şimdi bu isimleri ve anlamlarını sırasıyla inceleyelim:

  • Global Faaliyet Alanı Property’leri (Properties of Global Scope): Bütün Build sürecinin kendisini ilgilendiren Property’lerdir.
  • Dizin Property’leri (Properties on Directories): Build sürecindeki alt dizinleri ilgilendiren Property’lerdir.
  • Hedef Property’leri (Properties on Targets): Build sürecindeki derleme hedeflerini ilgilendiren Property’lerdir.
  • Kaynak Dosya Property’leri (Properties on Source Files): Build sürecindeki kaynak dosyaları ilgilendiren Property’lerdir.
  • Yüklenen Dosya Property’leri (Properties on Installed Files): Build süreci sonunda sisteme yüklenecek olan dosyaları ilgilendiren Property’lerdir.
  • Test Property’leri (Properties on Tests): Build sürecindeki testleri ilgilendiren Property’lerdir.
  • Cache Girdisi Property’leri (Properties on Cache Entries): Build sürecindeki Cache değişkenlerini ilgilendiren Property’lerdir.

Bu yazıda sadece Property’lerin genel özelliklerini, değerlerini nasıl elde edip değiştirebileceğimizi ve onları nasıl tanımlayabileceğimizi anlatacağım. Her bir varlığın önceden tanımlı Property’lerini başka yazılarda daha ayrıntılı olarak ele alacağım. Öncelikle CMake’te bir Property’nin değerini elde etmek için get_property, onun değerini değiştirmek için set_property, onu tanımlamak için ise define_property komutlarını kullanmaktayız. Elbette bunlar her bir Property kategorisini kapsayan genel komutlardır. Daha özel komutları sonraki yazılarda göreceğiz. Öncelikle get_property komutunun genel biçimine bakalım:

get_property(resultVar entitySpecific PROPERTY propName
[DEFINED | SET | BRIEF_DOCS | FULL_DOCS])

Bu komutta yer alan resultVar yerine değerin yazılacağı değişkenin adı yazılır. Bu komuttan çıkan değer, onun sonuna yazılan anahtar kelimeye göre değişiklik göstermektedir. Bunları birazdan inceleyeceğiz. Öncelikle herhangi bir anahtar kelimenin yazılmadığı durumu ele alalım.entitySpecific kısmına elde edilecek Property türü yazılmalıdır. Bu tür bilgisi verilen anahtar kelimeye göre farklı formlarda olabilir entitySpecific yerine yazılabilecek anahtar kelimeler ve onların argümanları şöyledir:

  • GLOBAL
  • DIRECTORY [<dir>]
  • TARGET <target>
  • SOURCE <source> [DIRECTORY <dir> | TARGET_DIRECTORY <target>]
  • INSTALL <file>
  • TEST <test>
  • CACHE <entry>
  • VARIABLE

GLOBAL anahtar kelimesi, o Property’nin global faaliyet alanı Property’si olduğunu belirtir. Zaten bu tür bir Property için ek argüman belirtmeye gerek yoktur. DIRECTORY anahtar kelimesi ise o Property’nin bir dizin Property’si olduğunu belirtir. Burada DIRECTORY anahatar kelimesinden sonra bir alt dizin ismi yazmak seçenekseldir. Eğer yazılmazsa o anki dizin ile ilgili Property’lerin değeri elde edilebilir. TARGET anahtar kelimesi o Property’nin bir hedef Property’si olduğunu belirtir. Bu anahtar kelimeden sonra projedeki add_library veya add_executable gibi komutlar ile tanımlanmış hedef isimleri yazılmalıdır.

SOURCE ise o Property’nin bir kaynak dosya Property’si olduğunu belirtir. Bu anahtar kelimeden sonra bir kaynak dosyanın ismi yazılmalıdır. Eğer bu dosya isminden sonra bir şey yazılmazsa, varsayılan olarak o anki dizin faaliyet alanındaki kaynak dosyanın Property’si ele alınır. Ancak CMake 3.18 ile kaynak dosya isminden sonra DIRECTORY anahtar kelimesi ile herhangi bir alt dizindeki kaynak dosyanın Property’sini değiştirme imkanı gelmiştir. Yine CMake 3.18 ile kaynak dosya isminden sonra TARGET_DIRECTORY anahtar kelimesi ile bir hedef ismi belirtilerek, bu hedefin dizin faaliyet alanı kullanılabilir hale getirilmiştir.

INSTALL anahtar kelimesi, o Property’nin bir yüklenen dosya Property’si olduğunu belirtmektedir. Bu anahtar kelimeden sonra yükleme yapılacak dosyanın yolu verilmelidir. TEST anahtar kelimesi bu Property’nin bir test Property’si olduğunu belirtmektedir ve bu anahtar kelimeden sonra “dd_test ile belirtilen test ismi yazılmalıdır. CACHE anahtar kelimesi, o Property’nin bir Cache girdi Property’si olduğunu belirtir. Bu anahtar kelimeden sonra bir Cache değişkeni ismi yazılmalıdır. VARIBALE anahtar kelimesinin kullanımının özel bir anlamı vardır ve burada tartışılmayacaktır. INSTALL, TEST, CACHE ve VARIABLE kullanımlarını daha sonra göreceğiz. Şimdilik ilk 4 varlık türüne odaklanıp bunlarla ilgili çeşitli kullanım örnekleri verelim:

get_property(result GLOBAL PROPERTY global_prop) # 1
get_property(result DIRECTORY PROPERTY current_dir_prop) # 2
get_property(result DIRECTORY subdir PROPERTY subdir_dir_prop) # 3
get_property(result TARGET program PROPERTY program_target_prop) # 4
get_property(result SOURCE source1.cpp PROPERTY source_prop) # 5
get_property(result SOURCE source1.cpp DIRECTORY subdir PROPERTY source_prop) # 6
get_property(result SOURCE source1.cpp TARGET_DIRECTORY target PROPERTY source_prop) # 7

Sırayla her bir satırda tam olarak ne yapıldığını tek tek yazalım:

  1. global_prop isimli global Property’nin değerini al ve result değişkenine ata.
  2. O anki dizin faaliyet alanında yer alan current_dir_prop isimli dizin Property’sinin değerini al ve result değişkenine ata.
  3. subdir alt dizinin dizin faaliyet alanında yer alan subdir_dir_prop isimli dizin Property’sinin değerini al ve result değişkenine ata.
  4. program isimli hedefin program_target_prop isimli hedef Property’sinin değerini al ve result değişkenine ata.
  5. O anki dizin faaliyet alanında yer alan “source1.cpp” kaynak dosyasına ait source_prop isimli kaynak dosya Property’sinin değerini al ve result değişkenine ata.
  6. subdir dizin faaliyet alanında yer alan “source1.cpp” kaynak dosyasına ait source_prop isimli kaynak dosya Property’sinin değerini al ve result değişkenine ata.
  7. target hedefinin bulunduğu dizin faaliyet alanında yer alan “source1.cpp” kaynak dosyasına ait source_prop isimli kaynak dosya Property’sinin değerini al ve result değişkenine ata.

Bu kullanımlar get_property komutunun sonunda herhangi bir anahtar kelime belirtmediğimiz zaman geçerlidir. Eğer bu komutun sonuna 4 anahtar kelimeden birini getirirsek, bu sefer Property’nin değeri değil de onun tanımlı olup olmadığı, değerinin set edilip edilmedği ve dokümantasyonları gibi bilgileri resultVar kısmına yazdığımız değişkenlerde depolayabiliriz. get_property komutunun sonuna yazılabilecek anahtar kelimeler ve anlamları şöyledir:

  • DEFINED: Eğer ismi girilen Property tanımlı ise resultVar kısmına true değeri, tanımlı değilse false değeri dönecek şekilde komutu ayarlar.
  • SET: Eğer ismi girilen Property’e daha önce bir değer verilmişse resultVar kısmına true değeri, verilmemişse false değeri dönecek şekilde komutu ayarlar.
  • BRIEF_DOCS: İsmi girilen Property’nin kısa dokümantasyonunu resultVar değişkenine geri döndürür. Eğer herhangi bir kısa dokümanı yoksa NOTFOUND değeri ile geri döner.
  • FULL_DOCS: İsmi girilen Property’nin tam dokümantasyonunu resultVar değişkenine geri döndürür. Eğer herhangi bir tam dokümanı yoksa NOTFOUND değeri ile geri döner.

Aslında get_property ve set_property gibi komutlar oldukça genel Property komutlarıdır. İleride her bir varlığa özel Property komutlarını da göreceğiz. Şimdi get_property komutunun GLOBAL varlık türü için kullanımını, son gördüğümüz 4 anahtar kelime ile beraber bir örnek üzerinde inceleyelim. Bu örnekte C özelliklerinin (features) bir listesini içeren CMAKE_C_KNOWN_FEATURES isimli global Property’i kullanarak, anahtar kelimelerin ne gibi sonuçlara yol açtığını göreceğiz:

get_property(c_features GLOBAL PROPERTY CMAKE_C_KNOWN_FEATURES) # Global faaliyet alanı Property'sinin değerini alma
get_property(is_cxx_defined GLOBAL PROPERTY CMAKE_C_KNOWN_FEATURES DEFINED) # DEFINED örneği
get_property(is_cxx_set GLOBAL PROPERTY CMAKE_C_KNOWN_FEATURES SET) # SET örneği
get_property(cxx_brief GLOBAL PROPERTY CMAKE_C_KNOWN_FEATURES BRIEF_DOCS) # BRIEF_DOCS örneği
get_property(cxx_full GLOBAL PROPERTY CMAKE_C_KNOWN_FEATURES FULL_DOCS) # FULL_DOCS örneği


message("CMAKE_C_KNOWN_FEATURES: ${c_features}")
message("Is CMAKE_C_KNOWN_FEATURES defined: ${is_cxx_defined}")
message("Is CMAKE_C_KNOWN_FEATURES set: ${is_cxx_set}")
message("CMAKE_C_KNOWN_FEATURES Brief Docs: ${cxx_brief}")
message("CMAKE_C_KNOWN_FEATURES Full Docs: ${cxx_full}")
ÇIKTI
CMAKE_C_KNOWN_FEATURES: c_std_90;c_std_99;c_std_11;c_std_17;c_std_23;c_function_prototypes;c_restrict;c_variadic_macros;c_static_assert
Is CMAKE_C_KNOWN_FEATURES defined: 0
Is CMAKE_C_KNOWN_FEATURES set: 1
CMAKE_C_KNOWN_FEATURES Brief Docs: NOTFOUND
CMAKE_C_KNOWN_FEATURES Full Docs: NOTFOUND

Gördüğünüz gibi SET ve DEFINED anahtar kelimeleri kullanıldığında, değişken kısmına bir Boolean değer geri dönüyor. Diğerlerinde ise doküman varsa String, yoksa NOTFOUND değeri geri dönüyor. Aslında DEFINED, BRIEF_DOCS ve FULL_DOCS anahtar kelime kullanımlarından elde edilen sonuçlar, bir nevi bu Property’nin define_property gibi bir komutla tanımlanmasına bağlıdır. SET ise biraz daha farklıdır. Bir değişkenin değeri önceden set edilmişse veya set_property gibi bir komut ile set edilmişse, SET değeri true dönebilir. Bu nedenle SET daha güçlü bir kontrol sağlar.

İşte biz bu şekilde bir Property’nin değerini alabilir veya onun çeşitli özelliklerini sorgulayabiliriz. Peki onlara normal bir değişken gibi davranıp o şekilde değerini elde etmeye çalışırsak ne olur? Şu örneği inceleyip cevabımızı uygulama ile bulalım:

get_property(test GLOBAL PROPERTY UNKONWN_PROPERTY) # Global faaliyet alanı Property'sinin değerini alma

message("${UNKONWN_PROPERTY}") # Ekrana herhangi bir çıktı vermez

Gördüğünüz gibi Property’ler, değişkenlerden daha karmaşık nesnelerdir ve değerleri değişkenler kadar kolay elde edilemez veya değiştirilemez. Şimdi VARIABLE, INSTALL ve TEST haricinde diğer Property’lerin değerlerinin nasıl elde edileceği ile ilgili bir örnek daha gösterelim. VARIABLE aslında sedece get_property ve define_property komutlarında karşımıza çıkan, nadir kullanıma sahip bir anahtar kelimedir. Bu nedenle onu anlatmayı düşünmüyorum. INSTALL ve TEST türlerinden de daha sonra bahsedeceğim:

project(TestProject)

add_subdirectory(ExampleProject)

add_executable(TestTarget ExampleProject/main.cpp)

set(TestCache "TestValue" CACHE STRING "TestDescription")

get_property(bin DIRECTORY PROPERTY BINARY_DIR) # Argümansız DIRECTORY örneği
get_property(bin_dir DIRECTORY ExampleProject PROPERTY BINARY_DIR) # Argümanlı DIRECTORY örneği
get_property(bin_target TARGET TestTarget PROPERTY BINARY_DIR) # TARGET örneği
get_property(language_source SOURCE ExampleProject/main.cpp PROPERTY LANGUAGE) # SOURCE örneği
get_property(cache_type CACHE TestCache PROPERTY TYPE) # CACHE örneği


message("BINARY_DIR: ${bin}")
message("BINARY_DIR (ExampleProject): ${bin_dir}")
message("BINARY_DIR (TestTarget): ${bin_target}")
message("LANGUAGE (ExampleProject/main.cpp): ${language_source}")
message("VALUE (TestCache): ${cache_type}")
ÇIKTI
BINARY_DIR: C:/Users/CMake-Example/build
BINARY_DIR (ExampleProject): C:/Users/CMake-Example/build/ExampleProject
BINARY_DIR (TestTarget): C:/Users/CMake-Example/build
LANGUAGE (ExampleProject/main.cpp): CXX
VALUE (TestCache): STRING

Örneklerden varlık türüne göre get_property komutunun nasıl bir form aldığını açıkça görebilirsiniz. Burada kullanılan önceden tanımlı Property isimlerine ve ne işe yaradıklarına şimdilik takılmayın. Bunları daha sonraki yazılarda ayrıntılı olarak ele alacağım. Şimdi de Property’lere değer vermek için kullanılan set_property komutunun genel biçimine bakalım:

set_property(entitySpecific [APPEND] [APPEND_STIRNG] PROPERTY <name> [<value1> …])

Yine entitySpecific kısmına gelebilen anahtar kelime ve argümanları get_ptoperty komutundakine benzerdir:

  • GLOBAL
  • DIRECTORY [<dir>]
  • TARGET [<target1> …]
  • SOURCE [<src1> …] [DIRECTORY <dirs> …] [TARGET_DIRECTORY <targets> …]
  • INSTALL [<file1> …]
  • TEST [<test1> …]
  • CACHE [<entry1> …]

APPEND anahtar kelimesini kullanırsanız, yeni değeri Property’nin varolan değerine bağlamış olursunuz. APPEND_STRING ise bu bağlamayı String olarak yapacaktır. Şimdi birkaç set_property kullanımına bakalım:

set_property(GLOBAL PROPERTY USE_FOLDER OFF) # Global Property
set_property(DIRECTORY PROPERTY CLEAN_NO_CUSTOM OFF) # Directory Property

add_executable(Program main.cpp)

add_library(ui UI/ui.cpp)
add_library(engine Engine/Core/math.cpp)

set_property(TARGET Program APPEND PROPERTY BUILD_RPATH ui engine) # Target Property
set_property(SOURCE main.cpp PROPERTY LANGUAGE cxx) # Source Property

get_property(global_example GLOBAL PROPERTY USE_FOLDER)
get_property(dir_example DIRECTORY PROPERTY CLEAN_NO_CUSTOM)
get_property(target_example TARGET Program PROPERTY BUILD_RPATH)
get_property(source_example SOURCE main.cpp PROPERTY LANGUAGE)

message("Global USE_FOLDER: ${global_example}")
message("Directory CLEAN_NO_CUSTOM: ${dir_example}")
message("Target Program BUILD_RPATH: ${target_example}")
message("Source main.cpp LANGUAGE: ${source_example}")
ÇIKTI
Global USE_FOLDER: OFF
Directory CLEAN_NO_CUSTOM: OFF
Target Program BUILD_RPATH: ui;engine
Source main.cpp LANGUAGE: cxx

Burada şimdilik Property’lerin türlerine göre değerlerine nasıl erişeceğimiz ve onları nasıl değiştireceğimizi anlamamız önemlidir. get_property komutunda sadece dizin Property’si ile çalışırken alt dizin ismini belirtmek seçenekseldi. Ancak set_property komutunda yazacağınız bütün dizin, hedef veya kaynak dosya isimleri seçenekseldir. Yani bu anahtar kelimelerden sonra hiçbir şey de yazmayabilirsiniz veya birden fazla şey de yazabilirsiniz (dizin Property’si hariç). Örnek:

set_property(DIRECTORY PROPERTY XXX value)
set_property(DIRECTORY dir1 PROPERTY XXX value)
set_property(TARGET PROPERTY XXX value)
set_property(TARGET target1 PROPERTY XXX value)
set_property(TARGET target1 target2 target3 PROPERTY XXX value)
set_property(SOURCE PROPERTY XXX value)
set_property(SOURCE src1 PROPERTY XXX value)
set_property(SOURCE src1 src2 src3 PROPERTY XXX value)
set_property(SOURCE src1 DIRECTORY dir1 PROPERTY XXX value)

Peki biz bir Property tanımlayabilir miyiz? define_property komutu ile bunu yapmamız mümkündür. Ancak bu komuta genellikle nadiren ihtiyaç duyulur. Yine de komutun prototipini ve kullanımını görelim:

define_property(<GLOBAL | DIRECTORY | TARGET | SOURCE | TEST | VARIABLE | CACHED_VARIABLE>
PROPERTY <name> [INHERITED]
[BRIEF_DOCS <brief-doc> [docs…]]
[FULL_DOCS <full-doc> [docs…]]
[INITIALIZE_FROM_VARIABLE <variable>])

Komuta yazılan ilk anahtar kelime tanımlanacak Property’nin türünü belirtmektedir. Eğer herhangi bir varlık türü yazılmazsa, tanımlanacak Property’nin türü VARIABLE olarak ele alnır. Property ismini yazdıktan sonra BRIEF_DOCS ile ona kısa bir açıklama yazabilir, FULL_DOCS ile ona ayrıntılı ve daha uzun bir açıklama (dokümantasyon) yazabilirsiniz. Bu komut herhangi bir Property’e değer vermez. Onu sadece tanımlar. Bu komut ile tanımlanan bir Property üzerinde get_property komutunu DEFINED anahtar kelimesi ile kullandığınızda, true değerini elde edersiniz. Aynı şekilde bu komut ile kısa veya uzun dokümantasyon tanımlanmışsa, get_property komutunun BRIEF_DOCS ve FULL_DOCS anahtar kelimeleri ile kullanımlarından bu dokümanlar geri döner.

INHERITED anahatar kelimesi ise tanımladığımız bu Property’e bu faaliyet alanında bir değer verilmemişse, üst faaliyet alanlarına özyinelemeli olarak bakılmasını söyler. Örneğin bir hedef Property’si tanımladığınızda ve o anki faaliyet alanında bu Property bulunamadıysa, üst faaliyet alanlarında arama yapılacaktır. INTIALIZE_FROM_VARIABLE anahtar kelimesi ise CMake 3.23 ile bu komuta eklenmiştir. Bu anahtar kelimenin yanına yazdığınız değişken ile, tanımladığınız Property’e ilk değer verebilirsiniz. Bu sadece hedef (target) Property’leri için geçerlidir. “<variable>” ismi Property ismi ile bitmelidir ve CMAKE_ veya _CMAKE_ ön ekleri ile başlamamalıdır. Şimdi define_property ile ilgili örneklere bakalım:

cmake_minimum_required(VERSION 3.25)
project(TestProject)

define_property(GLOBAL PROPERTY TEST_GLOB_PROP
                           BRIEF_DOCS "Bu bir test global Property dir."
                           FULL_DOCS "Bu bir test global Property dir. Bu daha uzun bir aciklamadir.")

define_property(TARGET PROPERTY TEST_TARGET_PROP
                           BRIEF_DOCS "Bu bir test target Property dir.")

add_executable(target ExampleProject/main.cpp)

get_property(is_glob_defined GLOBAL PROPERTY TEST_GLOB_PROP DEFINED)
get_property(glob_full_docs GLOBAL PROPERTY TEST_GLOB_PROP FULL_DOCS)
get_property(target_full_docs TARGET target PROPERTY TEST_TARGET_PROP BRIEF_DOCS)

get_property(before_set TARGET target PROPERTY TEST_TARGET_PROP)
set_property(TARGET target PROPERTY TEST_TARGET_PROP "Test Value")
get_property(after_set TARGET target PROPERTY TEST_TARGET_PROP)

message("TEST_GLOB_PROP DEFINED: ${is_glob_defined}")
message("TEST_GLOB_PROP FULL_DOCS: ${glob_full_docs}")
message("TEST_TARGET_PROP BRIEF_DOCS: ${target_full_docs}")
message("Before set TEST_TARGET_PROP for target: ${before_set}")
message("After set TEST_TARGET_PROP for target: ${after_set}")
ÇIKTI
TEST_GLOB_PROP DEFINED: 1
TEST_GLOB_PROP FULL_DOCS: Bu bir test global Property dir. Bu daha uzun bir aciklamadir.
TEST_TARGET_PROP BRIEF_DOCS: Bu bir test target Property dir.
Before set TEST_TARGET_PROP for target:
After set TEST_TARGET_PROP for target: Test Value

Bu örnekten neredeyse Property’ler ile ilgili tüm genel komutların kullanımlarını ve çeşitli anahtar kelimelerin etkilerini görebilirsiniz. define_property komutundaki BRIEF_DOCS ve FULL_DOCS anahtar kelimelerinin kullanımları tamamen seçenekseldir. Eğer bunları vermezseniz, kullanıcı get_property ile bunları elde etmeye kalktığında NOTFOUND değerini alacaktır. Ayrıca get_property komutu ile kullanılan DEFINED anahtar kelimesi ile elde edilen değerin define_property kullanımından sonra nasıl değişiklik gösterdiğine dikkat edin.

Böylelikle bu yazıda genel anlamda Property’lerden bahsedip çeşitli Property türlerini kısaca incelemiş olduk. Ayrıca genel anlamda tüm Property çeşitleri ile ilgili olan get_property, set_property ve define_property komutlarının kullanımlarını inceledik. İleriki yazılarda her bir Property türüne özel komutları görecek ve önemli önceden tanımlanmış CMake Property’lerini inceleyeceğiz.

0 0 votes
Article Rating
Subscribe
Bildir
guest

0 Yorum
Inline Feedbacks
View all comments