【问题标题】:Best way to check with CMake whether list containts a specific entry使用 CMake 检查列表是否包含特定条目的最佳方法
【发布时间】:2014-06-12 22:34:18
【问题描述】:

我想检查列表是否包含特定条目,如以下代码片段:

macro(foo)
if ($(ARGN} contains "bar")
  ...
endif
endmacro()

CMake 不提供contains。获得所需结果的最佳/最简单方法是什么?

在 CMake 的 wiki 中,我发现了一个 LIST_CONTAINS 宏,但 wiki 页面已过时。这仍然是最好的方法还是 CMake 获得了新功能?

【问题讨论】:

    标签: cmake


    【解决方案1】:

    对于 CMake 3.3 或更高版本,if 命令支持 IN_LIST operator,例如:

    if ("bar" IN_LIST _list)
     ...
    endif()
    

    对于旧版本的 CMake,您可以使用内置的 list(FIND) 函数:

    list (FIND _list "bar" _index)
    if (${_index} GREATER -1)
      ...
    endif()
    

    【讨论】:

    • 我不推荐这个有几个原因。在宏的范围内(根据 OP),您必须复制 ARGN 否则这将静默失败。此外,对于大型列表,这比我的回答要慢得多。
    • @Fraser 为什么会默默地失败?
    • 我必须在第一个参数 "${ARGN}" 周围添加引号。也许这与弗雷泽的评论有关。
    • docs for macro,特别是注意事项,解释一下。如果您在 macro 中尝试 list(FIND ARGN "bar" _index) ,它将始终将 _index 设置为 -1,因为 ARGN 不是这里的普通变量。
    【解决方案2】:

    行数更少:

    if (";${ARGN};" MATCHES ";bar;")
      #  ...
    endif()
    

    但请参阅 @sakra 中的 IN_LIST 语法以获得更现代的语法。

    【讨论】:

      【解决方案3】:

      我一直在使用if ("${PLATFORM}" MATCHES "^(os|ios|android|linux|win32)$") 之类的衬垫来检查PLATFORM 是否在列表中

      【讨论】:

      • 这可能适合您的用例,但通常不起作用。 (a) 你必须知道列表,动态列表是行不通的。 (b) 列表限于十几个条目,否则难以维护。 (c) 对读者来说,这种感冒应该做什么不太明显。 (d) MATCHES 很慢,因为它使用正则表达式。
      【解决方案4】:

      如果这里的目的是向列表中添加一个值但前提是它尚未在列表中,那么另一种方法是将其添加到列表中并立即再次删除可能的重复项:

      list(APPEND            SOME_LIST "value")
      list(REMOVE_DUPLICATES SOME_LIST)
      

      【讨论】:

      • 获得一些数字来比较性能会很有趣。从代码方面来说,阅读起来很好。
      猜你喜欢
      • 1970-01-01
      • 2013-08-15
      • 2016-07-02
      • 2021-02-18
      • 2011-06-04
      • 2021-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多