相关疑难解决方法(0)

设置和使用变量的CMake语法是什么?

我问这个是下次我使用CMake的时候提醒自己的.它永远不会坚持,谷歌的结果也不是很好.

在CMake中设置和使用变量的语法是什么?

cmake

143
推荐指数
3
解决办法
11万
查看次数

将列表传递给CMake宏

我正在尝试编写一个宏,它通过给定的库列表.但是,宏中的消息调用仅打印列表的第一项.我在这做错了什么?

码:

    macro( FindLibs LIBRARY_NAMES_LIST )
        message( "inside ${LIBRARY_NAMES_LIST}" )
    endmacro()

    set( LIBRARY_NAMES_LIST lib1 lib2 lib3)
    message( "outside ${LIBRARY_NAMES_LIST}" )
    FindLibs(${LIBRARY_NAMES_LIST})
Run Code Online (Sandbox Code Playgroud)

输出:

message( "outside lib1 lib2 lib3" )
message( "inside lib1" )
Run Code Online (Sandbox Code Playgroud)

cmake

43
推荐指数
3
解决办法
2万
查看次数

与STREQUAL失败的CMake比较空字符串

我一直认为,如果你想比较两个字符串(但不是变量),你需要做的就是引用它:

if("${A}" STREQUAL "some string")
Run Code Online (Sandbox Code Playgroud)

但现在我发现这段代码有时打印出来oops:

cmake_minimum_required(VERSION 2.8)

if("d" STREQUAL "")
  message("oops...")
endif()
Run Code Online (Sandbox Code Playgroud)

可能是它的错误(因为它用Xcode打印,但不是用make打印)?还是有一些特殊的变量?

  • cmake:2.8.12,2.8.11.2
  • xcode:4.6.2,5.0.1

更新

有没有描述问题的命令字符串:

string(COMPARE EQUAL "${A}" "" result)
if(result)
  message("...")
endif()
Run Code Online (Sandbox Code Playgroud)

更新2

我期望从CMake 3.1.0开始实现的行为(参见CMP0054).

3.0.2 测试的输出:

CMake version: 3.0.2
Quoted test
Surprise!
Unquoted test
Surprise!
Run Code Online (Sandbox Code Playgroud)

3.1.0 测试的输出:

CMake version: 3.1.0
Quoted test
OK
Unquoted test
Surprise!
Run Code Online (Sandbox Code Playgroud)

cmake

26
推荐指数
2
解决办法
2万
查看次数

循环遍历字符串列表

我想循环遍历字符串中给出的项目列表.根据CMake的要求,项目以分号分隔.下列

cmake_minimum_required(VERSION 2.8)

FOREACH(LETTER "a;b;c")
  MESSAGE("<<${LETTER}>>")
ENDFOREACH()
Run Code Online (Sandbox Code Playgroud)

将字符串解释"a;b;c"为字符串文字.相反,当首先分配"a;b;c"变量时,所有变量都按预期进行.

cmake_minimum_required(VERSION 2.8)

SET(MYLIST "a;b;c")
FOREACH(LETTER ${MYLIST})
  MESSAGE("<<${LETTER}>>")
ENDFOREACH()
Run Code Online (Sandbox Code Playgroud)

这是循环列表的推荐方法还是有更优雅的解决方案?

foreach list cmake

22
推荐指数
1
解决办法
3万
查看次数

CMake:$ {}和"$ {}之间的差异"

在cmake中,有什么区别:

set(any_new_var ${old_var})
Run Code Online (Sandbox Code Playgroud)

set(any_new_var "${old_var}")
Run Code Online (Sandbox Code Playgroud)

有什么重要区别?我何时使用其中一种形式?

例如,我尝试下一个迷你测试

# test.cmake

# Variable 'a' isn't defined.
set(hola "${a}")

# message(${hola})
message("${hola}")
Run Code Online (Sandbox Code Playgroud)

这个迷你测试(cmake -P test.cmake)的输出是一个空行(因为'a'没有定义).如果我取消注释第一条消息,cmake会抛出一条消息错误:

CMake Error at prueba.cmake:6 (message):
  message called with incorrect number of arguments
Run Code Online (Sandbox Code Playgroud)

为什么在第二种情况下它不会抛出错误但是空行?

cmake

10
推荐指数
1
解决办法
3144
查看次数

如何在自定义CMake命令中包含文字双引号?

