joepol
joepol

Reputation: 842

CMake how to check that exactly one option is selected?

Assuming I have 3 defined options in a CMakeLists file, for instance:

option(FIRST_OPT "<text1>" ON)
option(SECOND_OPT "text2>" OFF)
option(THIRD_OPT "<text3>" OFF)

Exactly one option (of the three) should be selected. Is there an elegant way/ Macro to verify it?

Currently I just check for all valid conditions (which, for 3 options still looks reasonable but for larger groups is not practical):

(FIRST_OPT AND SECOND_OPT) OR 
(FIRST_OPT AND THIRD_OPT) OR 
(SECOND_OPT AND THIRD_OPT) OR 
(NOT (FIRST_OPT AND SECOND_OPT AND THIRD_OPT))

Upvotes: 1

Views: 1637

Answers (2)

joepol
joepol

Reputation: 842

Based on nayab comment:

option(FIRST_OPT "<text1>" ON)
option(SECOND_OPT "<text2>" OFF)
option(THIRD_OPT "<text3>" OFF)

set(COUNTER 0)
set(ALL_OPTIONS FIRST_OPT;SECOND_OPT;THIRD_OPT)
foreach(option IN LISTS ALL_OPTIONS)
    if(${option})
        math(EXPR COUNTER "${COUNTER+1}")
    endif()
endforeach()

if(NOT ${COUNTER})
    message("No option was chosen")
elseif(${COUNTER} GREATER 1)
    message("More than one option was chosen")
endif()

Upvotes: 0

Tsyvarev
Tsyvarev

Reputation: 65928

Instead of mutually-exclusive set of options use a single parameter with a string value:

set(OPT "FIRST" CACHE STRING "Provider choosen")

This parameter is visible to the user in the same extent, as one created by option command.

Because the parameter can have only a single value, you needn't to check whether at most one of your options is enabled.

By assigning STRINGS property of the parameter, you may tell a user which parameter's values can be used, and even provide drop-down list of them in the GUI:

set_property(CACHE OPT PROPERTY STRINGS "FIRST" "SECOND" "THIRD")

CMake itself doesn't check correctness of the parameter's value, but you may easily check it by yourself:

# Extract "STRINGS" property of the parameter
get_property(OPT_STRINGS CACHE OPT PROPERTY STRINGS)
# Check that value of the parameter is inside "STRINGS" list.
if (NOT OPT IN_LIST OPT_STRINGS)
  message(FATAL_ERROR "Wrong value of the parameter 'OPT'")
endif

Upvotes: 4

Related Questions