Open2
CMakeのif()は変数を展開したりしなかったりする
このコミットでビルドが壊れた。
CMakeは if
文の仕様を途中で変えて、変数をダブルクオートすることで展開しないようになった 。よって、 cmake_minimum_required
を足すと挙動が変わってしまう。
macOSでは変数 APPLE
は 1
に初期化されるため、
set(host APPLE)
message(STATUS "Host: ${host} Apple: ${APPLE}")
if(host STREQUAL "APPLE")
message(STATUS "true")
else()
message(STATUS "false")
endif()
# 途中で前提バージョンを変更することでポリシを切り替える
cmake_minimum_required(VERSION 3.1)
if(host STREQUAL "APPLE")
message(STATUS "true")
else()
message(STATUS "false")
endif()
のようにすることで、挙動が変化することを確かめられる。
-- Host: APPLE Apple: 1
-- false
-- true
いやまぁ実際には、
-- Host: APPLE Apple: 1
CMake Warning (dev) at check.cmake:5 (if):
Policy CMP0054 is not set: Only interpret if() arguments as variables or
keywords when unquoted. Run "cmake --help-policy CMP0054" for policy
details. Use the cmake_policy command to set the policy and suppress this
warning.
Quoted variables like "APPLE" will no longer be dereferenced when the
policy is set to NEW. Since the policy is not set the OLD behavior will be
used.
This warning is for project developers. Use -Wno-dev to suppress it.
-- false
-- true
のようにバッチリ警告されるけど。
直した
CMakeでは変数参照も展開される
cmake_minimum_required(VERSION 3.1)
set(host APPLE)
# NG: ${host} => APPLE => 1 のように展開され、 (1 STREQUAL "APPLE") は偽
if(${host} STREQUAL "APPLE")
message(STATUS "OK")
else()
message(STATUS "NG")
endif()
# OK: APPLE == 1 なので、1と比較した場合は真となる
if(${host} STREQUAL "1")
message(STATUS "OK")
else()
message(STATUS "NG")
endif()
# OK: 変数参照をクオートすれば展開は止まる
if("${host}" STREQUAL "APPLE")
message(STATUS "OK")
else()
message(STATUS "NG")
endif()
は、
-- NG
-- OK
-- OK
のようになる。要するに慣れてないなら if
のパラメタは全部quoteしろという事で。。10年CMakeやってるけど年に1回は間違えてる気がする。