junction - Integrate subprojects
This element acts as a window into another BuildStream project. It allows integration of multiple projects into a single pipeline.
# Specify the BuildStream project source
- kind: git
# Specify the junction configuration
# Override project options
# Optionally look in a subpath of the source repository for the project
# Optionally override elements in subprojects, including junctions.
With a junction element in place, local elements can depend on elements in
the other BuildStream project using element paths.
For example, if you have a
toolchain.bst junction element referring to
a project which contains a
gcc.bst element, you can express a build
dependency to the compiler like this:
- junction: toolchain.bst:gcc.bst
Junction elements are only connectors which bring multiple projects together, and as such they are not in the element dependency graph. This means that it is illegal to depend on a junction, and it is also illegal for a junction to have dependencies.
While junctions are elements, a limited set of element operations are supported. Junction elements can be tracked and fetched like other elements but they do not produce any artifacts, which means that they cannot be built or staged.
Note that when running bst source track
on your project, elements found in subprojects are not tracked by default.
You may specify
--cross-junctions to the
bst source track command to explicitly track
elements across junction boundaries.
The sources of a junction element define how to obtain the BuildStream project that the junction connects to.
Most commands, such as bst build, will automatically try to fetch the junction elements required to access any subproject elements which are specified as dependencies of the targets provided.
bst source fetch junction.bst
Junction elements can configure the project options
in the subproject, using the
# Specify the options for this subproject
Options are never implicitly propagated across junctions, however variables can be used to explicitly assign configuration in a subproject which matches the toplevel project’s configuration.
It is possible to override elements in subprojects. This can be useful if for example, you need to work with a custom variant or fork of some software in the subproject. This is a better strategy than overlapping and overwriting shared libraries built by the subproject later on, as we can ensure that reverse dependencies in the subproject are built against the overridden element.
Overridding elements allows you to build on top of an existing project and benefit from updates and releases for the vast majority of the upstream project, even when there are some parts of the upstream project which need to be customized for your own applications.
Even junction elements in subprojects can be overridden, this is sometimes important in order to reconcile conflicts when multiple projects depend on the same subproject, as discussed below.
# Override elements in a junctioned project
It is also possible to override elements in deeply nested subprojects, using project relative junction paths:
# Override deeply nested elements
Overriding an element causes your project to completely define the element being overridden, which means you will no longer receive updates or security patches to the element in question when updating to newer versions and releases of the upstream project.
As such, overriding elements is only recommended in cases where the element is very significantly redefined.
Such cases include cases when you need a newer version of the element than the one maintained by the upstream project you are using as a subproject, or when you have significanly modified the code in your own custom ways.
If you only need to introduce a security patch, then it is recommended that
you create your own downstream branch of the upstream project, not only will
this allow you to more easily consume updates with VCS tools like
but it will also be more convenient for submitting your security patches
to the upstream project so that you can drop them in a future update.
Similarly, if you only need to enable/disable a specific feature of a module, it is also preferrable to use a downstream branch of the upstream project. In such a case, it is also worth trying to convince the upstream project to support a project option for your specific element configuration, if it would be of use to other users too.
Junctions can be nested. That is, subprojects are allowed to have junctions on their own. Nested junctions in different subprojects may point to the same project, however, in most use cases the same project should be loaded only once.
As the junctions may differ in source version and options, BuildStream cannot simply use one junction and ignore the others. Due to this, BuildStream requires the user to resolve conflicting nested junctions, and will provide an error message whenever a conflict is detected.
Overriding subproject junctions
If your project and a subproject share a subproject in common, then one way to resolve the conflict is to override the subproject’s junction with a local in your project.
You can override junctions in a subproject in the junction declaration of that subproject, e.g.:
# Here we are junctioning "subproject" which
# also junctions "subsubproject", which we also
# use directly.
- kind: git
# Override `subsubproject.bst` in the subproject using
# the locally declared `local-subsubproject.bst` junction.
When declaring the
overrides dictionary, the keys (on the left side)
refer to junction paths which are relative
to the subproject you are declaring. The values (on the right side) refer
to junction paths which are relative to the
project in which your junction is declared.
This approach modifies your subproject, causing its output artifacts to differ from that project’s expectations.
If you rely on validation and guarantees provided by the organization which maintains the subproject, then it is desirable to avoid overriding any details from that upstream project.
Multiple project instances
By default, loading the same project more than once will result in a conflicting junction error. There are some use cases which demand that you load the same project more than once in the same build pipeline.
In order to allow the loading of multiple instances of the same project in the same build pipeline, please refer to the relevant project.conf documentation.