Open3

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

okuokuokuoku

これ簡単な方法が無いの謎だよね。。

(改善前 -- 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
okuokuokuoku

一旦エスケープしてから置換する

https://github.com/okuoku/mergecol-proto/commit/855dd63c8c8dd561b5384d90ff0f902d218c8db9

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 を元に戻す必要がある。今回は挙動にとって重要じゃないのでサボっている。

okuokuokuoku

セミコロンだけだと不十分

さらに \ (backslash) 、 [ ] (ブラケット) もエスケープする必要がある。backslashは改行がセミコロンのエスケープに化けてしまうため。ブラケットは文字列中で特別扱いされるため。

https://gitlab.kitware.com/cmake/cmake/-/issues/19156

これちょっと理解しづらい挙動だよなぁ。。(CMakeにはよくある事)