1. Junction elements

BuildStream’s junction elements are the mechanism which allow projects to interact and depend on eachother.

Junction elements represent the BuildStream project you are depending, and behave much like other elements in the sense that they can be fetched and tracked like other elements, except that regular elements cannot depend on junctions directly, nor can junctions be built. Instead, junctions act like a window into another project you depend on, and allow elements of your project to depend on elements exposed by the project referenced by the junction.

Projects which are junctioned by your project are referred to as subprojects.

1.1. A simple example

Note

This example is distributed with BuildStream in the doc/examples/junctions subdirectory.

Below is a simple example of bst file for the junction element, which we have called hello-junction.bst in this project:

kind: junction
sources:
- kind: local
  path: autotools

This element imports the autotools example subproject distributed with BuildStream in the doc/examples/junctions/autotools subdirectory.

Note

For the sake of this example we are using a local source in a subdirectory of the example project.

Since junctions allow interoperability of projects, it would be more common to use a junction to a remote project under separate revision control, possibly using a kind: git source.

The below bst file describes the element callHello.bst, which depends on the hello.bst element from the autotools example:

kind: import

sources:
- kind: local
  path: files/callHello.sh

depends:
  - filename: hello.bst
    junction: hello-junction.bst

Note how this element refers to the previously declared hello-junction.bst junction in its dependency dictionary. This dependency expresses that we are depending on the hello.bst element in the project which hello-junction.bst refers to.

The callHello.bst element simply imports a callHello.sh shell script which calls the hello command provided by hello.bst:

#!/bin/sh
echo "Calling hello:"
hello

1.2. Building and running

Building the callHello.bst element which requires an external project is just a matter of invoking bst build in the regular way:

user@host:~/junctions$ bst build callHello.bst

[--:--:--][        ][    main:core activity                 ] START   Build
[--:--:--][        ][    main:core activity                 ] START   Loading elements

BuildStream Version 1.93.1+172.g03ccfcd3b
  Session Start: Friday, 17-04-2020 at 20:52:55
  Project:       junctions (/home/user/junctions)
  Targets:       

User Configuration
  Configuration File:      /home/user/.config/buildstream.conf
  Cache Directory:         /home/user/.cache/buildstream
  Log Files:               /home/user/.cache/buildstream/logs
  Source Mirrors:          /home/user/.cache/buildstream/sources
  Build Area:              /home/user/.cache/buildstream/build
  Strict Build Plan:       Yes
  Maximum Fetch Tasks:     10
  Maximum Build Tasks:     4
  Maximum Push Tasks:      4
  Maximum Network Retries: 2

Pipeline

===============================================================================
[00:00:00][        ][    main:core activity                 ] SUCCESS Loading elements
[--:--:--][        ][    main:core activity                 ] START   Resolving elements
[00:00:00][        ][    main:core activity                 ] SUCCESS Resolving elements
[--:--:--][        ][    main:core activity                 ] START   Resolving cached state
[00:00:00][        ][    main:core activity                 ] SUCCESS Resolving cached state
[--:--:--][        ][    main:core activity                 ] START   Checking sources
[00:00:00][        ][    main:core activity                 ] SUCCESS Checking sources

BuildStream Version 1.93.1+172.g03ccfcd3b
  Session Start: Friday, 17-04-2020 at 20:52:55
  Project:       junctions (/home/user/junctions)
  Targets:       callHello.bst

User Configuration
  Configuration File:      /home/user/.config/buildstream.conf
  Cache Directory:         /home/user/.cache/buildstream
  Log Files:               /home/user/.cache/buildstream/logs
  Source Mirrors:          /home/user/.cache/buildstream/sources
  Build Area:              /home/user/.cache/buildstream/build
  Strict Build Plan:       Yes
  Maximum Fetch Tasks:     10
  Maximum Build Tasks:     4
  Maximum Push Tasks:      4
  Maximum Network Retries: 2

Pipeline
fetch needed 179c6ae937e8e2ece3192ab8dc2a55053134a591c9ccd37507b56d11885fae23 hello-junction.bst:base/alpine.bst 
     waiting 7e7bdf36e3d6947ebf279f651fc492c0d20f919e114fb3af8196ac6d2863a8b7 hello-junction.bst:base.bst 
fetch needed 26721a3b05918bec80836da7b713f8f0227410c6a7fecc82a158e0bebe7baddf hello-junction.bst:hello.bst 
     waiting 18d029559c67773c834fe614312382190e080c08c9c6ce5b786552424ef9e69e callHello.bst 
