Configuration options or other entities may be either active or inactive. Typically this is controlled by the option's location in the overall hierarchy. Consider the option CYGDBG_INFRA_DEBUG_PRECONDITIONS, which exists below the component CYGDBG_USE_ASSERT. If the whole component is disabled then the options it contains are inactive: there is no point in enabling preconditions unless there is generic assertion support; any requires constraints associated with preconditions are irrelevant; any compile property or other build-related property is ignored.
In some cases the hierarchy does not provide sufficient control over whether or not a particular option should be active. For example, the math library could have support for floating point exceptions which is only worthwhile if the hardware implements appropriate functionality, as specified by the architectural HAL. The relevant math library configuration options should remain below the CYGPKG_LIBM package in the overall hierarchy, but should be inactive unless there is appropriate hardware support. In cases like this an active_if property is appropriate.
Another common use of active_if properties is to avoid excessive nesting in the configuration hierarchy. If some option B is only relevant if option A is enabled, it is possible to turn A into a component that contains B. However adding another level to the hierarchy for a component which will contain just one entry may be considered excessive. In such cases it is possible for B to have an active_if dependency on A.
active_if takes a goal expression as argument. For details of goal expression syntax see the Section called Goal Expressions in Chapter 3. In most cases the goal expression will be very simple, often involving just one other option, but more complicated expressions can be used when appropriate. It is also possible to have multiple active_if conditions in a single option, in which case all of the conditions have to be satisfied if the option is to be active.
The active_if and requires properties have certain similarities, but they serve a different purpose. Suppose there are two options A and B, and option B relies on functionality provided by A. This could be expressed as either active_if A or as requires A. The points to note are:
If active_if A is used and A is disabled or inactive, then graphical tools will generally prevent any attempt at modifying B. For example the text for B could be grayed out, and the associated checkbutton (if B is a boolean option) would be disabled. If the user needs the functionality provided by option B then it is necessary to go to option A first and manipulate it appropriately.
If requires A is used and A is disabled or inactive, graphical tools will still allow B to be manipulated and enabled. This would result in a new conflict which may get resolved automatically or which may need user intervention.
If there are hardware dependencies then an active_if condition is usually the preferred approach. There is no point in allowing the user to manipulate a configuration option if the corresponding functionality cannot possibly work on the currently-selected hardware. Much the same argument applies to coarse-grained dependencies, for example if an option depends on the presence of a TCP/IP stack then an active_if CYGPKG_NET condition is appropriate: it may be possible to satisfy the condition, but it requires the fairly drastic step of loading another package; further more, if the user wanted a TCP/IP stack in the configuration then it would probably have been loaded already.
If option B exists to provide additional debugging information about the functionality provided by A then again an active_if constraint is appropriate. There is no point in letting users enable extra debugging facilities for a feature that is not actually present.
The configuration system's inference engine will cope equally well with active_if and requires properties. Suppose there is a conflict because some third option depends on B. If B is active_if A then the inference engine will attempt to make A active and enabled, and then to enable B if necessary. If B requires A then the inference engine will attempt to enable B and resolve the resulting conflict by causing A to be both active and enabled. Although the inference occurs in a different order, in most cases the effect will be the same.
# Do not provide extra semaphore debugging if there are no semaphores cdl_option CYGDBG_KERNEL_INSTRUMENT_BINSEM { active_if CYGPKG_KERNEL_SYNCH … } # Avoid another level in the configuration hierarchy cdl_option CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INHERITANCE_SIMPLE_RELAY { active_if CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INHERITANCE_SIMPLE … } # Functionality that is only relevant if another package is loaded cdl_option CYGSEM_START_UITRON_COMPATIBILITY { active_if CYGPKG_UITRON … } # Check that the hardware or HAL provide the appropriate functionality cdl_option CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT { active_if CYGINT_HAL_DEBUG_GDB_STUBS_BREAK … } |