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中跨多行拆分字符串?_Cmake - Fatal编程技术网

如何在CMake中跨多行拆分字符串?

如何在CMake中跨多行拆分字符串?,cmake,Cmake,在我的项目中,我通常有一个策略,就是永远不要在文本文件中创建超过80行的行,这样它们就可以在各种编辑器中轻松编辑(你知道这是怎么回事)。但是有了CMake,我遇到了一个问题,我不知道如何将一个简单的字符串分割成多行,以避免一个巨大的行。考虑这个基本代码: set(MYPROJ_VERSION_MAJOR "1") set(MYPROJ_VERSION_MINOR "0") set(MYPROJ_VERSION_PATCH "0") se

在我的项目中,我通常有一个策略,就是永远不要在文本文件中创建超过80行的行,这样它们就可以在各种编辑器中轻松编辑(你知道这是怎么回事)。但是有了CMake,我遇到了一个问题,我不知道如何将一个简单的字符串分割成多行,以避免一个巨大的行。考虑这个基本代码:

set(MYPROJ_VERSION_MAJOR "1")
set(MYPROJ_VERSION_MINOR "0")
set(MYPROJ_VERSION_PATCH "0")
set(MYPROJ_VERSION_EXTRA "rc1")
set(MYPROJ_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_EXTRA}")