===============================================================================
[--:--:--][179c6ae9][   fetch:hello-junction.bst:base/alpine.bst] START   autotools/base-alpine/179c6ae9-fetch.32733.log
[--:--:--][26721a3b][   fetch:hello-junction.bst:hello.bst  ] START   autotools/hello/26721a3b-fetch.32734.log
[--:--:--][18d02955][   fetch:callHello.bst                 ] START   junctions/callHello/18d02955-fetch.32735.log
[--:--:--][179c6ae9][   fetch:hello-junction.bst:base/alpine.bst] START   Fetching https://bst-integration-test-images.ams3.cdn.digitaloceanspaces.com/integration-tests-base.v1.x86_64.tar.xz
[--:--:--][26721a3b][   fetch:hello-junction.bst:hello.bst  ] START   Fetching https://ftpmirror.gnu.org/gnu/automake/automake-1.16.tar.gz
[00:00:00][18d02955][   fetch:callHello.bst                 ] SUCCESS junctions/callHello/18d02955-fetch.32735.log
[00:00:02][179c6ae9][   fetch:hello-junction.bst:base/alpine.bst] SUCCESS Fetching https://bst-integration-test-images.ams3.cdn.digitaloceanspaces.com/integration-tests-base.v1.x86_64.tar.xz
[00:00:03][26721a3b][   fetch:hello-junction.bst:hello.bst  ] SUCCESS Fetching https://ftpmirror.gnu.org/gnu/automake/automake-1.16.tar.gz
[00:00:03][26721a3b][   fetch:hello-junction.bst:hello.bst  ] SUCCESS autotools/hello/26721a3b-fetch.32734.log
[00:00:10][179c6ae9][   fetch:hello-junction.bst:base/alpine.bst] SUCCESS autotools/base-alpine/179c6ae9-fetch.32733.log
[--:--:--][179c6ae9][   build:hello-junction.bst:base/alpine.bst] START   autotools/base-alpine/179c6ae9-build.32750.log
[--:--:--][179c6ae9][   build:hello-junction.bst:base/alpine.bst] START   Staging sources
[00:00:00][179c6ae9][   build:hello-junction.bst:base/alpine.bst] SUCCESS Staging sources
[--:--:--][179c6ae9][   build:hello-junction.bst:base/alpine.bst] START   Caching artifact
[00:00:00][179c6ae9][   build:hello-junction.bst:base/alpine.bst] SUCCESS Caching artifact
[00:00:00][179c6ae9][   build:hello-junction.bst:base/alpine.bst] SUCCESS autotools/base-alpine/179c6ae9-build.32750.log
[--:--:--][7e7bdf36][   build:hello-junction.bst:base.bst   ] START   autotools/base/7e7bdf36-build.32755.log
[--:--:--][7e7bdf36][   build:hello-junction.bst:base.bst   ] START   Caching artifact
[00:00:00][7e7bdf36][   build:hello-junction.bst:base.bst   ] SUCCESS Caching artifact
[00:00:00][7e7bdf36][   build:hello-junction.bst:base.bst   ] SUCCESS autotools/base/7e7bdf36-build.32755.log
[--:--:--][26721a3b][   build:hello-junction.bst:hello.bst  ] START   autotools/hello/26721a3b-build.32759.log
[--:--:--][26721a3b][   build:hello-junction.bst:hello.bst  ] START   Staging dependencies
[00:00:00][26721a3b][   build:hello-junction.bst:hello.bst  ] SUCCESS Staging dependencies
[--:--:--][26721a3b][   build:hello-junction.bst:hello.bst  ] START   Integrating sandbox
[00:00:00][26721a3b][   build:hello-junction.bst:hello.bst  ] SUCCESS Integrating sandbox
[--:--:--][26721a3b][   build:hello-junction.bst:hello.bst  ] START   Staging sources
[00:00:00][26721a3b][   build:hello-junction.bst:hello.bst  ] SUCCESS Staging sources
[--:--:--][26721a3b][   build:hello-junction.bst:hello.bst  ] START   Running configure-commands
[--:--:--][26721a3b][   build:hello-junction.bst:hello.bst  ] STATUS  Running command

    export NOCONFIGURE=1;
    
    if [ -x ./configure ]; then true;
    elif [ -x ./autogen ]; then ./autogen;
    elif [ -x ./autogen.sh ]; then ./autogen.sh;
    elif [ -x ./bootstrap ]; then ./bootstrap;
    elif [ -x ./bootstrap.sh ]; then ./bootstrap.sh;
    else autoreconf -ivf .;
    fi

