Flo*_*ian 245
在编写CMake脚本时,您需要了解很多关于语法以及如何在CMake中使用变量的知识.
字符串使用set()
:
set(MyString "Some Text")
set(MyStringWithVar "Some other Text: ${MyString}")
set(MyStringWithQuot "Some quote: \"${MyStringWithVar}\"")
或者string()
:
string(APPEND MyStringWithContent " ${MyString}")
列表使用set()
:
set(MyList "a" "b" "c")
set(MyList ${MyList} "d")
或者更好list()
:
list(APPEND MyList "a" "b" "c")
list(APPEND MyList "d")
文件名列表:
set(MySourcesList "File.name" "File with Space.name")
list(APPEND MySourcesList "File.name" "File with Space.name")
add_excutable(MyExeTarget ${MySourcesList})
set()
命令string()
命令list()
命令首先是"正常变量"以及您需要了解的关于其范围的事项:
CMakeLists.txt
,他们在一切从那里叫(集和add_subdirectory()
,include()
,macro()
和function()
).add_subdirectory()
和function()
命令是特殊的,因为他们的开拓自己的范围.
set(...)
只在那里可见,它们复制了它们被调用的范围级别的所有正常变量(称为父范围).set(... PARENT_SCOPE)
function(xyz _resultVar)
是设置set(${_resultVar} 1 PARENT_SCOPE)
include()
或macro()
脚本将直接在调用它们的范围内修改变量.其次是"全局变量缓存".您需要了解的有关缓存的事项:
CMakeCache.txt
二进制输出目录中的文件中.在生成之前,可以在CMake的GUI应用程序中修改Cache中的值.因此,与正常变量相比,它们具有a type
和a docstring
.我通常不使用GUI,所以我set(... CACHE INTERNAL "")
用来设置我的全局和持久值.
请注意,INTERNAL
缓存变量类型确实意味着FORCE
在CMake脚本中,如果使用set(... CACHE ... FORCE)
语法,则只能更改现有的Cache条目.这种行为是由CMake本身使用的,因为它通常不会强制Cache条目本身,因此您可以使用其他值预先定义它.
cmake -D var:type=value
,只是cmake -D var=value
或使用cmake -C CMakeInitialCache.cmake
.unset(... CACHE)
.缓存是全局的,您可以在CMake脚本中的任何位置设置它们.但我建议你三思而后行使用Cache变量(它们是全局的,它们是持久的).我通常更喜欢使用set_property(GLOBAL PROPERTY ...)
和set_property(GLOBAL APPEND PROPERTY ...)
语法来定义我自己的非持久性全局变量.
为避免陷阱,您应该了解以下有关变量的信息:
find_...
命令-如果成功的话-不要写自己的结果缓存变量"这样没有呼叫将再次搜索"set(MyVar a b c)
是"a;b;c"
和set(MyVar "a b c")
是"a b c"
list()
处理列表的命令functions()
而不是macros()
因为您不希望局部变量显示在父作用域中.project()
和enable_language()
调用设置的.因此,在使用这些命令之前设置一些变量可能很重要.有时只有调试变量有帮助.以下内容可以帮助您:
printf
调试样式message()
.CMake本身附带了一些随时可用的模块:CMakePrintHelpers.cmake,CMakePrintSystemInformation.cmakeCMakeCache.txt
二进制输出目录中的文件.如果make环境的实际生成失败,甚至会生成此文件.cmake --trace ...
来查看CMake的完整解析过程.这是最后一种储备,因为它会产生大量的输出.$ENV{...}
和写入set(ENV{...} ...)
环境变量$<...>
仅在CMake的生成器写入make环境时进行评估(它与解析器"就地"替换的普通变量进行比较)${${...}}
你可以给一个变量的变量名,并引用其内容.if()
命令)
if(MyVariable)
你可以直接检查变量真/假(无需这里封闭${...}
)1
,ON
,YES
,TRUE
,Y
,或一个非零数.0
,OFF
,NO
,FALSE
,N
,IGNORE
,NOTFOUND
,空字符串,或后缀结尾-NOTFOUND
.if(MSVC)
,但对于不知道这种语法快捷方式的人来说可能会让人感到困惑.set(CMAKE_${lang}_COMPILER ...)
if()
.这里是一个例子CMAKE_CXX_COMPILER_ID
是"MSVC"
和MSVC
是"1"
:
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
是的,因为它评估为 if("1" STREQUAL "1")
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
是错误的,因为它评估为 if("MSVC" STREQUAL "1")
if(MSVC)
cmake_policy(SET CMP0054 NEW)
为"仅if()
在不引用时将参数解释为变量或关键字".option()
命令
Civ*_*Fan 14
以下是一些快速而肮脏的基本示例.
设置变量:
SET(INSTALL_ETC_DIR "etc")
Run Code Online (Sandbox Code Playgroud)
使用变量:
SET(INSTALL_ETC_CROND_DIR "${INSTALL_ETC_DIR}/cron.d")
Run Code Online (Sandbox Code Playgroud)
设置变量:
SET(PROGRAM_SRCS
program.c
program_utils.c
a_lib.c
b_lib.c
config.c
)
Run Code Online (Sandbox Code Playgroud)
使用变量:
add_executable(program "${PROGRAM_SRCS}")
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
106724 次 |
最近记录: |