我正在尝试创建一个与某些环境变量一起运行的自定义命令,例如LDFLAGS,如果它包含空格,则需要引用它的值:

LDFLAGS="-Lmydir -Lmyotherdir"
Run Code Online (Sandbox Code Playgroud)

由于CMake的转义规则,我无法找到将此参数包含在CMake自定义命令中的方法.这是我到目前为止所尝试的:

COMMAND LDFLAGS="-Ldir -Ldir2" echo blah VERBATIM)
Run Code Online (Sandbox Code Playgroud)

产量 "LDFLAGS=\"-Ldir -Ldir2\"" echo blah

COMMAND LDFLAGS=\"-Ldir -Ldir2\" echo blah VERBATIM)
Run Code Online (Sandbox Code Playgroud)

产量 LDFLAGS=\"-Ldir -Ldir2\" echo blah

似乎我要么引用整个字符串,要么在作为命令的一部分使用时,转义的引号不会解析.

我希望既可以包含文字双引号,也可以作为为命令设置环境变量的更好方法.请注意,我仍然使用CMake 2.8,因此我没有在3.2中使用新的"env"命令.

请注意,这与何时引用变量不重复因为这些引用方法都不适用于这种特殊情况.

quotes escaping cmake literals

8
推荐指数
2
解决办法
7135
查看次数

CMake错误"如果给定参数"后跟括号,"NOT","EQUALS"等

CMake从以下行发出错误

if(NOT ($ENV{TnCfg} STREQUAL Linux_Build_Speech))
Run Code Online (Sandbox Code Playgroud)

错误是

CMakeLists.txt的CMake错误:37(如果):

    如果给出论点:

"NOT" "(" "STREQUAL" "Linux_Build_Speech" ")"
Run Code Online (Sandbox Code Playgroud)

指定了未知参数

有什么问题?该行是有效代码.

if-statement cmake

7
推荐指数
1
解决办法
6512
查看次数

CMake list to string:简单的分号替换

我对一个非常简单的例子感到困惑.我有一个标准列表,所以基本上它的字符串表示使用分号作为分隔符.我想用另一个替换它:

set(L1 "A" "B" "C")
message("L1: ${L1}")

string(REPLACE ";" "<->" L2 ${L1})
message("L2: ${L2}")
Run Code Online (Sandbox Code Playgroud)

这个片段打印:

L1: A;B;C
L2: ABC
Run Code Online (Sandbox Code Playgroud)

而且我不明白为什么.根据其他一些SO答案,我的字符串替换似乎有效.我究竟做错了什么 ?有没有办法将值存储A<->B<->C在我的第二个变量中?

注意:我使用CMake 3.7.2

cmake

7
推荐指数
2
解决办法
7591
查看次数

CMake:如何在目标之间重用源文件定义而不重复?

在我的 CMake 项目中,我有 2 个共享相同源代码文件的目标(静态库和共享库),如下所示:

add_library("${PROJECT_NAME}" STATIC
    "${PROJECT_SOURCE_DIR}/src/calculator/core/ShuntingYard.h"
    "${PROJECT_SOURCE_DIR}/src/calculator/core/ShuntingYard.cpp"
    "${PROJECT_SOURCE_DIR}/include/calculator/core/Calculator.h"
    "${PROJECT_SOURCE_DIR}/src/calculator/core/Calculator.cpp"
)
add_library("${PROJECT_NAME}-shared" SHARED
    "${PROJECT_SOURCE_DIR}/src/calculator/core/ShuntingYard.h"
    "${PROJECT_SOURCE_DIR}/src/calculator/core/ShuntingYard.cpp"
    "${PROJECT_SOURCE_DIR}/include/calculator/core/Calculator.h"
    "${PROJECT_SOURCE_DIR}/src/calculator/core/Calculator.cpp"
)
Run Code Online (Sandbox Code Playgroud)

显然,这里存在一个问题:源定义是重复的。它很难维护并且也容易出错。

为了避免这种情况,我想创建一个 CMake 列表变量,以便源定义可以在两个目标中重用。

我已经尝试过这个但它不起作用:

