如何使用CMake中的CONFIG generator表达式提取复杂配置的部分
在我们的项目中,我们有大量的配置源于多种目标硬件类型乘以少数模式 为了避免不必要的细节,让我们假设配置的形式是如何使用CMake中的CONFIG generator表达式提取复杂配置的部分,cmake,Cmake,在我们的项目中,我们有大量的配置源于多种目标硬件类型乘以少数模式 为了避免不必要的细节,让我们假设配置的形式是 是以下三者之一:A、B或C 是其中之一:1、2或3 此外,为了保持接近实际情况,我们假设A_3和C_1是不受支持的例外。(不过,我认为这并不重要。) 这就给我们留下了3 x 3-2=7个受支持的配置 现在,我们希望设置(除其他外,还有编译器和sysroot的路径)取决于配置。此外,某些源仅应包含在某些配置中。我们更愿意根据部分配置来完成 例如,我们希望对所有A.*配置使用/thi
是以下三者之一:
、A
或B
C
是其中之一:
、1
或2
3
A_3
和C_1
是不受支持的例外。(不过,我认为这并不重要。)
这就给我们留下了3 x 3-2=7个受支持的配置
现在,我们希望设置(除其他外,还有编译器和sysroot的路径)取决于配置。此外,某些源仅应包含在某些配置中。我们更愿意根据部分配置来完成 例如,我们希望对所有
A.*
配置使用/this/g++
,对所有其他配置使用/this/g++
。或者,我们想为所有*\u 2
配置添加mode2.cpp
文件,但其他配置除外
这是一个简单的任务,如果我们使用。我们可以使用regex()将其拆分,并且每个部分都有变量。然后simple完成了这项工作
然而,这种方法对多配置生成器并不友好(目前似乎只有VisualStudio和Xcode)。为了更好地使用多配置生成器,我们必须使用
但是,问题是,我看不到任何方法可以提取生成器表达式中配置(
CONFIG
)的部分
例如,我可以这样做:
add_executable(my_prog
source_1.cpp
# ...
source_n.cpp
$<$<CONFIG:A_2>:mode2.cpp>
$<$<CONFIG:B_2>:mode2.cpp>
$<$<CONFIG:C_2>:mode2.cpp>
)
add_可执行文件(my_prog
来源1.cpp
# ...
资料来源
$
$
$
)
但考虑到我们迟早会添加新的硬件类型(或删除过时的硬件),这看起来不像是一种可维护的方法
有没有办法在生成器表达式中进行某种形式的匹配
到目前为止,我发现的唯一解决方法是使用如下方法:
set(CONFIG_IS_MODE_2 $<OR:$<CONFIG:A_2>,$<CONFIG:B_2>,$<CONFIG:C_2>>)
add_executable(my_target
source_1.cpp
# ...
source_n.cpp
$<${CONFIG_IS_MODE_2}:mode2.cpp>
)
set(配置为模式2$)
添加\u可执行文件(我的\u目标
来源1.cpp
# ...
资料来源
$
)
这至少允许集中这些表达式,当添加新的硬件类型时,只有一个地方需要更新。然而,仍然有许多变量需要更新
有更好的解决方案吗?使用命令和a,您仍然可以使用正则表达式来匹配您的配置 这类似于下面的示例代码:
cmake_最低要求(3.0版)
项目(TestConfigRegEx)
函数(my_add_sources_by_config_regex_target_regex)
foreach(\u config IN list CMAKE\u CONFIGURATION\u TYPE CMAKE\u BUILD\u TYPE)
if(_config匹配“${u regex}”)
目标源(${u目标}私有$)
endif()
endforeach()
endfunction()
文件(写入main.cpp“int main(){return 0;}”)
文件(写入modeRelease.cpp“”)
添加可执行文件(my_target main.cpp)
my_add_sources_by_config_regex(my_target Release modeRelease.cpp)
但这给了我一个CMake版本3.11.1Visual Studio 15 2017
生成器端的错误:
Target "my_target" has source files which vary by configuration. This is
not supported by the "Visual Studio 15 2017" generator.
Config "Debug":
.../main.cpp
Config "Release":
.../main.cpp
.../modeRelease.cpp
奇怪的是,它仍然产生了解决方案
备选方案
- 经典的方法是添加一个包含配置的define,并使用
检查来处理C/C++代码中的差异#if
- 您不是根据配置进行区分,而是根据其他目标进行区分(如
和my\u target
)my\u target\u 2