CMake:如何添加仅针对一种配置执行的自定义命令?

Posted

技术标签:

【中文标题】CMake:如何添加仅针对一种配置执行的自定义命令?【英文标题】:CMake: How to add a custom command that is only executed for one configuration? 【发布时间】:2017-08-02 08:21:27 【问题描述】:

我想添加一个 cmake 自定义命令,该命令仅在使用 Visual Studio 多配置生成器时在调试配置中构建自定义目标时执行。有没有一种干净的方法可以做到这一点?

为了实现这一点,我首先尝试将整个命令列表包装在这样的生成器表达式中。

add_custom_command(
    ...
    COMMAND $<$<CONFIG:Debug>:cmake;-E;echo;foo>
)

但这在执行命令时会给我一个语法错误。经过反复试验,我得到了以下 hacky 解决方案。这会将命令列表的每个单词包装在一个生成器表达式中,如下所示。

add_custom_command(
    ...
    COMMAND $<IF:$<CONFIG:Debug>,cmake,echo>;$<IF:$<CONFIG:Debug>,-E, >;$<IF:$<CONFIG:Debug>,echo, >;$<IF:$<CONFIG:Debug>,foo, >
)

这在编译调试配置时执行cmake -E echo foo 命令,为所有其他配置执行虚拟命令echo " " " " " "

这很丑陋,必须根据主机系统更改虚拟命令。在 Linux 上,它可能是 ":" ":" ":" ":"。那么有没有更清洁的方法来做到这一点?

感谢您的宝贵时间!

【问题讨论】:

为什么不简单地if (CMAKE_BUILD_TYPE STREQUAL "Debug") add_custom_command(...) endif() 或者为什么不简单地制作两个自定义目标? 仅供参考,skypjack,CMAKE_BUILD_TYPE STREQUAL "Debug" 对 Visual Studio 项目无效。在这种情况下需要使用 CONFIG,但它是一个构建类型的属性,因为直到那时它才知道。您可能希望在 add_custom_command 中执行一个 cmake 脚本,并将 CONFIG 的值传递给它,例如 -DBUILD_CONFIG=$&lt;CONFIG&gt;。然后,在脚本中,您可以确定 BUILD_CONFIG 是否等于“DEBUG”等并采取相应措施。不过,这与您的要求略有不同。 @StAlphonzo 我没有将评论放在答案中,因为我实际上不习惯使用 VS。谢谢你的澄清。 @StAlphonzo 他们可以通过允许列表使我尝试的第一件事工作 ''''COMMAND $:cmake;-E;echo;foo>''''如果 COMMAND 参数为空字符串,则在生成器表达式中不执行任何命令。 【参考方案1】:

这是我的一段代码(在多个单配置和多配置平台上测试):

CMakeLists.txt

cmake_minimum_required(VERSION 3.8)

project(DebugEchoFoo NONE)

string(
    APPEND _cmd
    "$<IF:$<CONFIG:Debug>,"
        "$CMAKE_COMMAND;-E;echo;foo,"
        "$CMAKE_COMMAND;-E;echo_append"
    ">"
)

add_custom_target(
    $PROJECT_NAME
    ALL
    COMMAND "$_cmd"
    COMMAND_EXPAND_LISTS
)

注意COMMAND_EXPAND_LISTS 是关键字仅适用于 CMake 版本 >= 3.8

参考

Modern way to set compiler flags in cross-platform cmake project

【讨论】:

未经测试,我将您的答案标记为正确。现在我只需要等待,直到我们可以在 OUTPUT (gitlab.kitware.com/cmake/cmake/issues/12877) 中使用生成器表达式

以上是关于CMake:如何添加仅针对一种配置执行的自定义命令?的主要内容,如果未能解决你的问题,请参考以下文章

CMake基础教程(30)CMake构建系统概览

CMake基础教程(30)CMake构建系统概览

使用 CMake 的自定义 .h 和 cpp 的未定义符号 [关闭]

针对特定 API 级别的自定义 Android/Flutter 版本

如何仅列出我的自定义命令(Laravel)?

CMake系列之一:概念