Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用CMake中的CONFIG generator表达式提取复杂配置的部分_Cmake - Fatal编程技术网

如何使用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.1
Visual 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,并使用
    #if
    检查来处理C/C++代码中的差异

  • 您不是根据配置进行区分,而是根据其他目标进行区分(如
    my\u target
    my\u target\u 2


这似乎是发电机中缺少的一项功能。VisualStudio本身在根据配置排除/包括源文件甚至整个项目方面没有问题。实际上,很高兴看到有一个文件,但在当前选择的配置中它是“非活动”的。我刚刚用VS2017和CMake 3.9.3检查了这一点。事实上,生成项目会发出许多警告(不仅仅是一次…)。事实上,该项目的产生并没有减少。正如我在上面的评论中所描述的,它确实使用了“Exclude From Build”属性!我对这个问题提出了一个问题(关于“假错误”):。