如何将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)