Building on a Flatpak SDK

Here we demonstrate how to build and run software using a Flatpak SDK for the base runtime.

Note

This example is distributed with BuildStream in the doc/examples/flatpak-autotools subdirectory.

Project structure

The following is a simple project definition:

project.conf

name: flatpak-autotools

aliases:
  gnomesdk: https://sdk.gnome.org/

element-path: elements

options:
  arch:
    type: arch
    description: The machine architecture
    values:
    - x86_64
    - i386

Here we use an arch option to allow conditional statements in this project to be made depending on machine architecture. For this example we only support the i386 and x86_64 architectures.

Note that we’ve added a source alias for the https://sdk.gnome.org/ repository to download the SDK from.

elements/base/sdk.bst

kind: import
description: Import the base freedesktop SDK
sources:
- kind: ostree
  url: gnomesdk:repo/
  gpg-key: keys/gnome-sdk.gpg
  (?):
  - arch == "x86_64":
      track: runtime/org.freedesktop.BaseSdk/x86_64/1.4
      ref: 0d9d255d56b08aeaaffb1c820eef85266eb730cb5667e50681185ccf5cd7c882
  - arch == "i386":
      track: runtime/org.freedesktop.BaseSdk/i386/1.4
      ref: 16036b747c1ec8e7fe291f5b1f667cb942f0267d08fcad962e9b7627d6cf1981
config:
  source: files
  target: usr

This is the import element used to import the actual Flatpak SDK, it uses an ostree source to download the Flatpak since these are hosted in OSTree repositories.

While declaring the ostree source, we specify a GPG public key to verify the OSTree download. This configuration is optional but recommended for OSTree repositories. The key is stored in the project directory at keys/gnome-sdk.gpg, and can be downloaded from https://sdk.gnome.org/keys/.

We also use conditional statements to decide which branch to download.

For the config section of this import element, it’s important to note two things:

  • source: We only want to extract the files/ directory from the SDK,

    This is becase Flatpak runtimes dont start at the root of the OSTree checkout, instead the actual files start in the files// subdirectory

  • target: The content we’ve extracted should be staged at /usr

    This is because Flatpak runtimes only contain the data starting at /usr, and they expect to be staged at /usr at runtime, in an environment with the appropriate symlinks setup from /.

elements/base/usrmerge.bst

kind: import
description: Base usr merge symlinks

# Depend on the base-sdk.bst such that the
# symlinks get added after staging the SDK
depends:
- base/sdk.bst

sources:
- kind: local
  path: files/links

This is another import element, and it uses the local source type so that we can stage files literally stored in the same repository as the project.

The purpose of this element is simply to add the symlinks for /lib -> /usr/lib, /bin -> /usr/bin and /etc -> /usr/etc, we have it depend on the base/sdk.bst element only to ensure that it is staged after, i.e. the symlinks are created after the SDK is staged.

As suggested by the .bst file, the symlinks themselves are a part of the project and they are stored in the files/links directory.

elements/base.bst

kind: stack
description: Base stack

depends:
- base/sdk.bst
- base/usrmerge.bst

This is just a stack element for convenience sake.

Often times you will have a more complex base to build things on, and it is convenient to just use a stack element for your elements to depend on without needing to know about the inner workings of the base system build.

elements/hello.bst

kind: autotools
description: Autotools project

depends:
- base.bst

sources:
- kind: local
  path: files/src

Finally, we show an example of an autotools element to build our sample “Hello World” program.

We use another local source to obtain the sample autotools project, but normally you would probably use a git or other source to obtain source code from another repository.

Using the project

Now that we’ve explained the basic layout of the project, here are just a few things you can try to do with the project.

Note

The following examples assume that you have first changed your working directory to the project root.

Build the hello.bst element

To build the project, run bst build in the following way:

user@host:~/flatpak-autotools$ bst build hello.bst

[--:--:--][][] STATUS  Cache usage recomputed: 12K / infinity (0%)
[--:--:--][][] START   Build
[--:--:--][][] START   Loading elements
[00:00:00][][] SUCCESS Loading elements
[--:--:--][][] START   Resolving elements
[00:00:00][][] SUCCESS Resolving elements
[--:--:--][][] START   Resolving cached state
[00:00:00][][] SUCCESS Resolving cached state
[--:--:--][][] START   Checking sources
[00:00:00][][] SUCCESS Checking sources

BuildStream Version 1.2.7+20.gb7a6624f.dirty
  Session Start: Tuesday, 16-07-2019 at 07:52:01
  Project:       flatpak-autotools (/home/user/flatpak-autotools)
  Targets:       hello.bst
  Cache Usage:   12K / infinity (0%)

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

Project Options
  arch: x86_64

Pipeline
   buildable 255e67b968f3b1906f7fe1053ec7ef7e5bb1c5085148830d6738b84397d0e809 base/sdk.bst 
     waiting e400dde40a45252b5633f4613a9a1df0e6748794f3e5d546da4e989a6921607c base/usrmerge.bst 
     waiting 77a5946acffd506a7e222765ae5e1c78e37ca94f3473ff65049bbcf97c981d00 base.bst 
     waiting 848f838ab66d8b0f428605b4e94a73be519793adc2ccc28a533204e5559a9c83 hello.bst 
