A sandbox represents a developer's private build area. To avoid the need to compile an entire project, only the small pieces currently being modified by the developer are normally copied to the user's sandbox. The remainder of the build environment comes from one (or more) backing trees to which the user has read-only access. The backing tree will hold an image of the source and compiled objects and libraries for the target architecture.
The use of backing trees requires some support from the underlying build system and appropriate construction of Makefiles (or their equivalent). Systems with the needed functionality include GNU Make, CMake and Scons. The fundamental idea is to separate the output directory for objects from the directory holding the source code and exploit a mechanism like GNU Make's VPATH to search multiple directories for a required dependency.
Note: while it is typical for a sandbox to be backed by a single backing tree, this implementation permits multiple backing trees to be chained.
At a given moment in time, a sandbox is typically associated with a single target architecture. It can be rebased to a different target architecture using the resb command and the sb_retarget command will automatically be run on the next workon invocation to regenerate any architecture-specific configuration files.
A developer may use multiple sandboxes to keep progress on independent work units separated; common practice is to pursue work on only one feature or defect in a given sandbox. Sandboxes can be rebased against historical backing trees to compile a new version of previously deployed executables and libraries compatible with the data structures as they were defined for those releases. This is most useful when releasing object-code-only distributions and one needs to apply bug fixes against releases previously shipped to customers, which may have incompatible data structure layouts and function names, etc.
A user's sandbox descriptions are stored in a sandbox rc file,
typically $HOME/.sandboxrc
. It can be
overridden by the -rc fileName
argument
on most commands.
/opt/backingTrees
.
$HOME/sandboxes
.
$HOME/.sandboxrc
.A backing tree directory structure can be prepared using the mkbt command. Depending on the administrative environment, this command might normally only be used by an adminstrator preparing shared resources, but it can be used by a single developer by specifying a backing tree root under their respective home directory.
usage: mkbt [-btroot btRoot] -bt backingTree [...]
-btroot = specify alternate backing tree root, default is "/opt/backingTrees"
A user can create a new sandbox tree using the mksb command. A sandbox root starting with the user's HOME directory will be alter to replace that prefix with “~”. This permits the sandbox configuration to be used on alternate hosts that might mount in a different location the network file system holding the user's home directory.
usage: resb [ i] [ rc rcFile] [ btroot btRoot=/opt/backingTrees] [ sbroot sbRoot=/home/geoff/sandboxes] [ desc description] [ ta targetArch] sb sandboxName bt backingTree [...]
-i = interactive mode
-rc = specify alternate rc file, default is "$HOME/.sandboxrc"
-btroot = specify alternate backing tree root, default is "/opt/backingTrees"
-sbroot = specify alternate sandbox root, default is "$HOME/sandboxes"
-desc = descriptive note for sandbox to help identify its purpose
-ta = desired target architecture
-force = allow mksb to tolerate existing sandbox directory
The resb command can be used to rebase an existing sandbox. Normally installed as an alias for mksb. If already in a workon shell, the sb sandbox argument may be omitted and will be inferred to be the current sandbox.
usage: resb [ i] [ rc rcFile] [ btroot btRoot=/opt/backingTrees] [ sbroot sbRoot=/home/geoff/sandboxes] [ sb sandboxName] bt backingTree [...]
-i = interactive mode
-rc = specify alternate rc file, default is "$HOME/.sandboxrc"
-btroot = specify alternate backing tree root, default is "/opt/backingTrees"
-sbroot = specify alternate sandbox root, default is "$HOME/sandboxes"
-desc = descriptive note for sandbox
-ta = desired target architecture
Some build environments may require configuration files to be updated when a sandbox's target architecture has been changed. The sb_retarget utility is an internal script that will automatically be run by the first workon performed after a resb command that alters the target architecture (using its -ta argument). The current implementation deals with regeneration of Makefiles derived from CMakeLists.txt files; if the build system does not use cmake, the script has no effect.
The rmsb command is used to remove an existing sandbox. Normally installed as an alias for mksb. An existing sandbox's directory structure will be removed and the corresponding entries deleted from the sandbox rc file.
usage: rmsb [ i] [ rc rcFile] sb sandboxName
-i = interactive mode
-rc = specify alternate rc file, default is /home/user/.sandboxrc
A list of available backing trees can be obtained with the lsbt command. The backing tree names are normally separated by colons, but this character can be overridden with the -s option.
usage: lsbt [{ n| f}] [ s separator] [ btroot backingTreeRoot=/opt/backingTrees]
-n = list only backing tree name
-f = list full path name of backing tree (default)
-btroot = backing tree root, default is "/opt/backingTrees"
default output separator: ":"
The sandboxes maintained by a user can be obtained with the lssb command. One sandbox name is displayed per output line.
usage: lssb [ rc rcFile]
-rc = alternate rc file, default is $HOME/.sandboxrc
The sbinfo utility is a convenience program used to display information about the current sandbox.
The workon command is the most frequently used sandbox-related command because one only creates a sandbox once, but will frequently workon on it.
usage: workon sb sandboxName [ ta targetArchitecture] [ bt backingTree] [ ba buildArchitecture] [ rc rcFile] [cmd ....]
-ta = specify target architecture
-rc = override sandbox rc file, default="$HOME/.sandboxrc"
-bt = override backing tree
-ba = specify build architecture (not normally used)
The buildArch command is used to display the available target architectures supported by the build infrastructure.
usage: buildArch [ s separator] [ btroot backingTreeRoot] [ ba | ta | all]
-all = list all available architectures
-ba = list current build architecture
-ta = list current target architecture
The getsbattr command implements a standard interface for retrieving sandbox-related attributes. This interface should be used in preference to directly accessing the sandbox rc file as it permits all of the implementation details to be altered without requiring modifications to applications.
usage: getsbattr [ v] [ null] [ sb sandboxName] [ rc rcFile] attrName ...
-v = prefix results with attribute name
-null = report null string rather than [undefined]
The setsbattr command implements a standard interface for modifying sandbox-related attributes. This interface should be used in preference to directly accessing the sandbox rc file as it permits all of the implementation details to be altered without requiring modifications to applications.
Attribute value pairs can be specified using contiguous elements with an equals-sign separator or as space-separated pairs.
usage: setsbattr [ sb sandboxName] [ rc rcFile] attrName=value ...
The setsbattr command implements a standard interface for modifying sandbox-related attributes. This interface should be used in preference to directly accessing the sandbox rc file as it permits all of the implementation details to be altered without requiring modifications to applications.
usage: delsbattr [ sb sandboxName] [ rc rcFile] attrName ...
The pathedit command is a convenience utility that can append, prepend or remove elements from a list, typically a colon-separate list of directories.
usage: pathedit [{ a| r| p}] [ s separator] initialPath arg [...]
-a = append, -p = prepend, -r = remove
default mode: "a" separator: ":"
The findFile command is a convenience utility that will search a set of colon-separated directory paths for a file. If no file is found, an exit status of 1 is returned; otherwise 0 is returned. The full path name of the found files is displayed, one per line.
usage: [ 1 | all] fileOrDirName path [...]
path can be colon-separated
-1 = report first entry found only
-all = report all entries found (default)
Unless otherwise noted, these environment variables are set by the workon command.
The two key exceptions are the BT_ROOT_DIR and SB_ROOT_DIR variables, which are never set by the commands. They are reserved for by an administrator or user to point the framework at alternate locations.
/opt/backingTrees
. A user or
administrator can set this environment variable to override the
default backing tree root directory on the local system. All
commands that reference this directory take a -btroot
argument which can also be used to achieve the required effect.$HOME/sandboxes
. A user can set this
environment variable to override the user's default sandbox
collection root. All commands that reference this directory take a
-sbroot argument which can also be used to achieve the
required effect.$SB_ROOT_DIR/$SB_NAME
.NOTE: the SB_BUILD_ARCH and SB_TARGET_ARCH environment variables are often identical; however, they will always be different when utilizing support for a cross-compiler (e.g., compiling for Windows targets on an x64 Linux host). The feature can also be exploited to support incompatible compilation options, such as enabling various profiling options or compiling for a different addressing mode (e.g., 32-bit vs. 64-bit). In general, SB_BUILD_ARCH will be used to find utilities used during the build process by the local machine.
Various global configuration files are maintained in the $BT_ROOT_DIR/config directory. These specify the supported architectures, customization scripts for the build and target environment, and shell-specific rc files. When a new backing tree is created, symbolic links of the appropriate files are made from the $BT_ROOT_DIR into the backing tree's $BT/BuildEnv directory. This permits each backing tree to have custom configuration files, but they start out using common images. Consequently, normally any updates to the master versions will have immediate effect in all backing trees except those in which effort was made to create unique copies.
The list of all available target architectures is provided in the ALL_supportedArchitectures.txt file. The subset of locally supported architectures is provided in either `hostname s`_supportedArchitectures.txt or `buildArch`_supportedArchitectures.txt. In some environments, the backing trees will be placed on a network file system and visible to machines with heterogeneous operating system and processor architectures and not all will be capable of compiling for non-native targets. The 3 distinct files thus indicate the extent of all platforms supported by the local development infrastructure, those available on a specific machine and those supported by any of the build machines with a given operating system/processor combination.
The buildEnv_`buildArch`_sh.txt file is used by the workon command to setup any specialization needed in the configuration environment for the build architecture. The targetEnv_`buildArch ta`_sh.txt file is used by the workon command to setup any specialization required by the configuration for the target architecture. Typically, this will involve specifying an alternate C/C++ compiler in the CC and CXX environment variables. For cross-compilation, it will also usually involve specifying an alternate linker and library archive utility.
These files are consumed by the workon command and must be valid for processing by the /bin/sh interpreter.
Users can use the command shell of their choice. A shell_rc.${SHELL} script is passed by the workon command to the spawned subshell prepared with the sandbox environment. The scripts must be written in the respective language for the selected SHELL. Consequently, it is suggested that the complexity of these scripts should be minimized to avoid duplicated effort and generally used only to implement shell-specific functionality, like setting a command prompt. Generally, customizing the appropriate buildEnv_*_sh.txt or targetEnv_*_sh.txt file is the preferred mechanism as only one set of modifications will be required.
The sandbox rc format appears as a collection of lines formatted as demonstrated below:
SB_${sbName}_${attribute}_ value
The ${sbName} portion corresponds to the sandbox's name and the ${attribute} portion is the name of the desired parameter. Note that there is always an underscore after the attribute name. The sandbox rc file is modified by the mksb command (and its variants resb and rmsb). It is a simple text file and can be easily modified by humans, though this will normally not be done. Instead, the mksb utility will be used to create the appropriate records. Other scripts use the getsbattr, setsbattr and delsbattr utilities to modify the sandbox rc file; this level of abstraction permits replacing the mechanism for storing sandbox attributes persistently without requiring modification of the sandbox-related commands.
The file format for the sandbox attributes supports an arbitrary number of parameters and can be extended at any time without affecting previously implemented applications. There are 3 mandatory attributes:
A sandbox rc file is illustrated below:
SB_test1_sbname_ test1
SB_test1_sbroot_ ~/sandboxes/test1
SB_test1_btpath_ /opt/backingTrees/tree1:/opt/backingTrees/tree2
SB_test1_defaultTargetArch_ Linux.x86_64
SB_test1_description_ Sample sandbox
mkbt -bt tree1
mksb -sb test1 -bt tree1 -desc “Sample sandbox”
workon -sb test1
resb -sb test1 -ta Windows.i686