Chapter 25. Build Item Visibility

Table of Contents

25.1. Increasing a Build Item's Visibility
25.2. Mixed Classification Example

By default, build items are allowed to refer to other build items directly in their Abuild.conf files subject to certain scoping rules as described in Section 6.3, “Build Item Name Scoping”. In some rare instances, in order to resolve a conflict between what a given build item is supposed to be able to see and which items a given item is supposed to be seen by, it is necessary to increase the visibility of a build item. In this chapter, we describe a mechanism for doing this and present a real-world example in which it would be required.

25.1. Increasing a Build Item's Visibility

The Abuild.conf file supports an optional visible-to key has a value consisting of a single scope identifier. It may have one of the following two forms:

  • ancestor-scope.*: the current build item is visible to all build items under the named ancestor-scope. The ancestor-scope must be at or above the “grandparent” of the current build item since build items belong by default to the scope named by the parent build item.

  • *: this build item may be seen by any build item.

For example, if the item A.B.C declared itself as visible to A.*, then the items A.P, A.Q.R, or anything else under A would be allowed to access it directly. Even though it is hidden beneath A.B, access to it would be checked as if it were directly under A. The A.B.C build item would increase its visibility by adding this line to its Abuild.conf:

visible-to: A.*

Here we describe a more concrete example. The next section demonstrates an actual implementation of the pattern described here. Suppose you needed to implement a project that contained build items at different levels of classification, which we'll call public and sensitive. We want the sensitive build items to be able to see the public ones, but the public ones should never be allowed to see the sensitive ones. To achieve this, we create an public build tree and a sensitive build tree, and then we have the sensitive build tree list the public build tree as a tree dependency. The explanation that follows refers to Figure 25.1, “Build Item Visibility”.

Figure 25.1. Build Item Visibility

Build Item Visibility

B.sensitive can see B.W and B.X because of its scope. B.sensitive can be seen by A.sensitive because of its visibility.


Suppose you have software components A and B and that A depends on B. Let's say that B has two public subcomponents called B.Q and B.R and that B's Abuild.conf declares those as dependencies, making it a facade build item for its subcomponents. When A depends on B, it will automatically get B.Q's and B.R's interfaces through B's dependency on them. Now suppose that both A and B have some additional subcomponents that are sensitive. In order to avoid having the public items even know that the sensitive items exist and to prevent them from ever accidentally depending on them even when they are being modified in a sensitive environment, we add sensitive subcomponents to A and B in a completely separate build tree. Suppose B has sensitive subcomponents B.W and B.X. Those need to be under the scope B so that they can see B.Q and B.R. Now we can create a facade build item called B.sensitive that depends on B and also on B.W and B.X. Then anyone who depends on B.sensitive can see all four subcomponents of B. Suppose we have a sensitive version of A called A.sensitive. Unfortunately, by our normal scoping rules, A.sensitive would not be allowed to depend on B.sensitive because B.sensitive would be hidden beneath B. We can't move B.sensitive out of B (by calling it something like B_sensitive, for example) since then it would not be able to depend on B.W and B.X. Instead, we have to have B.sensitive make itself globally visible by adding visible-to: * to its Abuild.conf. Now any build item that can resolve its name, which by design means only build items in the sensitive build tree, can declare a dependency directly on B.sensitive. That way, the public A build item depends on the public B build item, and the sensitive A.sensitive build item depends on the sensitive B.sensitive build item, and all constraints are satisfied. This pattern can be useful whenever separate build trees are used to add new private subcomponents to something defined in a different build tree. In this case, the use of a separate tree and a tree dependency creates what is effectively a one-way dependency gate: items in the sensitive tree can see items in the public tree, but items in the public tree can't see items in the sensitive tree. The next section demonstrates an actual implementation of this pattern.