$<CONFIG>
返回正确的配置,但是否可以将其值存储到变量中?怎么做?
下面的最小示例似乎只需要在它调用的add_custom_command
或GetCurrentConfiguration.cmake
中类似于set(currentBuildType $<CONFIG>)
的东西,但我不知道什么语法可能允许它。
CMakeLists.txt:
cmake_minimum_required(VERSION 3.26.0...3.26.3)
project(LinkLibraryWithoutConfigCmake VERSION 0.0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_executable(targetExe Main.cpp)
set(absolutePathToInstallTrunk /opt/somewhere/install)
set(currentBuildType unknown)
add_custom_command(TARGET targetExe PRE_BUILD
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/GetCurrentConfiguration.cmake
COMMAND ${CMAKE_COMMAND} -E echo "-- In add_custom_command echo:"
COMMAND ${CMAKE_COMMAND} -E echo " CONFIG = $<CONFIG>, CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}, currentBuildType = ${currentBuildType}"
)
./GetCurrentConfiguration.cmake
set(currentBuildType $<CONFIG>)
function(GetBuildType returnBuildType)
set(${returnBuildType} $<CONFIG> PARENT_SCOPE)
message(STATUS "In function GetBuildType:\n CONFIG = $<CONFIG>, CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}, returnBuildType: ${returnBuildType}")
endfunction()
GetBuildType(currentBuildType)
message(STATUS "In GetCurrentConfiguration.cmake:\n CONFIG = $<CONFIG>, CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}, currentBuildType = ${currentBuildType}")
以下是单配置(#1和#2)和多配置(#3和#4)生成器的configure/build命令的输出:
1
cmake -S . -B buildNinja -G Ninja -D CMAKE_BUILD_TYPE=Debug
cmake --build buildNinja
-- In function GetBuildType:
CONFIG = `$<CONFIG>`, CMAKE_BUILD_TYPE = , returnBuildType: currentBuildType
-- In GetCurrentConfiguration.cmake:
CONFIG = `$<CONFIG>`, CMAKE_BUILD_TYPE = , currentBuildType = `$<CONFIG>`
-- In add_custom_command echo:
**CONFIG = Debug**, CMAKE_BUILD_TYPE = Debug, currentBuildType = unknown
2
cmake -S . -B buildNinja -G Ninja -D CMAKE_BUILD_TYPE=Release
cmake --build buildNinja
-- In function GetBuildType:
CONFIG = `$<CONFIG>`, CMAKE_BUILD_TYPE = , returnBuildType: currentBuildType
-- In GetCurrentConfiguration.cmake:
CONFIG = `$<CONFIG>`, CMAKE_BUILD_TYPE = , currentBuildType = `$<CONFIG>`
-- In add_custom_command echo:
**CONFIG = Release**, CMAKE_BUILD_TYPE = Release, currentBuildType = unknown
3
cmake -S . -B buildNinjaMC -G "Ninja Multi-Config"
cmake --build buildNinjaMC --config Debug
-- In function GetBuildType:
CONFIG = `$<CONFIG>`, CMAKE_BUILD_TYPE = , returnBuildType: currentBuildType
-- In GetCurrentConfiguration.cmake:
CONFIG = `$<CONFIG>`, CMAKE_BUILD_TYPE = , currentBuildType = `$<CONFIG>`
-- In add_custom_command echo:
**CONFIG = Debug**, CMAKE_BUILD_TYPE = , currentBuildType = unknown
4
cmake --build buildNinjaMC --config Release
-- In function GetBuildType:
CONFIG = `$<CONFIG>`, CMAKE_BUILD_TYPE = , returnBuildType: currentBuildType
-- In GetCurrentConfiguration.cmake:
CONFIG = `$<CONFIG>`, CMAKE_BUILD_TYPE = , currentBuildType = `$<CONFIG>`
-- In add_custom_command echo:
**CONFIG = Release**, CMAKE_BUILD_TYPE = , currentBuildType = unknown
请注意,在每种情况下,最后一行都给出了CONFIG的正确值,因此似乎应该可以捕获它,但如何捕获呢?
这样做的目的是将currentBuildType
附加到absolutePathToInstallTrunk
,以便可以链接正确的导入库(这适用于没有 *Config.cmake的导入库),例如:在CMake脚本中,也会有:
add_library(StaticLib::StaticLib STATIC IMPORTED)
include(GNUInstallDirs)
target_include_directories(StaticLib::StaticLib
INTERFACE
${absolutePathToInstallTrunk}/${CMAKE_INSTALL_INCLUDEDIR}
)
set_target_properties(StaticLib::StaticLib
PROPERTIES
IMPORTED_LOCATION ${absolutePathToInstallTrunk}/${CMAKE_INSTALL_LIBDIR}/${currentBuildType}/libStaticLibName.a
)
我尝试了一个简单的方法:
add_custom_command(TARGET targetExe PRE_BUILD
COMMAND set(currentBuildType $<CONFIG>)
)
这将配置,但构建失败,并显示:
Environment variable ( currentBuildType Debug ) not defined
ninja: build stopped: subcommand failed.
我还尝试将CONFIG设置为一个函数中的变量,该函数返回parent_scope中的变量:
function(GetBuildType returnBuildType)
set(${returnBuildType} $<CONFIG> PARENT_SCOPE)
该函数通过脚本在add_custom_command中调用:
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/GetCurrentConfiguration.cmake
但是该值并没有像前面的输出中所示的那样设置。
3条答案
按热度按时间js81xvg61#
生成器表达式的全部意义在于,它是在 * 生成 * 阶段而不是在配置阶段进行评估/扩展的,因此它可以扩展为根据多配置生成器的构建配置而变化的值。值将在生成时扩展。直到生成时间(在配置时间期间,生成器表达式将只是:生成器表达式)。配置脚本中的CMake变量在配置时进行计算。
仅供参考,你尝试的很多事情都是...奇怪。首先,在脚本模式下运行另一个CMake作为自定义命令,脚本模式-CMake(据我所知)不会对生成器表达式做任何事情,因为它是脚本模式-它不会生成构建系统。因此,尝试使用
$<CONFIG>
将被视为字符串。当你试图将一个变量传递给一个函数时,你要么需要使用一个变量(de)引用来传递值并在函数中使用该值,要么传递变量的名称,并在函数中“解引用”它。您的
GetBuildType(currentBuildType)
将变量名传递给函数,而您的函数只需取消引用其参数名即可获得字符串currentBuildType
。在CMake脚本的自定义命令调用中引用
CMAKE_BUILD_TYPE
的尝试将扩展为空,因为脚本没有这样的变量,并且不存在的变量将扩展为空。要在脚本模式下调用CMake配置中的CMAKE_BUILD_TYPE
变量,需要使用-D
将该变量传递给脚本。自定义命令在生成buildsystem之后的构建期间运行。生成器表达式在生成阶段进行计算,即生成构建系统的过程中。所以如果你想在自定义命令中使用生成器表达式...照做吧如果要将计算值传递给自定义命令中调用的脚本.照做吧然后在GetCurrentConfiguration.cmake中,
$<CONFIG>
生成器表达式的计算值将位于名为CONFIG
的变量中。不,没有技巧可以在作为自定义命令的一部分调用的CMake脚本中获取求值的生成器表达式,然后在配置自定义命令的配置脚本中获取该值。同样,自定义命令在构建时运行-完全在生成buildsystem完成之后。并且
$<CONFIG>
生成器表达式(和其他生成器表达式)在生成阶段之前不会被计算,因为在配置阶段不可能同时在一个变量中有多个单独的不同值。mnowg1ta2#
这是一个更简单的解决方案,并根据上面的评论进行了更正:
CMakeLists.txt
./GetCurrentConfiguration.cmake
输出为:
1
2
3
4
kupeojn63#
将
currentBuildType
作为参数传递给脚本(如@Tsyvarev所建议的):COMMAND ${CMAKE_COMMAND} -D currentBuildType=$ -P ${CMAKE_CURRENT_LIST_LIST}/GetCurrentConfiguration.cmake
没有在该脚本中生成有效的配置,即打印${currentBuildType}将给出文字字符串“
$<CONFIG>
“,而不是“Release”或“RelWithDebInfo”。但是按照这个想法,这里有一些修改过的脚本可以工作-只要配置值只在调用的脚本中使用,并且在主CMakeLists.txt中不需要它:./GetCurrentConfiguration.cmake
输出显示,单配置和多配置生成器的相关配置确实已被捕获,但它只保留在调用的脚本中,即到已安装库的路径有一个currect_appeared-它是“/release/”或/Release/”-但有点不幸的是,只在调用的脚本中:
1
cmake -S . -B buildNinja -G Ninja -D CMAKE_BUILD_TYPE= 0
cmake --build buildNinja
--在GetCurrentConfiguration.cmake中:CONFIG = $,CMAKE_BUILD_TYPE = NULL,installDirValidOnlyInThisScript = /opt/somewhere/install/lib/NULL
--在add_custom_command ECHO中:CONFIG = 0,CMAKE_BUILD_TYPE = 0,absolutePathToInstalledLibrary = /opt/somewhere/install/lib
2
cmake -S . -B buildNinja -G Ninja -D CMAKE_BUILD_TYPE=发行版
cmake --build buildNinja
--在GetCurrentConfiguration.cmake中:CONFIG = $,CMAKE_BUILD_TYPE = Release,installDirValidOnlyInThisScript = /opt/somewhere/install/lib/Release
--在add_custom_command ECHO中:CONFIG = Release,CMAKE_BUILD_TYPE = Release,absolutePathToInstalledLibrary = /opt/somewhere/install/lib
3
cmake -S . -B buildNinjaMC -G“Ninja Multi-Config”
cmake --build buildNinjaMC --config配置文件
--在GetCurrentConfiguration.cmake中:CONFIG = $,CMAKE_BUILD_TYPE = NULL,installDirValidOnlyInThisScript = /opt/somewhere/install/lib/NULL
--在add_custom_command ECHO中:CONFIG =配置文件,CMAKE_BUILD_TYPE =,absolutePathToInstalledLibrary = /opt/somewhere/install/lib
4
cmake -S . -B buildNinjaMC -G“Ninja Multi-Config”
cmake --build buildNinjaMC --config发布
--在GetCurrentConfiguration.cmake中:CONFIG = $,CMAKE_BUILD_TYPE = Release,installDirValidOnlyInThisScript = /opt/somewhere/install/lib/Release
--在add_custom_command ECHO中:CONFIG = Release,CMAKE_BUILD_TYPE =,absolutePathToInstalledLibrary = /opt/somewhere/install/lib
请注意,变量
installDirValidOnlyInThisScript
每次都有正确的值,但在父级CMakeLists.txt中,absolutePathToInstalledLibrary
的值没有附加配置名称的后缀。