web-dev-qa-db-ja.com

CMakeのジェネレータ式の三項演算子

Cmakeの ジェネレータ式 特定の関数呼び出し内で論理式を使用できるようにします。たとえば、デバッグモードで/MTdコンパイラフラグを追加したい場合は、次のように言うことができます。

add_compile_options($<$<CONFIG:Debug>:/MTd>)

CONFIGが "Debug"と等しい場合、値 "/ MTd"でadd_compile_optionsを呼び出します。それ以外の場合は、空の文字列を使用します。

しかし、通常、私は値と空の文字列の間ではなく、2つの値の間で決定したいと思います。上記の例では、CONFIGnot "Debug"の場合、/MTを渡します(末尾のdなし)。次のような構文が欲しいのですが。

add_compile_options($<$<CONFIG:Debug>:/MTd:/MT>)

上記は、CMakeの仕様によると無効なコードであることに注意してください。私が思いついた、実際に機能する最高のものはこれです:

add_compile_options($<$<CONFIG:Debug>:/MTd>$<$<NOT:$<CONFIG:Debug>>:/MT>)

これは私にはひどく冗長に思えます。 2つの値のどちらかを決定するための、より短く、より読みやすい方法はありますか?

注:この特別なケースでは、次のように書くことができます。

add_compile_options(/MT$<$<CONFIG:Debug>:d>)

しかし、これは私にはかなりハッキーに思え、一方のオプションがもう一方の部分文字列である場合にのみ機能します。

22
Daniel Wolf

Cmake 3.8は、式を生成するために必要なものを正確に追加したことに注意してください...

$<IF:?,true-value...,false-value...>
true-value... if ? is 1, false-value... if ? is 0

使用例:

target_link_libraries(MyLib PUBLIC
    $<IF:$<CONFIG:Debug>,cppzmq,cppzmq-static>
    )

ここで、cppzmqDebugビルドで使用される共有ライブラリであり、cppzmq-staticは他の場合に使用される静的ライブラリです。 Release

7

マクロを使用した実際の例を次に示します。

_cmake_minimum_required(VERSION 2.8.12)

macro(ternary var boolean value1 value2)
    set(${var} $<${${boolean}}:${value1}>$<$<NOT:${${boolean}}>:${value2}>)
endmacro()

set(mybool 0)
ternary(myvar mybool hello world)

add_custom_target(print
    ${CMAKE_COMMAND} -E echo ${myvar}
    )
_

_CMakeLists.txt_ファイルを作成し、_cmake . && make print_を実行します(ジェネレーター式はビルド時にのみ評価されます)。

myboolの値を_0_または_1_に変更して、何が起こるかを確認してください。

次の定義も機能し、より明確になります。

_cmake_minimum_required(VERSION 2.8.12)

macro(ternary var boolean value1 value2)
    if(${boolean})
        set(${var} ${value1})
    else()
        set(${var} ${value2})
    endif()
endmacro()

set(mybool 0)
ternary(myvar mybool hello world)

add_custom_target(print
    ${CMAKE_COMMAND} -E echo ${myvar}
    )
_

TL; DR

ternary(var boolean value1 value2)

つまり、C/C++と比較して:

_int var = boolean ? value1 : value2;_

6
thiagowfx

それをより明確にしましょう:

add_custom_command(TARGET myProject PRE_BUILD
    COMMAND cd \"D:/projects/$<IF:$<CONFIG:Debug>,Debug,Release>\"
    COMMAND call prebuild.bat)

次に、生成されたVisual Studioプロジェクトで、プロジェクト「myProject」のプロパティウィンドウに移動します。

ビルド構成が「デバッグ」の場合、評価プロセスは次のとおりです。

  1. $<IF:$<CONFIG:Debug>,Debug,Release>
  2. $<IF:1,Debug,Release>
  3. Debug

ビルド構成が「リリース」の場合、評価プロセスは次のとおりです。

  1. $<IF:$<CONFIG:Debug>,Debug,Release>
  2. $<IF:0,Debug,Release>
  3. Release

0
zwcloud