Open3
CMakeのexecute_processの出力を行に分割する

これ簡単な方法が無いの謎だよね。。
(改善前 -- regexで先頭から改行にマッチ、残り全体をsubmatch)
% time cmake -P mergecol.cmake > /dev/null
cmake -P mergecol.cmake > /dev/null 16.65s user 1.07s system 99% cpu 17.855 total
(改善後 -- string
コマンドでセミコロンを 0x01
に置き換えてから改行をセミコロンに置換)
% time cmake -P mergecol.cmake > /dev/null
cmake -P mergecol.cmake > /dev/null 7.68s user 0.86s system 99% cpu 8.630 total

一旦エスケープしてから置換する
function(split_lines in out)
string(ASCII 1 one)
string(ASCII 2 two)
string(ASCII 3 three)
string(ASCII 4 four)
string(REPLACE ";" "${one}" str "${in}")
string(REPLACE "[" "${two}" str "${str}")
string(REPLACE "]" "${three}" str "${str}")
string(REPLACE "\\" "${four}" str "${str}")
string(REPLACE "\n" ";" str "${str}")
set(${out} "${str}" PARENT_SCOPE)
endfunction()
function(decode_line in out)
string(ASCII 1 one)
string(ASCII 2 two)
string(ASCII 3 three)
string(ASCII 4 four)
string(REPLACE "${one}" ";" str "${in}")
string(REPLACE "${two}" "[" str "${str}")
string(REPLACE "${three}" "]" str "${str}")
string(REPLACE "${four}" "\\" str "${str}")
set(${out} "${str}" PARENT_SCOPE)
endfunction()
うーむ。。当然、セミコロンが入った元のデータが必要な場合は、 0x01
を元に戻す必要がある。今回は挙動にとって重要じゃないのでサボっている。

セミコロンだけだと不十分
さらに \
(backslash) 、 [
]
(ブラケット) もエスケープする必要がある。backslashは改行がセミコロンのエスケープに化けてしまうため。ブラケットは文字列中で特別扱いされるため。
これちょっと理解しづらい挙動だよなぁ。。(CMakeにはよくある事)