The open source OpenXR runtime
at main 154 lines 5.6 kB view raw
1# Copyright 2022, Collabora, Ltd. 2# Copyright 2000-2022, Kitware, Inc., Insight Software Consortium 3# 4# SPDX-License-Identifier: BSD-3-Clause 5# 6# CMake was initially developed by Kitware with the following sponsorship: 7# * National Library of Medicine at the National Institutes of Health 8# as part of the Insight Segmentation and Registration Toolkit (ITK). 9# 10# * US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel 11# Visualization Initiative. 12# 13# * National Alliance for Medical Image Computing (NAMIC) is funded by the 14# National Institutes of Health through the NIH Roadmap for Medical Research, 15# Grant U54 EB005149. 16# 17# * Kitware, Inc. 18# 19# (Based on CMakeDependentOption) 20 21#[=======================================================================[.rst: 22OptionWithDeps 23-------------- 24 25Macro to provide an option dependent on other options. 26 27This macro presents an option to the user only if a set of other 28conditions are true. If it is already specified by the user but the 29conditions are not true, it triggers an error. 30 31This is based on cmake_dependent_options but meets common expectations better: 32if you explicitly try to enable something that is not available, you get an error 33instead of having it silently disabled. 34 35.. command:: option_with_deps 36 37 .. code-block:: cmake 38 39 option_with_deps(<option> "<help_text>" [DEFAULT <default>] DEPENDS [<depends>...]) 40 41 Describes a build option that has dependencies. If the option is requested, 42 but the depends are not satisfied, an error is issued. DEPENDS is a list of 43 conditions to check: all must be true to make the option available. 44 Otherwise, a local variable named ``<option>`` is set to ``OFF``. 45 46 When ``<option>`` is available, the given ``<help_text>`` and initial 47 ``<default>`` are used. Otherwise, any value set by the user is preserved for 48 when ``<depends>`` is satisfied in the future. 49 50 Note that the ``<option>`` variable only has a value which satisfies the 51 ``<depends>`` condition within the scope of the caller because it is a local 52 variable. 53 54 Elements of ``<depends>`` cannot contain parentheses nor "AND" (each item is 55 implicitly "ANDed" together). Be sure to quote OR and NOT expressions, and avoid 56 complex expressions (such as with escaped quotes, etc) since they may fail, 57 especially before CMake 3.18. 58 59Example invocation: 60 61.. code-block:: cmake 62 63 option_with_deps(USE_PACKAGE_ABC "Use Abc" DEPENDS "USE_PACKAGE_XYZ" "NOT USE_CONFLICTING_PACKAGE") 64 65If ``USE_PACKAGE_XYZ`` is true and ``USE_CONFLICTING_PACKAGE`` is false, this provides 66an option called ``USE_PACKAGE_ABC`` that defaults to ON. Otherwise, it sets 67``USE_PACKAGE_ABC`` to OFF and hides the option from the user. If the status of 68``USE_PACKAGE_XYZ`` or ``USE_CONFLICTING_PACKAGE`` ever changes, any value for the 69``USE_PACKAGE_ABC`` option is saved so that when the option is re-enabled it retains 70its old value. 71 72#]=======================================================================] 73 74function(option_with_deps option doc) 75 set(options) 76 set(oneValueArgs DEFAULT) 77 set(multiValueArgs DEPENDS) 78 cmake_parse_arguments(_option_deps "${options}" "${oneValueArgs}" 79 "${multiValueArgs}" ${ARGN}) 80 81 if(NOT DEFINED _option_deps_DEFAULT) 82 set(_option_deps_DEFAULT ON) 83 endif() 84 85 # Check for invalid/bad depends args 86 foreach(d ${_option_deps_DEPENDS}) 87 if("${d}" MATCHES "[(]") 88 message( 89 FATAL_ERROR "option_with_deps does not support parens in deps") 90 endif() 91 if("${d}" MATCHES "\\bAND\\b") 92 message( 93 FATAL_ERROR 94 "option_with_deps treats every deps item as being implicitly 'ANDed' together" 95 ) 96 endif() 97 if("${d}" STREQUAL "OR") 98 message(FATAL_ERROR "option_with_deps needs OR expressions quoted") 99 endif() 100 if("${d}" STREQUAL "NOT") 101 message(FATAL_ERROR "option_with_deps needs NOT expressions quoted") 102 endif() 103 endforeach() 104 105 # This is a case we removed from the original CMakeDependentOption module 106 if(NOT (${option}_ISSET MATCHES "^${option}_ISSET$")) 107 message( 108 FATAL_ERROR 109 "Probably too old of CMake version to cope with this module") 110 endif() 111 112 # Check the actual deps, determine if the option is available 113 set(_avail ON) 114 foreach(d ${_option_deps_DEPENDS}) 115 cmake_language( 116 EVAL 117 CODE 118 " 119 if(${d}) 120 else() 121 set(_avail OFF) 122 set(_cond ${d}) 123 endif()") 124 endforeach() 125 126 # Error if option was requested but not available 127 if("${${option}}" AND NOT "${_avail}") 128 message( 129 FATAL_ERROR 130 "${option} specified but not available: failed check ${_cond}") 131 endif() 132 133 # Handle remaining cases 134 set(_already_defined OFF) 135 if(DEFINED ${option}) 136 set(_already_defined ON) 137 endif() 138 if(${_avail}) 139 # Set a cache variable: the value here will not override an already-set value. 140 option(${option} "${doc}" "${_option_deps_DEFAULT}") 141 142 if(NOT _already_defined) 143 # Needed to force this for some reason 144 set(${option} 145 "${${option}}" 146 CACHE BOOL "${doc}" FORCE) 147 endif() 148 else() 149 # Don't set a cache variable for something that's not available 150 set(${option} 151 OFF 152 PARENT_SCOPE) 153 endif() 154endfunction()