ehnmsのブログ

ボケ防止

CmakeのCtestでWinの環境変数に複数の値を設定したい

結論から言うと、バックスラッシュ三個です。 言われてみれば普通の話。

変数に1つの値を設定する時(普通バージョン)

Cmakeを利用したプロジェクトでユニットテスト ctest を利用しているとします。該当するテストで、例えば example.cpp を利用したテストで環境変数を利用したいとき CMakeLists.txt に次のような記載をします。

add_executable(test_test example)
add_test(NAME example COMMAND test_test)
set_property(TEST example
             PROPERTY ENVIRONMENT MY_CONFIG_DIR=/usr/local/)

環境変数に一個だけ値を入れたいのであればこれでOK

変数に複数の値を設定する時(Linux)

けど、例えば PATH みたいな感じで環境変数複数の値を入れてやりたいときがあります。Linuxなら単純に、

set_property(TEST example
             PROPERTY ENVIRONMENT MY_CONFIG_DIR=/usr/local/:/mnt/share/nantoka)

ってやれば、あとはプログラム内部でデリミタを : として解析してあげればいいんです。普通ですね。

変数に複数の値を設定する時(Windows)

問題はWindowsWindowsだとドライブ文字の後の区切り文字が : であるため、環境変数の区切り文字が ; (semicolon)になっているのですよね。単純にやると以下のようになりそうじゃないですか。

set_property(TEST example
             PROPERTY ENVIRONMENT MY_CONFIG_DIR=C:/work;D:/docs)

これダメなんですよ。なぜかセミコロンで終了扱いにされているらしく、 getenv() とかで環境変数を見てみてもセミコロンの前までしか入っていないんです。この例だと C:/work までしか入ってない。 セミコロンがダメならバックスラッシュでエスケープしてあげれば行けるだろう!と思ってやってみても、意味がなく、同じ結果になります。

バックスラッシュ三個です

実はバックスラッシュを三個入れてあげるとうまく動作します。つまり以下の通りです。

set_property(TEST example
             PROPERTY ENVIRONMENT MY_CONFIG_DIR=C:/work\\\;D:/docs)

StackOverflowに解説がありました。

stackoverflow.com

Cmake的にはこの設定値を一回解釈し(ここでエスケープが外れる)、そのあと再度解釈するので、2回解釈します。つまり2回分エスケープしていないとダメなんですね。焦ってるとあんまり考えが及ばないので思いつかなかったけど言われてみると単純な理由だったけど、それどっかドキュメントに書いてほしかった。書いてあったらごめんなさい。

いじょうです。

ついに何のブログなのか意味不明になってきた。