Yanıtlar:
CMake komut dosyaları yazarken, sözdizimi ve CMake'de değişkenlerin nasıl kullanılacağı hakkında bilmeniz gereken çok şey vardır.
Dizeleri kullanarak set()
:
set(MyString "Some Text")
set(MyStringWithVar "Some other Text: ${MyString}")
set(MyStringWithQuot "Some quote: \"${MyStringWithVar}\"")
Veya string()
:
string(APPEND MyStringWithContent " ${MyString}")
Şunu kullanan listeler set()
:
set(MyList "a" "b" "c")
set(MyList ${MyList} "d")
Veya daha iyisi list()
:
list(APPEND MyList "a" "b" "c")
list(APPEND MyList "d")
Dosya Adlarının Listeleri:
set(MySourcesList "File.name" "File with Space.name")
list(APPEND MySourcesList "File.name" "File with Space.name")
add_excutable(MyExeTarget ${MySourcesList})
set()
Komutustring()
Komutulist()
Komutuİlk olarak "Normal Değişkenler" ve kapsamları hakkında bilmeniz gereken şeyler vardır:
CMakeLists.txt
dedikleri ayarlanır ve her şeyi vardır orada ( add_subdirectory()
, include()
, macro()
ve function()
).add_subdirectory()
Ve function()
açtıkları-up çünkü kendi kapsamı komutları özeldir.
set(...)
Oradaki anlam değişkenleri sadece orada görülebilir ve çağrıldıkları kapsam seviyesinin tüm normal değişkenlerinin bir kopyasını oluştururlar (üst kapsam olarak adlandırılır).set(... PARENT_SCOPE)
function(xyz _resultVar)
,set(${_resultVar} 1 PARENT_SCOPE)
include()
veya macro()
komut dosyaları, değişkenleri doğrudan çağrıldıkları yer kapsamında değiştirir.İkincisi "Global Değişkenler Önbelleği" var. Önbellek hakkında bilmeniz gerekenler:
CMakeCache.txt
ikili çıktı dizininizdeki dosyada saklanır .Önbellekteki değerler , oluşturulmadan önce CMake'in GUI uygulamasında değiştirilebilir . Bu nedenle onlar - Normal değişkenlere göre - bir var type
bir docstring
. Normalde GUI kullanmıyorum, bu yüzden set(... CACHE INTERNAL "")
genel ve kalıcı değerlerimi ayarlamak için kullanıyorum .
Unutmayın ki INTERNAL
önbellek değişken türü anlamına gelmezFORCE
CMake komut dosyasında varolan Önbellek girdilerini yalnızca set(... CACHE ... FORCE)
sözdizimi kullanıyorsanız değiştirebilirsiniz . Bu davranış, örneğin CMake'in kendisi tarafından kullanılır, çünkü normalde Önbellek girdilerini zorlamaz ve bu nedenle başka bir değerle önceden tanımlayabilirsiniz.
cmake -D var:type=value
(yalnızca cmake -D var=value
veya) ayarlamak için komut satırını kullanabilirsiniz cmake -C CMakeInitialCache.cmake
.unset(... CACHE)
.Önbellek geneldir ve CMake komut dosyalarınızda neredeyse her yere ayarlayabilirsiniz. Ancak Önbellek değişkenlerini nerede kullanacağınızı düşünmenizi öneririm (bunlar globaldir ve kalıcıdır). Ben normalde kendi kalıcı olmayan değişkenlerimi tanımlamak için set_property(GLOBAL PROPERTY ...)
ve set_property(GLOBAL APPEND PROPERTY ...)
sözdizimini tercih ederim .
Tuzaklardan kaçınmak için değişkenler hakkında aşağıdakileri bilmelisiniz:
find_...
Başarılı olursa - - komutlar önbelleğe değişkenler olarak sonuçlarını yazabilirim "böylece hiçbir çağrı yeniden arama edeceğini"set(MyVar a b c)
öyle "a;b;c"
ve set(MyVar "a b c")
öyle"a b c"
list()
listeleri işleme komutunu tercih edinfunctions()
bunun yerine kullanılması önerilir macros()
.project()
ve enable_language()
çağrıları ile ayarlanır . Bu yüzden, bu komutlar kullanılmadan önce bazı değişkenlerin ayarlanması önemli olabilir.Bazen sadece hata ayıklama değişkenleri yardımcı olur. Aşağıdakiler size yardımcı olabilir:
printf
kullanarak eski hata ayıklama stilini message()
kullanın. CMake'in kendisi ile birlikte gelen bazı kullanıma hazır modüller de vardır: CMakePrintHelpers.cmake , CMakePrintSystemInformation.cmakeCMakeCache.txt
İkili çıktı dizininizdeki dosyaya bakın . Bu dosya, make ortamınızın gerçek nesli başarısız olursa bile oluşturulur.cmake --trace ...
CMake'in tam ayrıştırma işlemini görmek için arayın . Bu bir tür son rezerv, çünkü çok fazla çıktı üretiyor.$ENV{...}
ve yazabilirsinizset(ENV{...} ...)
$<...>
yalnızca CMake'nin jeneratörü marka oluşturma ortamını yazdığında değerlendirilir (ayrıştırıcı tarafından "yerinde" değiştirilen normal değişkenlerle karşılaştırılır)${${...}}
değişkene değişken isimleri verebilir ve içeriğine başvurabilirsiniz.if()
komuta bakınız )
if(MyVariable)
doğrudan sizinle doğru / yanlış için bir değişken (kapatmakta burada gerek kontrol edebilirsiniz ${...}
)1
, ON
, YES
, TRUE
, Y
, ya da sıfır olmayan bir sayı.0
, OFF
, NO
, FALSE
, N
, IGNORE
, NOTFOUND
, boş dize veya son eki biter -NOTFOUND
.if(MSVC)
, ancak bu sözdizimi kısayolunu bilmeyen biri için kafa karıştırıcı olabilir.set(CMAKE_${lang}_COMPILER ...)
if()
komutlarda baş ağrısına neden olabileceğini unutmayın . İşte bir örnek CMAKE_CXX_COMPILER_ID
olduğunu "MSVC"
ve MSVC
bir "1"
:
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
doğrudur, çünkü if("1" STREQUAL "1")
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
yanlıştır, çünkü if("MSVC" STREQUAL "1")
if(MSVC)
cmake_policy(SET CMP0054 NEW)
"yalnızca if()
bağımsız değişkenleri değişken veya anahtar kelime olarak tırnak işaretsiz olarak yorumla" olarak ayarlamanız önerilir .option()
komuta
ON
veya OFF
bunlar gibi bağımlılıklar gibi bazı özel işlemlere izin veriroption
olan set
komuta. Verilen değer option
gerçekten yalnızca "başlangıç değeri" dir (ilk yapılandırma adımı sırasında bir kez önbelleğe aktarılır) ve daha sonra CMake'in GUI'si aracılığıyla kullanıcı tarafından değiştirilmesi amaçlanır .${MyString}
için hataların bir grup potansiyel müşteri "eğer verilen argümanlar ..." gibi eğer yakınındaki CKağıt hatası: parantez ardından “verilen argümanlar eğer”, “DEĞİL”, “EŞİT” ve benzeri .
if (MyString ...)
(eğer kodunuz uyarı verirse).
İşte hızlı ve kirli başlamak için birkaç temel örnek.
Set değişkeni:
SET(INSTALL_ETC_DIR "etc")
Değişkeni kullan:
SET(INSTALL_ETC_CROND_DIR "${INSTALL_ETC_DIR}/cron.d")
Set değişkeni:
SET(PROGRAM_SRCS
program.c
program_utils.c
a_lib.c
b_lib.c
config.c
)
Değişkeni kullan:
add_executable(program "${PROGRAM_SRCS}")
if ("${MyString}" ...)
görüyorum uyarıları değilim:Policy CMP0054 is not set: Only interpret if() arguments as variables or keywords when unquoted
. Bkz. Örneğin, Yapı 367 . Herhangi bir fikir?