1. Your first project

To get a feel for the basics, we’ll start with the most basic BuildStream project we could think of.

Note

This example is distributed with BuildStream in the doc/examples/first-project subdirectory.

1.1. Creating the project

First, lets create the project itself using the convenience bst init command to create a little project structure:

user@host:~/first-project$ bst init --project-name first-project

Created project.conf at: /home/user/buildstream/doc/examples/first-project/project.conf

This will give you a project.conf which will look like this:

1.1.1. project.conf

# Unique project name
name: first-project

# Required BuildStream version
min-version: 2.3

# Subdirectory where elements are stored
element-path: elements

The project.conf is a central point of configuration for your BuildStream project.

1.2. Add some content

BuildStream processes directory trees as input and output, so let’s just create a hello.world file for the project to have.

user@host:~/first-project$ touch hello.world

1.3. Declare the element

Here we’re going to declare a simple import element which will import the hello.world file we’ve created in the previous step.

Create elements/hello.bst with the following content:

1.3.1. elements/hello.bst

kind: import

# Use a local source to stage our file
sources:
- kind: local
  path: hello.world

# Configure the import element
config:

  # Place the content staged by sources at the
  # root of the output artifact
  target: /

1.3.2. The source

The local source used by the hello.bst element, can be used to access files or directories which are stored in the same repository as your BuildStream project. The hello.bst element uses the local source to stage our local hello.world file.

1.3.3. The element

The import element can be used to simply add content directly to the output artifacts. In this case, it simply takes the hello.world file provided by its source and stages it directly to the artifact output root.

Tip

In this example so far we’ve used two plugins, the local source and the import element.

You can always browse the documentation for all plugins in the plugins section of the manual.

1.4. Build the element

In order to carry out the activities of the import element we’ve declared, we’re going to have to ask BuildStream to build.

This process will collect all of the sources required for the specified hello.bst and get the backing import element to generate an artifact for us.

user@host:~/first-project$ bst build hello.bst

[--:--:--][        ][    main:core activity                 ] START   Build
[--:--:--][        ][    main:core activity                 ] START   Loading elements
[00:00:00][        ][    main:core activity                 ] SUCCESS Loading elements
[--:--:--][        ][    main:core activity                 ] START   Resolving elements
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
I0000 00:00:1723732089.002696    2833 config.cc:230] gRPC experiments enabled: call_status_override_on_cancellation, event_engine_dns, event_engine_listener, http2_stats_fix, monitoring_experiment, pick_first_new, trace_record_callops, work_serializer_clears_time_cache
[00:00:00][        ][    main:core activity                 ] SUCCESS Resolving elements
[--:--:--][        ][    main:core activity                 ] START   Initializing remote caches
[00:00:00][        ][    main:core activity                 ] SUCCESS Initializing remote caches
[--:--:--][        ][    main:core activity                 ] START   Query cache
[00:00:00][        ][    main:core activity                 ] SUCCESS Query cache

BuildStream Version 2.3.0
    Session Start: Thursday, 15-08-2024 at 14:28:09
    Project:       first-project (/home/user/buildstream/doc/examples/first-project)
    Targets:       hello.bst

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

Project: first-project

    Element Plugins
        import: core plugin

    Source Plugins
        local: core plugin

Pipeline
   buildable 8b3d535225335b4842b5d6b98ee6fdffc7340e190f33b79a2043f5c31e43fbde hello.bst 
===============================================================================
[--:--:--][8b3d5352][   fetch:hello.bst                     ] START   first-project/hello/8b3d5352-fetch.20240815-142809.log
[00:00:00][8b3d5352][   fetch:hello.bst                     ] SUCCESS first-project/hello/8b3d5352-fetch.20240815-142809.log
[--:--:--][8b3d5352][   build:hello.bst                     ] START   first-project/hello/8b3d5352-build.20240815-142809.log
[--:--:--][8b3d5352][   build:hello.bst                     ] START   Staging sources
[00:00:00][8b3d5352][   build:hello.bst                     ] SUCCESS Staging sources
[--:--:--][8b3d5352][   build:hello.bst                     ] START   Caching artifact
[00:00:00][8b3d5352][   build:hello.bst                     ] SUCCESS Caching artifact
[00:00:00][8b3d5352][   build:hello.bst                     ] SUCCESS first-project/hello/8b3d5352-build.20240815-142809.log
[00:00:00][        ][    main:core activity                 ] SUCCESS Build

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

Now the artifact is ready.

Using bst show, we can observe that the artifact’s state, which was reported as buildable in the bst build command above, has now changed to cached:

user@host:~/first-project$ bst show hello.bst

[--:--:--][        ][    main:core activity                 ] START   Loading elements
[00:00:00][        ][    main:core activity                 ] SUCCESS Loading elements
[--:--:--][        ][    main:core activity                 ] START   Resolving elements
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
I0000 00:00:1723732089.403581    2864 config.cc:230] gRPC experiments enabled: call_status_override_on_cancellation, event_engine_dns, event_engine_listener, http2_stats_fix, monitoring_experiment, pick_first_new, trace_record_callops, work_serializer_clears_time_cache
[00:00:00][        ][    main:core activity                 ] SUCCESS Resolving elements
[--:--:--][        ][    main:core activity                 ] START   Initializing remote caches
[00:00:00][        ][    main:core activity                 ] SUCCESS Initializing remote caches
[--:--:--][        ][    main:core activity                 ] START   Query cache
[00:00:00][        ][    main:core activity                 ] SUCCESS Query cache
      cached 8b3d535225335b4842b5d6b98ee6fdffc7340e190f33b79a2043f5c31e43fbde hello.bst 

1.5. Observe the output

Now that we’ve finished building, we can checkout the output of the artifact we’ve created using bst artifact checkout

user@host:~/first-project$ bst artifact checkout --directory here hello.bst

[--:--:--][        ][    main:core activity                 ] START   Loading elements
[00:00:00][        ][    main:core activity                 ] SUCCESS Loading elements
[--:--:--][        ][    main:core activity                 ] START   Resolving elements
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
I0000 00:00:1723732089.803402    2893 config.cc:230] gRPC experiments enabled: call_status_override_on_cancellation, event_engine_dns, event_engine_listener, http2_stats_fix, monitoring_experiment, pick_first_new, trace_record_callops, work_serializer_clears_time_cache
[00:00:00][        ][    main:core activity                 ] SUCCESS Resolving elements
[--:--:--][        ][    main:core activity                 ] START   Initializing remote caches
[00:00:00][        ][    main:core activity                 ] SUCCESS Initializing remote caches
[--:--:--][        ][    main:core activity                 ] START   Query cache
[00:00:00][        ][    main:core activity                 ] SUCCESS Query cache
[--:--:--][8b3d5352][    main:hello.bst                     ] START   Staging dependencies
[00:00:00][8b3d5352][    main:hello.bst                     ] SUCCESS Staging dependencies
[--:--:--][8b3d5352][    main:hello.bst                     ] START   Integrating sandbox
[00:00:00][8b3d5352][    main:hello.bst                     ] SUCCESS Integrating sandbox
[--:--:--][8b3d5352][    main:hello.bst                     ] START   Checking out files in 'here'
[00:00:00][8b3d5352][    main:hello.bst                     ] SUCCESS Checking out files in 'here'

And observe that the file we expect is there:

user@host:~/first-project$ ls ./here

hello.world

1.6. Summary

In this section we’ve created our first BuildStream project from scratch, but it doesnt do much.

We’ve observed the general structure of a BuildStream project, and we’ve run our first build.