aboutsummaryrefslogtreecommitdiff

build-scripts

The Theory

Building software should be repeatable and straightforward. Engineers building the same code in different ways will yield different results, making the development process less deterministic.

These simple build scripts aim to remove the randomness from development and provide a simple framework that can be used by the developer on the desktop and by and automated build and test system.

ARM should be moving to single binaries built from common source wherever possible, these build scripts take the concept further enabling a single build to create binaries for a number (if not all) of similar platforms in one go. The scripts will also provide a mechanism for building a single platform where they need to be delivered in isolation.

Any change which breaks the ability to build multiple platforms is bad, so will be rejected at code review!

The build is controlled by a platform files and filesystem files, the platform file specifies which components need to be build and provide configuration parameters for each component. Platform files describe a single platform, but there is functionality for having similar flavours of a platform, and building all flavours for a platform at once. Platform and filesystem configuration are decoupled (see the Platforms and Filesystems sections later), but platform files can specify some filesystem specific variables that only take effect if that filesystem is also being built.

The scripts also provide for a build-all that will build all components, but also provide for building individual components in isolation.

The build scripts provide the following functions: - clean - clean out the build objects - build - perform a build - package - package up the built binaries - all - do a clean, build and package in one go! This is only supported by the build-all.sh script.

Structure

There are 3 special files, framework.sh, build-all.sh and parse_params.sh.

framework.sh - This file contains helper environment variable and is responsible for making the calls in the individual build scripts, it also provides error handling so that each build script doesn't need to.

build-all.sh - This scripts is responsible for checking the arguments parsed to the build, loading framework.sh and then executing the individual build scripts.

parse_params.sh - This script handles arguments to the build scripts and is used by the previously mentioned scripts.

There are then a series of individual build scripts for each component, each script contains 3 functions: - do_build() - the build stage - do_clean() - the clean stage - do_package() - the package stage.

Each function must be protected with a component_BUILD_ENABLED variable to enable the platform to control if the build for a component is to be executed by that platform.

Each script must include a description of the variables it uses, but also must include the following lines at the bottom to enable it to work with the build framework:

DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source $DIR/framework.sh $@

build-target-bins.sh is a special script that must be run last, it is responsible for collecting together the build output and putting it in platform specific directories ready for testing or release.

Running The Build

You can either build everything or an individual component, you can call the build script from anywhere withing workspace (i.e. from the root or further in).

#Set some variables used by commands
BUILD_SCRIPT_DIR=$(pwd) # Assuming we're in the build-script directory
PLATFORM=juno
FLAVOUR=juno
FILESYSTEM=busybox
COMMAND=build #Can be build/clean/package
#Command can also be 'all' for build-all.sh only
#If command is omitted, 'build' is assumed

#Run $COMMAND on all components for specified platform/flavour/filesystem
$BUILD_SCRIPT_DIR/build-all.sh \
    -p $PLATFORM \
    -t $FLAVOUR \
    -f $FILESYSTEM \
    $COMMAND

#Run $COMMAND on linux component for specified platform/flavour/filesystem
$BUILD_SCRIPT_DIR/build-linux.sh \
    -p $PLATFORM \
    -t $FLAVOUR \
    -f $FILESYSTEM \
    $COMMAND

Examples

The following examples assume that the present working directory is one folder up from this directory.

If you are unsure what platforms, flavours or filesystems are available in this workspace, then just run ./build-scripts/build-all.sh -h. This will show the available choices.


./build-scripts/build-all.sh -p juno -f all
  • The above builds for the juno platform. All filesystems are also built. No packaging steps are done.

./build-scripts/build-all.sh -p juno -f all package
  • Packages juno binaries into the output directory. This must be run after the build for juno (previous example). For more reliable results, use the following example for a more reliable way of building and packaging in one go.

#Set platform and flavour and filesystem
#For single flavour platforms like Juno, flavour is set to platform.
./build-scripts/build-all.sh -p $platform -f $filesystem -t $flavour all

#For single flavour platform builds "-t" can be omitted.
#For example for juno, packaging for OE:
#./build-scripts/build-all.sh -p juno -f oe all
  • Cleans the source directories, then builds the a particular flavour of the given platforms. Then packages up the output.

./build-scripts/build-all.sh -p all -t all -f all clean
  • Cleans the source directories for all components for all components.

#Set 'platform' to an avaliable platform
./build-scripts/build-all.sh -p $platform all
  • Cleans the source directories, then for each flavour of the given platform, it will build source directories, and then package up the output.

Configs

Config files provide configuration for platforms and flavours of that platform. The structure on the filesystem is shown below.

configs/
├── common
│   └── common.base
└── platform_name
    ├── flavour1_name
    ├── platform_name.base
    └── flavour2_name

There will be a folder named after the platform. This should contain a .base file named after the platform which contains the core configuration for that platform. This should source the common.base file for the default configuration. Then a flavour file should source the .base file for this platform. Further flavours are subsequently a lot easier to define.

If this behaviour is not desired, and only one flavour of the platform is required then the following structure might be desired instead:

configs/
├── common
│   └── common.base
└── my_platform
    └── my_platform

This platform file should still source the common.base file for the defaults, then can override variables as appropriate.

The common.base file has comments on the types of variables than can and should be overridden.

These platform files also declare the compilers and tools required for each build step so that the build scripts can be used by multiple types of build (32 and 64bit for example).

Filesystems

Filesystem files are very similar to the platform files, but they will only be sourced if the particular filesystem is being built from the options passed to the build scripts.

This means that only one platform file needs to be maintained for a particular platform, and this can be configured to work for multiple filesystems.

Results of the build

Built binaries will be stored in a folder named output, in the same directory as the build-scripts folder. Under this output folder, a sub-directory will be named after platforms, and then platform flavour name will be one below that.

This is not the case for platforms with only a single flavour, and they will be stored in a subfolder with the name of the platform under the output folder.

Output for the juno flavour of the juno platform will be stored under output/juno/.