set(CALCULATOR_CORE_SOURCES_LIST
    "${PROJECT_SOURCE_DIR}/src/calculator/core/ShuntingYard.h"
    "${PROJECT_SOURCE_DIR}/src/calculator/core/ShuntingYard.cpp"
    "${PROJECT_SOURCE_DIR}/include/calculator/core/Calculator.h"
    "${PROJECT_SOURCE_DIR}/src/calculator/core/Calculator.cpp"
)
string(REPLACE ";" " " CALCULATOR_CORE_SOURCES "${CALCULATOR_CORE_SOURCES_LIST}")

add_library("${PROJECT_NAME}" STATIC ${CALCULATOR_CORE_SOURCES})
add_library("${PROJECT_NAME}-shared" SHARED ${CALCULATOR_CORE_SOURCES})
Run Code Online (Sandbox Code Playgroud)

它失败并出现错误:Cannot find source file.

那么...如何在目标之间重用源文件定义而不进行这种重复?是否可以使用列表来做到这一点,或者是否有更好的方法来解决这个问题?

PS:我使用的是CMake 3.15

cmake

4
推荐指数
1
解决办法
377
查看次数

CMAKE字符串比较失败

我想有选择地在我的CMakeLists文件中添加一些库路径,并且要做到这一点的方法是将变量设置为:

set(MYLIBDIR "DEFAULT")
Run Code Online (Sandbox Code Playgroud)

如果用户要指定自定义目录,则将其更改为:

set(MYLIBDIR /path/to/dir1
/path/to/dir2)
Run Code Online (Sandbox Code Playgroud)

因此,为了检查用户是否确实提供了额外的目录,我检查了:

if(NOT ${MYLIBDIR} STREQUAL "DEFAULT")
 link_directories(${MYLIBDIR})
endif()
Run Code Online (Sandbox Code Playgroud)

当我尝试这样做时,我从cmake中得到一个错误。有没有办法在字符串比较之前连接变量的所有元素?

cmake

3
推荐指数
1
解决办法
5729
查看次数

将列表转换为 cmake 函数的参数

假设我们有一个 CMake 函数func,它接受命名参数,比如NAMED1NAMED2。第一个参数是强制性的,第二个是可选的。例如

func(NAMED1 foo NAMED2 optional)
Run Code Online (Sandbox Code Playgroud)

现在我有一个循环需要func在每次迭代时调用这个函数,但根据当前的迭代,我有时需要提供可选值,有时不需要。所以在每次迭代时,我都会构建一个参数列表,比如

list(APPEND args "NAMED1" "foo")
if (...something...)
    list(APPEND args "NAMED2" "optional")
endif()
Run Code Online (Sandbox Code Playgroud)

所以我args现在有了清单。作为一个字符串,它可能看起来像

NAMED1;foo
Run Code Online (Sandbox Code Playgroud)

或者它可能看起来像

NAMED1;foo;NAMED2;optional
Run Code Online (Sandbox Code Playgroud)

所以我想用字符串替换整个列表

string(REPLACE ";" " " args "${args}")
Run Code Online (Sandbox Code Playgroud)

然后结果args看起来像

NAMED1 foo NAMED2 optional
Run Code Online (Sandbox Code Playgroud)

所以我想把这个字符串传递给函数func,用

func("${args}")
Run Code Online (Sandbox Code Playgroud)

但现在的问题是 CMake 认为这是一个大字符串,而它应该将其解释为单独的字符串。我怎样才能做到这一点?

cmake

3
推荐指数
1
解决办法
3502
查看次数

cmake很多INTERFACE_INCLUDE_DIRECTORIES

我正在创建一个导入目标,该目标希望公开两个接口包含目录:

list(APPEND LIB_INCLUDE_DIRS "dir1")
list(APPEND LIB_INCLUDE_DIRS "dir2")

add_library(lib SHARED IMPORTED GLOBAL)
set_target_properties(
    lib
    PROPERTIES
    IMPORTED_LOCATION "something"
    INTERFACE_INCLUDE_DIRECTORIES ${LIB_INCLUDE_DIRS}
)
Run Code Online (Sandbox Code Playgroud)

不幸的是,这是一个错误:set_target_properties的参数数目错误。

如果我尝试仅设置第一个目录,它将起作用。有办法设置两者吗?还是INTERFACE_INCLUDE_DIRECTORIES的复数形式具有讽刺意味?

cmake

2
推荐指数
1
解决办法
1417
查看次数

标签 统计

cmake ×12

escaping ×1

foreach ×1

if-statement ×1

list ×1

literals ×1

quotes ×1