[--:--:--][26721a3b][   build:hello-junction.bst:hello.bst  ] STATUS  Running command

    ./configure --prefix=/usr \
    --exec-prefix=/usr \
    --bindir=/usr/bin \
    --sbindir=/usr/sbin \
    --sysconfdir=/etc \
    --datadir=/usr/share \
    --includedir=/usr/include \
    --libdir=/usr/lib \
    --libexecdir=/usr/libexec \
    --localstatedir=/var \
    --sharedstatedir=/usr/com \
    --mandir=/usr/share/man \
    --infodir=/usr/share/info   

[00:00:03][26721a3b][   build:hello-junction.bst:hello.bst  ] SUCCESS Running configure-commands
[--:--:--][26721a3b][   build:hello-junction.bst:hello.bst  ] START   Running build-commands
[--:--:--][26721a3b][   build:hello-junction.bst:hello.bst  ] STATUS  Running command

    make

[00:00:00][26721a3b][   build:hello-junction.bst:hello.bst  ] SUCCESS Running build-commands
[--:--:--][26721a3b][   build:hello-junction.bst:hello.bst  ] START   Running install-commands
[--:--:--][26721a3b][   build:hello-junction.bst:hello.bst  ] STATUS  Running command

    make -j1 DESTDIR="/buildstream-install" install

[--:--:--][26721a3b][   build:hello-junction.bst:hello.bst  ] STATUS  Running command

    if false || false; then
      find "/buildstream-install" -name "*.la" -print0 | while read -d '' -r file; do
        if grep '^shouldnotlink=yes$' "${file}" &>/dev/null; then
          if false; then
            echo "Removing ${file}."
            rm "${file}"
          else
            echo "Not removing ${file}."
          fi
        else
          if false; then
            echo "Removing ${file}."
            rm "${file}"
          else
            echo "Not removing ${file}."
          fi
        fi
      done
    fi

[00:00:00][26721a3b][   build:hello-junction.bst:hello.bst  ] SUCCESS Running install-commands
[--:--:--][26721a3b][   build:hello-junction.bst:hello.bst  ] START   Running strip-commands
[00:00:00][26721a3b][   build:hello-junction.bst:hello.bst  ] SUCCESS Running strip-commands
[--:--:--][26721a3b][   build:hello-junction.bst:hello.bst  ] START   Caching artifact
[00:00:00][26721a3b][   build:hello-junction.bst:hello.bst  ] SUCCESS Caching artifact
[00:00:04][26721a3b][   build:hello-junction.bst:hello.bst  ] SUCCESS autotools/hello/26721a3b-build.32759.log
[--:--:--][18d02955][   build:callHello.bst                 ] START   junctions/callHello/18d02955-build.1391.log
[--:--:--][18d02955][   build:callHello.bst                 ] START   Staging sources
[00:00:00][18d02955][   build:callHello.bst                 ] SUCCESS Staging sources
[--:--:--][18d02955][   build:callHello.bst                 ] START   Caching artifact
[00:00:00][18d02955][   build:callHello.bst                 ] SUCCESS Caching artifact
[00:00:00][18d02955][   build:callHello.bst                 ] SUCCESS junctions/callHello/18d02955-build.1391.log
[00:00:15][        ][    main:core activity                 ] SUCCESS Build

Pipeline Summary
  Total:       4
  Session:     4
  Fetch Queue: processed 3, skipped 1, failed 0 
  Build Queue: processed 4, skipped 0, failed 0

You can see that the hello.bst element and its dependencies from the autotools project have been built as a part of the pipeline for callHello.bst.

We can now invoke bst shell and run our callHello.sh script, which in turn also calls the hello program installed by the subproject’s hello.bst element.

user@host:~/junctions$ bst shell callHello.bst -- /bin/sh callHello.sh

[--:--:--][        ][    main:core activity                 ] START   Loading elements
[00:00:00][        ][    main:core activity                 ] SUCCESS Loading elements
[--:--:--][        ][    main:core activity                 ] START   Resolving elements
[00:00:00][        ][    main:core activity                 ] SUCCESS Resolving elements
[--:--:--][        ][    main:core activity                 ] START   Resolving cached state
[00:00:00][        ][    main:core activity                 ] SUCCESS Resolving cached state
[--:--:--][        ][    main:callHello.bst                 ] START   Staging dependencies
[00:00:00][        ][    main:callHello.bst                 ] SUCCESS Staging dependencies
[--:--:--][        ][    main:callHello.bst                 ] START   Integrating sandbox
[00:00:00][        ][    main:callHello.bst                 ] SUCCESS Integrating sandbox
[--:--:--][        ][    main:callHello.bst                 ] STATUS  Running command

    /bin/sh callHello.sh

Calling hello:
Hello World!
This is amhello 1.0.

1.3. Further reading

For an example of junction elements being used in a real project, take a look at the freedesktop-sdk junction in the gnome-build-meta project.