更正可能空的CMake列表的正确方法

时间:2018-03-22 08:09:13

标签: list path cmake quotes

最近又出现了一个老问题:设置CMAKE_MODULE_PATH的正确方法是什么?但这几乎适用于任何列表。但是,对于一般文本可能存在差异,但仅当该文本可能包含分号时才有IMO。

前提条件:该变量可能未设置,为空或设置

选项:

  1. set (CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmakeModules ${CMAKE_MODULE_PATH})
  2. set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmakeModules" ${CMAKE_MODULE_PATH})
  3. list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmakeModules)
  4. list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmakeModules")
  5. if (NOT CMAKE_MODULE_PATH) set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmakeModules") else() set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmakeModules;${CMAKE_MODULE_PATH}") endif()
  6. 包含一些推理:

    a)1。可能会失败,当路径中有空格时,必须使用2.以避免这种情况。这是对的吗? b)3/4看起来更好/更简洁。需要的空间是什么?
    c)5。(丑陋的)特殊情况处理1-4避免。这需要吗?

    相关:cmake: when to quote variables?

    但我仍然不确定何时使用引号,特别是在处理路径和列表时。

    奖励:评估期间到底发生了什么?如果在将变量传递给函数之前将所有${...}替换为变量的值,则例如以下不起作用,需要空格。但它确实按预期工作:

    set(FOO_DIR "my space path")
    set(CMAKE_LIST /usr)
    set(CMAKE_LIST ${CMAKE_LIST} ${FOO_DIR}/foo)
    oder: list(APPEND CMAKE_LIST ${FOO_DIR}/foo)
    

    这也适用于对其他功能的调用。 E.g:

    set_target_properties(MYTARGET PROPERTIES
      IMPORTED_LOCATION ${FOO_DIR}/foo
    )
    

    问题是:为什么?标准中的哪个指定了?

2 个答案:

答案 0 :(得分:2)

setlist都有效,可以将值附加到列表中:

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmakeModules)

set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmakeModules)

第一种形式(带有'列表')是首选,因为它更短,并且不会复制变量的名称。

通过引用附加值,结果列表不受影响。也就是说,在这种情况下,引用只是一种品味问题。

注意1 :引用并不仅仅影响特定情况(setlist命令)。在其他情况下,报价可能至关重要。

注意2 :如果当前路径包含分号(;),则会引用或不引用它进行错误处理。

为什么报价在这里毫无意义

假设变量A包含分号,例如

set(A "a/b;c/d")

的处理
 ${A}/cmakeModules

 "${A}/cmakeModules"
传递给函数时,

不同的:第一种情况被视为两个参数,第二种情况被视为单个参数。您可以在message()来电中查看该差异:

# give: a/bc/d/cmakeModules
message(STATUS ${A}/cmakeModules)
# give: a/b;c/d/cmakeModules
message(STATUS "${A}/cmakeModules")

但这两种治疗方法在list命令中都有相同的效果:

set(B "m") # Initial value
# Either command below sets B to 3(!) values: m;a/b;c/d/cmakeModules
list(APPEND B ${A}/cmakeModules)
list(APPEND B "${A}/cmakeModules")

可以将其视为" CMake变量包含展平列表"。

答案 1 :(得分:1)

a)真实

b)错误。是的,我也喜欢这种方式。

c)错误