23.2. Using Interface Flags

In order to associate a particular variable assignment with a flag, the assignment in an Abuild.interface file must be prefixed with flag flagname, as we have seen above. Before flagname can be associated with an assignment, it must be declared as one of the build item's supported flags. This is achieved by including the flag in the supported-flags keyword in Abuild.conf. For example:

supported-flags: flagname

As we have already seen, the effect of an assignment that is associated with a flag is visible only if the value of the variable is requested when the specified flag is set. The only time this ever happens is when abuild is creating the dynamic output file for a build item. We mentioned above that abuild maintains a list of assignments for each variable and retains a record of any flag that may have been associated with each assignment. Abuild also stores the name of the build item that is responsible for each assignment in a variable's assignment history. When one build item depends on another, it may request the evaluation of any assignments made by the dependency item that were associated with a specific flag. This is done by including the -flag=flagname option when declaring the dependency in the Abuild.conf file. For example, if build item A wanted to see all assignments that B made associated with the private flag, then A's Abuild.conf would contain the following line:

deps: B -flag=private

When a flag is specified as part of a dependency in this fashion, abuild requires that the dependency list the given flag as one of its supported flags. For example, in this case, it would be an error if B's Abuild.conf did not list private in its supported-flags key.

As mentioned above, the effect of any flag-based assignment is visible only when actually exporting a build item's interface to the dynamic output. When abuild exports a build item's own interface for its own use, it does so with all of the flags supported by that build item in effect. For example, in Figure 23.1, “Private Interface Flag”, B has an include directory and a private-include directory. It wants the include directory to be visible to all build items that depend on it, but the private-include directory should be visible only to other build items that specifically ask for it. B would indicate that it supports the private flag by adding this line to its Abuild.conf:

supported-flags: private

If it wanted the header files in include directory to be visible to all items that depend on it, but it wanted the header files in the private-include directory to be visible only to those build items that specifically requested by depending on it with the private flag, it would include the following lines in its Abuild.interface file:

INCLUDES = include
flag private INCLUDES = private-include

If A wanted to see the private-include directory, it could indicate that it wants the private flag set when it reads B's Abuild.interface. It would do this by including the following in its Abuild.conf:

deps: B -flag=private

Then, when A reads B's Abuild.interface file, it will see the private-include assignment. B will also see it because build items always see all of their own flag-based assignments. If a third build item X depended on A without specifying the private flag, it would not see B's private-include directory as that assignment would not be inherited through A's interface.

Figure 23.1. Private Interface Flag

Private Interface Flag

A and B see private-include, but X does not.

This is a bit tricky to understand. For additional clarification, see the example below, Section 23.3, “Private Interface Example”.

Although we have used a single and generically named private flag for this example, there is nothing special about the name “private”. There's no reason that other special-purpose flags couldn't be introduced to provide fine-grained control over which parts of a build item are to be visible to other build items. In most cases, use of a simple flag like private should suffice. To reduce confusion among developers in a project, it is recommended that a project adopt its own conventions about how interface flags will be used.