===============================================================================
[--:--:--][255e67b9][build:base/sdk.bst                  ] START   flatpak-autotools/base-sdk/255e67b9-build.773.log
[--:--:--][255e67b9][build:base/sdk.bst                  ] START   Staging sources
[00:00:13][255e67b9][build:base/sdk.bst                  ] SUCCESS Staging sources
[--:--:--][255e67b9][build:base/sdk.bst                  ] START   Caching artifact
[00:00:21][255e67b9][build:base/sdk.bst                  ] SUCCESS Caching artifact
[00:00:44][255e67b9][build:base/sdk.bst                  ] SUCCESS flatpak-autotools/base-sdk/255e67b9-build.773.log
[--:--:--][e400dde4][build:base/usrmerge.bst             ] START   flatpak-autotools/base-usrmerge/e400dde4-build.775.log
[--:--:--][e400dde4][build:base/usrmerge.bst             ] START   Staging sources
[00:00:00][e400dde4][build:base/usrmerge.bst             ] SUCCESS Staging sources
[--:--:--][e400dde4][build:base/usrmerge.bst             ] START   Caching artifact
[00:00:00][e400dde4][build:base/usrmerge.bst             ] SUCCESS Caching artifact
[00:00:00][e400dde4][build:base/usrmerge.bst             ] SUCCESS flatpak-autotools/base-usrmerge/e400dde4-build.775.log
[--:--:--][77a5946a][build:base.bst                      ] START   flatpak-autotools/base/77a5946a-build.777.log
[--:--:--][77a5946a][build:base.bst                      ] START   Caching artifact
[00:00:00][77a5946a][build:base.bst                      ] SUCCESS Caching artifact
[00:00:00][77a5946a][build:base.bst                      ] SUCCESS flatpak-autotools/base/77a5946a-build.777.log
[--:--:--][848f838a][build:hello.bst                     ] START   flatpak-autotools/hello/848f838a-build.779.log
[--:--:--][848f838a][build:hello.bst                     ] START   Staging dependencies
[00:00:05][848f838a][build:hello.bst                     ] SUCCESS Staging dependencies
[--:--:--][848f838a][build:hello.bst                     ] START   Integrating sandbox
[00:00:00][848f838a][build:hello.bst                     ] SUCCESS Integrating sandbox
[--:--:--][848f838a][build:hello.bst                     ] START   Staging sources
[00:00:00][848f838a][build:hello.bst                     ] SUCCESS Staging sources
[--:--:--][848f838a][build:hello.bst                     ] START   Running configure-commands
[--:--:--][848f838a][build:hello.bst                     ] STATUS  Running configure-commands

    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

[--:--:--][848f838a][build:hello.bst                     ] STATUS  Running configure-commands

    ./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:05][848f838a][build:hello.bst                     ] SUCCESS Running configure-commands
[--:--:--][848f838a][build:hello.bst                     ] START   Running build-commands
[--:--:--][848f838a][build:hello.bst                     ] STATUS  Running build-commands

    make

[00:00:00][848f838a][build:hello.bst                     ] SUCCESS Running build-commands
[--:--:--][848f838a][build:hello.bst                     ] START   Running install-commands
[--:--:--][848f838a][build:hello.bst                     ] STATUS  Running install-commands

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

[00:00:00][848f838a][build:hello.bst                     ] SUCCESS Running install-commands
[--:--:--][848f838a][build:hello.bst                     ] START   Running strip-commands
[--:--:--][848f838a][build:hello.bst                     ] STATUS  Running strip-commands

    cd "/buildstream-install" && find -type f \
      '(' -perm -111 -o -name '*.so*' \
          -o -name '*.cmxs' -o -name '*.node' ')' \
      -exec sh -ec \
      'read -n4 hdr <"$1" # check for elf header
       if [ "$hdr" != "$(printf \\x7fELF)" ]; then
           exit 0
       fi
       debugfile="/buildstream-install/usr/lib/debug/$1"
       mkdir -p "$(dirname "$debugfile")"
       objcopy --only-keep-debug --compress-debug-sections "$1" "$debugfile"
       chmod 644 "$debugfile"
       strip --remove-section=.comment --remove-section=.note --strip-unneeded "$1"
       objcopy --add-gnu-debuglink "$debugfile" "$1"' - {} ';'

[00:00:00][848f838a][build:hello.bst                     ] SUCCESS Running strip-commands
[--:--:--][848f838a][build:hello.bst                     ] START   Caching artifact
[00:00:00][848f838a][build:hello.bst                     ] SUCCESS Caching artifact
[00:00:11][848f838a][build:hello.bst                     ] SUCCESS flatpak-autotools/hello/848f838a-build.779.log
[00:00:56][][] SUCCESS Build

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

Run the hello world program

The hello world program has been built into the standard /usr prefix, and will automatically be in the default PATH for running things in a bst shell.

To just run the program, run bst shell in the following way:

user@host:~/flatpak-autotools$ bst shell hello.bst -- hello

[--:--:--][][] START   Loading elements
[00:00:00][][] SUCCESS Loading elements
[--:--:--][][] START   Resolving elements
[00:00:00][][] SUCCESS Resolving elements
[--:--:--][][] START   Resolving cached state
[00:00:00][][] SUCCESS Resolving cached state
[--:--:--][848f838a][ main:hello.bst                     ] START   Staging dependencies
[00:00:03][848f838a][ main:hello.bst                     ] SUCCESS Staging dependencies
[--:--:--][848f838a][ main:hello.bst                     ] START   Integrating sandbox
[00:00:00][848f838a][ main:hello.bst                     ] SUCCESS Integrating sandbox
[--:--:--][848f838a][ main:hello.bst                     ] STATUS  Running command

    hello

Hello World!
This is amhello 1.0.