它已经超过了80列的限制。那么,我如何将CMake中的一行拆分为多行而不进行详细处理(multiple
list(APPEND…
或诸如此类)?

仍然有点详细,但是如果80个字符的限制真的让您感到不适,那么您可以重复将其附加到同一个变量:

set(MYPROJ_VERSION_MAJOR "1")
set(MYPROJ_VERSION_MINOR "0")
set(MYPROJ_VERSION_PATCH "0")
set(MYPROJ_VERSION_EXTRA "rc1")
set(MYPROJ_VERSION "${MYPROJ_VERSION_MAJOR}.")
set(MYPROJ_VERSION "${MYPROJ_VERSION}${MYPROJ_VERSION_MINOR}.")
set(MYPROJ_VERSION "${MYPROJ_VERSION}${MYPROJ_VERSION_PATCH}-")
set(MYPROJ_VERSION "${MYPROJ_VERSION}${MYPROJ_VERSION_EXTRA}")
message(STATUS "version: ${MYPROJ_VERSION}")
给出输出:

$ cmake  ~/project/tmp
-- version: 1.0.0-rc1
-- Configuring done
-- Generating done
-- Build files have been written to: /home/rsanderson/build/temp

在CMakeLists.txt文件或CMake脚本中,无法跨多行拆分字符串文字。如果在字符串中包含换行符,则字符串本身中将包含文字换行符

# Don't do this, it won't work, MYPROJ_VERSION will contain newline characters:
set(MYPROJ_VERSION "${VERSION_MAJOR}.
  ${VERSION_MINOR}.${VERSION_PATCH}-
  ${VERSION_EXTRA}")
但是,CMake使用空格分隔参数,因此您可以将作为参数分隔符的空格更改为任意新行,而无需更改行为

您可以重新表述这一较长的行:

set(MYPROJ_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_EXTRA}")
这两条较短的线:

set(MYPROJ_VERSION
  "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_EXTRA}")
它们完全相同。

CMake 3.0及更新版本 使用
字符串(CONCAT)
命令:

set(MYPROJ_VERSION_MAJOR "1")
set(MYPROJ_VERSION_MINOR "0")
set(MYPROJ_VERSION_PATCH "0")
set(MYPROJ_VERSION_EXTRA "rc1")
string(CONCAT MYPROJ_VERSION "${MYPROJ_VERSION_MAJOR}"
                             ".${MYPROJ_VERSION_MINOR}"
                             ".${MYPROJ_VERSION_PATCH}"
                             "-${MYPROJ_VERSION_EXTRA}")
尽管CMake 3.0和更新版本支持缩进,但如果字符串中没有缩进空格,则无法缩进第二行或后续行

CMake 2.8及以上版本 您可以使用列表。列表中的每个元素都可以放在新行上:

set(MYPROJ_VERSION_MAJOR "1")
set(MYPROJ_VERSION_MINOR "0")
set(MYPROJ_VERSION_PATCH "0")
set(MYPROJ_VERSION_EXTRA "rc1")
set(MYPROJ_VERSION_LIST "${MYPROJ_VERSION_MAJOR}"
                        ".${MYPROJ_VERSION_MINOR}"
                        ".${MYPROJ_VERSION_PATCH}"
                        "-${MYPROJ_VERSION_EXTRA}")
使用不带引号的列表连接时不带空格:

message(STATUS "Version: " ${MYPROJ_VERSION_LIST})
-- Version: 1.0.0-rc1
如果确实需要字符串,可以先将列表转换为字符串:

string(REPLACE ";" "" MYPROJ_VERSION "${MYPROJ_VERSION_LIST}")
message(STATUS "Version: ${MYPROJ_VERSION}")
-- Version: 1.0.0-rc1
原始字符串中的任何分号都将被视为列表元素分隔符,并被删除。他们必须逃脱:

set(MY_LIST "Hello World "
            "with a \;semicolon")

更新CMake 3.0及更新版本:

使用
\
可以继续行。看

CMake版本的可用性: Debian哮喘病(2013):2.8.9
Debian哮喘病后遗症:2.8.11
Debian Jessy(2015):3.0.2
Ubuntu 14.04(LTS):2.8.12
Ubuntu 15.04:3.0.2
Mac OSX:cmake-3可通过和

Windows:cmake-3可通过

获得原始问题中的示例仅涉及相对较短的字符串。对于较长的字符串(包括其他答案中给出的示例),a可能更好。从文件中:

开头的括号写为
[
后接零个或多个
=
后接
[
。相应的结尾括号写为
]
后接相同数量的
=
后接
]
。括号不能嵌套。打开和关闭支架可始终选择唯一长度,以包含其他长度的关闭支架

[……]

例如:

message([=[
This is the first line in a bracket argument with bracket length 1.
No \-escape sequences or ${variable} references are evaluated.
This is always one argument even though it contains a ; character.
The text does not end on a closing bracket of length 0 like ]].
It does end in a closing bracket of length 1.
]=])```

对于那些从这里带来的人,我想补充一些说明

行延续方法将不起作用,CMake无法解析由空格(缩进)和行延续组成的生成器列表

虽然字符串(CONCAT)解决方案将提供一个可以计算的生成器表达式,但如果结果包含空格,则计算的表达式将被引号包围

对于要添加的每个单独选项,必须构建一个单独的生成器列表,因此像我在下面所做的那样堆叠选项将导致构建失败:

string(CONCAT WARNING_OPTIONS "$<"
    "$<OR:"
        "$<CXX_COMPILER_ID:MSVC>,"
        "$<STREQUAL:${CMAKE_CXX_SIMULATE_ID},MSVC>"
    ">:"
    "/D_CRT_SECURE_NO_WARNINGS "
">$<"
    "$<AND:"
        "$<CXX_COMPILER_ID:Clang,GNU>,"
        "$<NOT:$<STREQUAL:${CMAKE_CXX_SIMULATE_ID},MSVC>>"
    ">:"
    "-Wall -Werror "
">$<"
    "$<CXX_COMPILER_ID:GNU>:"
    "-Wno-multichar -Wno-sign-compare "
">")
add_compile_options(${WARNING_OPTIONS})
要计算使用字符串(CONCAT)解决方案表示的冗长生成器表达式,每个生成器表达式必须计算为不带空格的单个选项:

string(CONCAT WALL "$<"
    "$<AND:"
        "$<CXX_COMPILER_ID:Clang,GNU>,"
        "$<NOT:$<STREQUAL:${CMAKE_CXX_SIMULATE_ID},MSVC>>"
    ">:"
    "-Wall"
">")
string(CONCAT WERROR "$<"
    "$<AND:"
        "$<CXX_COMPILER_ID:Clang,GNU>,"
        "$<NOT:$<STREQUAL:${CMAKE_CXX_SIMULATE_ID},MSVC>>"
    ">:"
    "-Werror"
">")
message(STATUS "Warning Options: " ${WALL} ${WERROR})
add_compile_options(${WALL} ${WERROR})
字符串(混凝土墙“$”)
字符串(CONCAT-WERROR“$”)
消息(状态“警告选项:${WALL}${WERROR})
添加编译选项(${WALL}${WERROR})
这可能与我发布答案的问题无关,不幸的是,我回答的问题被错误地标记为该问题的副本


生成器列表的处理和解析方式与字符串不同,因此,必须采取额外的措施将生成器列表拆分为多行。

要在代码中保持良好的缩进,只需简单地执行即可

message("These strings " "will all be "
        "concatenated. Don't forget "
        "your trailing spaces!")
或者直接用

string(CONCAT MYSTR "This and " "that "
                    "and me too!")

就像世卫组织有更多细节一样。然而,我认为这可能只是总结了要点。

CMake 3.0方法的问题在于它没有忽略缩进。这意味着多行字符串不能与代码的其余部分缩进。@void.pointer我遇到了同样的问题,您是否知道如何使用多行缩进?另外,如果要使用缩进并限制为80个字符,则另一种方法是这样做:
消息(“这是变量的值:
”${varValue}“
对于非常长的行,变量名后面的换行符甚至进一步改进了这种模式(在本例中不需要)。当然,猜测字符串中的双引号也需要用反斜杠转义是正确的,任何需要在字符串中显示为字符的反斜杠也需要用反斜杠转义吗?@JonathanLeffler是的,它们需要转义。语言规则如下:但确实令人困惑。另请参阅:如果我理解正确,请参阅e source还将在字符串中引入换行符。例如,“长度1”后面将有一个“\n”。有什么办法可以避免吗?没错,会有
\n
s。如果你不想这样,我不认为括号参数是你的解决方案。顺便说一句,它适用于3.x版,而不是2.xIt版。我可能值得在链接的“副本”上发布此答案的版本。这就是我遇到它时一直在寻找的答案。
message("These strings " "will all be "
        "concatenated. Don't forget "
        "your trailing spaces!")
string(CONCAT MYSTR "This and " "that "
                    "and me too!")