The activeIf
definition
Work in progress.
Purpose
Provide additional control over the active state of an xCDL object.
Syntax
{
"cdlOptions": {
"<name>": {
...
"activeIf": [ "<expression>",... ],
...
}
}
}
The value of the activeIf
property is an array of strings that contain boolean expressions, typically used to verify hardware properties. If all these expressions evaluate to true, the object is considered active.
Default value
If missing, no additional constraints are considered, the object is active.
Description
Configuration options or other objects may be either active or inactive. Typically, this is controlled by the object's location in the overall hierarchy. Consider the option utils-lists/trace
, which exists below the component utils-lists
. If the whole component is disabled, then all options it contains are inactive: there is no point in enabling trace for the utils-lists
if the utils-lists
are not used; any requires
constraints associated with trace are irrelevant; any sourceFile
property or other build-related property is ignored.
In some cases, the hierarchy does not provide sufficient control over whether or not a particular object 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 libm
package in the overall hierarchy but should be inactive unless there is appropriate hardware support. In cases like this, an activeIf property is appropriate.
Another common use of activeIf
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 that will contain just one entry may be considered excessive. In such cases, it is possible for B to have an activeIf
dependency on A.
activeIf
defines an array of boolean goal expressions, all of which must be satisfied for the object to be active. For details of goal expression syntax, see the section called Goal Expressions in XCDL packages. In most cases, the goal expressions will be very simple, often involving just one other object, but more complicated expressions can be used when appropriate.
The activeIf
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 B activeIf A or as B requires A. The points to note are:
- If B activeIf A is used and A is disabled or inactive, then configuration (graphical) tools will generally prevent any attempt at modifying B. For example the text for B could be greyed out, and the associated check button (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 enable it.
- If B requires A is used and A is disabled or inactive, configuration (graphical) tools will still allow B to be manipulated and enabled. This would result in a new conflict which may get resolved automatically or may require user intervention.
- If there are hardware dependencies, an
activeIf
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. The same argument applies to coarse-grained dependencies; for example if an option depends on the presence of a TCP/IP stack, then anactiveIf
isEnabled('net')
condition is appropriate. It may be possible to satisfy the condition, but it requires the fairly drastic step of loading another package. Furthermore, if the user wanted a TCP/IP stack in the configuration, it would probably have been loaded already. - If option B exists to provide additional debugging information about the functionality provided by A, then an
activeIf
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
activeIf
andrequires
properties. Suppose there is a conflict because some third option depends on B. If B activeIf 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.
Examples
Do not provide extra semaphore debugging if there are no semaphores:
{
"cdlOptions": {
"binsem": {
...
"parent": "kernel/instrument",
"activeIf": [ "isEnabled('kernel/synch')" ],
"generatedDefinition": "OS_PACKAGE_KERNEL_SYNCH_MUTEX_PRIORITY_INHERITANCE_SIMPLE_RELAY"
...
}
}
}
Avoid another level in the configuration hierarchy:
{
"cdlOptions": {
"relay": {
...
"parent": "kernel/synch/mutex/priorityInheritance/simple",
"activeIf": [ "isEnabled('kernel/synch/mutex/priorityInheritance/simple')" ],
"generatedDefinition": "OS_PACKAGE_KERNEL_SYNCH_MUTEX_PRIORITY_INHERITANCE_SIMPLE_RELAY",
...
}
}
}
Functionality that is only relevant if another package is loaded:
{
"cdlOptions": {
"uitron-compatibility": {
...
"parent": "start",
"activeIf": [ "isLoaded('uitron')" ],
"generatedDefinition": "OS_PACKAGE_START_UITRON_COMPATIBILITY",
...
}
}
}
Check that the hardware or HAL provide the appropriate functionality:
{
"cdlOptions": {
"debug-break-support": {
...
"parent": "hal/debug/gdb/break-support",
"activeIf": [ "isEnabled('hal/debug/gdb/stubs-break')" ],
"generatedDefinition": "OS_DEBUG_HAL_DEBUG_GDB_BREAK_SUPPORT",
...
}
}
}
See also
requires
property
eCos reference
active-if
property