如何将CMake分号分隔列表转换为换行分隔列表?
例如:如何将CMake分号分隔列表转换为换行分隔列表?,cmake,Cmake,例如: 我应该用什么来代替TODO?CMake的列表以分号分隔。因此,“Hello”“There”“World”在内部表示为Hello;那里世界。因此,一个简单的解决方案是用换行符替换分号: set (txt "Hello" "There" "World") # TODO message (txt) # Prints "Hello\nThere\nWorld" (i.e. each list item on a new line 这在本例中有效,但让我们尝试一个更复杂的示例: string (
我应该用什么来代替TODO?CMake的列表以分号分隔。因此,
“Hello”“There”“World”
在内部表示为Hello;那里世界
。因此,一个简单的解决方案是用换行符替换分号:
set (txt "Hello" "There" "World")
# TODO
message (txt) # Prints "Hello\nThere\nWorld" (i.e. each list item on a new line
这在本例中有效,但让我们尝试一个更复杂的示例:
string (REPLACE ";" "\n" txt "${txt}")
[[[
]
是一个原始字符串,因此\
将被传递到列表的CMake内部表示中,而不会改变。内部表示为:;\;一,;二,;太尔;eee;四\\;rrr
。我们希望它能打印:
set (txt "" [[\;One]] "Two" [[Thre\;eee]] [[Four\\;rrr]])
这是因为它不知道不转换转义的实际分号。解决方案是使用正则表达式:
<blank line>
\
One
Two
Thre\
eee
Four\\
rrr
即,仅替换
如果前面有一个非\
字符(并将该字符放入替换字符中)。几乎可以工作,但它不处理第一个空元素,因为分号前面没有任何内容。最后的答案是允许字符串也开始:
string (REGEX REPLACE "[^\\\\];" "\\1\n" txt "${txt}")
哦,\\\
是因为CMake处理字符串文字时会删除一级转义,而正则表达式引擎会删除另一级转义。您也可以这样做:
string (REGEX REPLACE "(^|[^\\\\]);" "\\1\n" txt "${txt}")
但我认为这不清楚
也许有比这更简单的方法,但我找不到。不管怎么说,女士们先生们,这就是为什么你们永远不应该使用字符串作为你们的唯一类型,或者做带内字符串定界。不过,情况可能更糟——至少他们没有像Bash那样使用空格作为分隔符 我只是想添加一些我所看到的备选方案,只是使用了一个事实,即在末尾单独放置一条换行符:
string (REGEX REPLACE [[(^|[^\\]);]] "\\1\n" txt "${txt}")
set (txt "Hello" "There" "World")
foreach(line IN LISTS txt)
message("${line}")
endforeach()
这些方法的更普遍版本如下所示:
for_each()
带字符串
function(message_cr line)
message("${line}")
if (ARGN)
message_cr(${ARGN})
endif()
endfunction()
set(txt "Hello" "There" "World")
message_cr(${txt})
set(txt "Hello" "There" "World")
foreach(line IN LISTS txt)
string(APPEND multiline "${line}\n")
endforeach()
message("${multiline}")
function()
带字符串
function(message_cr line)
message("${line}")
if (ARGN)
message_cr(${ARGN})
endif()
endfunction()
set(txt "Hello" "There" "World")
message_cr(${txt})
set(txt "Hello" "There" "World")
foreach(line IN LISTS txt)
string(APPEND multiline "${line}\n")
endforeach()
message("${multiline}")
字符串(带“${multiline}”multiline)