cmaketernary-operator

Ternary operator in CMake's generator expressions


Cmake's generator expressions allow me to use logical expressions within certain function calls. For instance, if I want to add the /MTd compiler flag in Debug mode, I can say

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

If CONFIG equals "Debug", this will call add_compile_options with the value "/MTd", otherwise with an empty string.

But usually, I don't want to decide between a value and the empty string, but between two values. In the example above, if CONFIG is not "Debug", I want to pass /MT (without the trailing d). I'd love to have a syntax like this:

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

Note that the above is not valid code according to the CMake specs. The best I have come up with that actually works is this:

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

This seems awfully redundant to me. Is there a shorter, more readable way to decide between two values?

Note: I realize that in this special case, I could write this:

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

But this seems rather hacky to me and only works in those cases where one option is a substring of the other.


Solution

  • Note that cmake 3.8 added exactly what you want to generator expressions ...

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

    Example usage:

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

    Where cppzmq is shared library used in Debug build and cppzmq-static is static library used in other case e.g. Release