Sandbox Documentation


Sandbox Concepts

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). Build systems with the needed functionality include GNU Make, CMake and Scons. The two fundamental ideas are to separate the output directories for objects from the directories holding the source code and exploit a mechanism like GNU Make's VPATH to search multiple directories for a required dependency.

This particular implementation has been in use for about a decade-and-a-half and took its initial inspiration from the Open Software Foundation's Open Development Environment (aka, OSF ODE) that was utilized in the IBM product divisions to build projects such as AIX, DB2, etc. For the curious, IBM released a copy of their version of the OSF ODE for public use a few years back: https://github.com/IBM/ode. While the basic ideas in the OSF ODE were sound, the implementation makes heavy use of custom executables, which increases the effort required to deploy on a new operating system/CPU architecture and renders much of the implementation logic as a black box to the user.

This implementation keeps any of the needed logic implemented in shell scripts and provides additional features and functionality to enhance developer productivity. Use of the sandbox tool suite should be a force-multiplier even in the case of a single developer, not a constant drain on programmer productivity. It will, however, serve well even if one does not have to maintain multiple release images and support different operating system and CPU architecture combinations. The best designed systems provide rich functionality and flexibility, some guidance but do not impose a strict policy.

While it is typical for a sandbox to be backed by a single backing tree, this implementation permits multiple backing trees to be chained. This is often used when developers are collaborating on experimental or incompatible changes; an intermediate backing tree is used to share work in progress and override images that would normally have come from a production backing tree. Even if a site only has a single operating system/CPU combination in use, there are incompatible compilation modes that effectively serve as the equivalent of compiling for a different architecture, such as test code coverage or link-time optimization. Some organizations may have a population of supposedly compatible hardware but want to take advantage of the features present in more recent instruction sets. An illustration would be the evolution of the Intel's AVX instruction set, having evolved from not-present, to AVX, AVX2 and then AVX-512.

At a given moment in time, a sandbox is typically associated with a single target architecture. It can be re-based 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. Many build systems do not require this and switching target architectures can be done using the ‑‑ta option of the workon command.

A developer will often use multiple sandboxes to keep progress on independent work units separated; common best practice is to pursue work on only one feature or defect in a given sandbox, though sometimes work units are interrelated. It is almost always a bad idea to tackle an emergency bug fix in a sandbox where work was already underway; these unscheduled but focused work activities should be handled in a distinct sandbox that is removed after the bug fixes are committed. Some organizations have strict policies imposed that every committed change has to be associated with a distinct feature or defect record, and sandboxes serve well to keep such administratively-imposed distinctions separate.

Sandboxes can be re-based against historical backing trees to compile a new version of previously deployed executables and libraries while remaining 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, function names, etc. that differ from the current source code images.

Some of the benefits of sandboxes are reduced by source code control systems that expect every developer to have a complete checkout of the source tree. Normal git usage is a prime offender, but the experimental (as of 2020) sparse‑checkout feature should ameliorate that requirement. There are also a wealth of utilities associated with the sandbox tools suite that are useful inside and outside of sandboxes, such as debug_core.

Target Architecture Naming Conventions

One can devise their own naming conventions, but the default assumption is that a fundamental architecture is named from a combination of the operating system and CPU architecture. The operating system is normally obtained from the output of uname ‑s and the local CPU architecture is usually obtained from uname ‑m. These are combined with a "." separating them to form the fundamental architecture name, such as Linux.x86_64, Linux.s390x and Windows.x86_64. Even though two of them share the same operating system name and two share the same underlying CPU architecture, they are all mutually incompatible.

Sometimes it is desired to compile code is a way other than the default. In these situations, the desired modifications are appended to the target architecture name. In some cases, the alternative compilation mode is compatible with the default. An example of such a common scenario would be the difference between optimized and un-optimized code. The compilation feature is appended to the target architecture name using a "+" separator if it does not result in incompatible code.

Features that result in incompatible object code are appended using an initial "." separator with additional features appended using a ",". Examples incompatible compilation modes can include test coverage, sanity checking, and profiling.

Some example target architecture names:

Linux.x86_64
Fundamental architecture for x86_64 hardware running Linux.
Linux.s390x
Fundamental architecture for zSeries hardware running Linux.
Darwin.x86_64
Fundamental architecture for x86_64 hardware running MacOS.
Linux.86_64.coverage
A Linux on x86_64 target with test coverage selected. Generated objects, libraries and executables are treated as belonging to a distinct target architecture.
Linux.86_64+release
A Linux on x86_64 target with optimization selected. Generated objects, libraries and executables are treated as belonging to the same fundamental Linux.x86_64 target architecture.
Linux.x86_64.coverage+release
A Linux on x86_64 target with both test coverage and optimization selected, but only the test coverage feature is treated as influencing the target architecture.

The name used for a target architecture has a significant effect on the configuration files read by the workon command. The file naming conventions are discussed later.

Sandbox Commands

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. While logically a “database” that maintains a list of sandboxes and their associated attributes, this is realized via a simple text file structure and it can be modified by a text editor if the need arises.

The hierarchy of commands used with backing trees and sandboxes can be visualized as seen below:

Sandbox Tool Chain

A synopsis of the more commonly-used commands is below. Each command is described in detail later.

Commonly-used sandbox commands
Command Description
mkbt Make a backing tree (prepares directory structure).
mksb Make a new sandbox.
resb Rebase an existing sandbox.
rmsb Remove a sandbox (removal of the directory tree is left to the user).
lsbt List available backing tree names or paths.
lssb List available sandboxes.
workon Create subshell and start working in a sandbox.
buildArch List default or available build architectures; used to set compiler target architecture.
getsbattr Get sandbox attributes from sandbox rc file.
setsbattr Set sandbox attributes in sandbox rc file.
delsbattr Delete sandbox attributes from sandbox rc file.
sbinfo Display information about the active workon session.
pathedit Prefix/append/remove elements from a character-separated list .
findFile Find a file within a collection of directories.
findFileInSB Find a file within a collection of sandbox trees.
insb In a sandbox, run a command using automatically located file name arguments.
sbdiff Compare local version of a file against previous.
sbmake Sandbox-aware cover to make utility.
sbrel Display relative components of sandbox-related path.
sbscan Scan files in sandbox and backing trees for text pattern.
sbsvnget Sandbox-aware interface to Subversion that supports sparse checkouts.
sb_retarget Regenerate any target-specific configuration files after a sandbox has been re-based.
sb_commit Equivalent of svn commit that is also git-aware and will do git add, git commit and git push. Useful if one wants a common working style without having to be aware of the repository system associated with the sandbox.
debug_core Launch the debugger against the most recent core file. Supports several debuggers, such as gdb, gdbgui, ddd and lldb. Can use coredumpctl to extract saved core files. Locates executable responsible for generating core file.
last_core Locates most recent core file. Can use coredumpctl to extract saved core files.
filter_errors Isolate error and warning messages from compiler output with the intent of identifying the true location of the error and its context.
sbgcov Run gcov against the named files, automatically setting ‑‑object-directory and ‑‑source-prefix appropriately.
sbInstallFiles Sandbox-aware implementation of install. appropriately.

Common arguments:

Many of the sandbox commands take arguments that with consistent semantics:

Common Arguments
Flag Description
‑‑sb Specifies the sandbox name.
‑‑bt Specifies the name of a backing tree, which can be fully qualified or assumed to name one under the backing tree root.
‑‑ba Specifies target build architecture; defaults to that indicated by buildArch, but can be used to select different sets of compiler options, such as optimized vs. debug with profiling or cross-compilation.
‑‑btroot Specifies a root of backing trees. Can be set by the BT_ROOT_PATH environment variable and defaults to /opt/backingTrees.
‑‑sbroot Specifies the root of the user's sandbox collection. Can be set by the SB_ROOT_DIR environment variable and defaults to $HOME/sandboxes.
‑‑rc Specifies the sandbox rc file. Defaults to $HOME/.sandboxrc.
‑s Usually used to specify a separator character.

mkbt – make backing tree

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 administrator preparing shared resources, but it can be used by a single developer who specifies a backing tree root under their respective home directory. Most sandbox users will not have occasion to use the mkbt command; instead, the most common usage of this utility is from scripts run either manually or automatically be an administrator to setup a build tree, extract current source from a source code repository and perform a compile. The DoNewBTbuild command is an example of a high-level command that performs such tasks.

usage: mkbt [‑‑btroot btRoot] [{‑‑ta targetArchitecture} ...] [‑‑copy] [‑‑reuse] [{‑‑gitclone | ‑‑svnco} repositoryURL] {‑‑bt backingTree} ...
  --bt = backing tree name.
    Can be specified more than once.
  --btroot = specify alternate parent directory for backing tree.
    Default is "/storage/backingTrees".
  --ta = target architecture, default is native (Linux.x86_64).
    "all" means prepare for all supported.
    "avail" means prepare for all locally supported.
    Can be specified more than once.
  --copy = copy templates to BuildEnv directory.
    Default is to use symbolic links to "/opt/sandboxTools/config".
  --reuse = overwrite an existing backing tree.
  --gitclone = clone git repository under src directory.
  --svnco = checkout SVN repository under src directory.

The root of backing tree is normally obtained from BT_ROOT_DIR, which defaults to /opt/backingTrees if not set.

The mkbt command prepares several architecture-specific directories and configuration files. If no target architecture is specified, only configuration related to the local native build architecture is performed. The alias of “avail” can be used to set up the configuration for all locally-supported architectures. The alias of “all” can be used to set up the configuration for all known architectures.

In some environments, there may be no distinction between these three options. However, a not atypical case would be an environment where a cross-compiler exists for Windows on Linux x86 systems and is not present on Sun SPARC hardware running Solaris nor PowerPC hardware running AIX or Linux. Similarly, native compilation by Microsoft Visual Studio might be a known platform, but it would not be performed by the Linux or Solaris hosts. If the backing tree is to be visible to all platforms (requiring it to be exported as a networked file system), then using “‑‑ta all” is arguably the best choice. If hosts have their own copies of backing trees, then “‑‑ta avail” could be preferred.

mksb – make a sandbox

A user can create a new sandbox tree using the mksb command. A sandbox root starting with the user's HOME directory will be altered to replace that prefix with “~”. This permits the sandbox configuration file to be used on alternate hosts that might mount the network file system holding the user's home directory in a different location. This issue frequently arises when one host “owns” the user's home directory and other hosts (perhaps running different operating systems) have different naming conventions.

usage: mksb [‑i] [‑‑rc rcFile] [‑‑btroot btRoot] [‑‑sbroot sbRoot] [‑‑desc description] [‑‑ta targetArch] [‑‑force] [{‑‑bt backingTree} ...] ‑‑sb sandboxName
  -i = interactive mode
  --rc = specify alternate sandbox database 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, defaults to "Linux.x86_64"
  --force = allow mksb to tolerate existing sandbox directory or missing backing tree

resb – re-base a sandbox

The resb command can be used to re-base 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] [‑‑sbroot sbRoot] [‑‑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
  --ta = desired target architecture

sb_retarget – do reconfiguration after an sandbox has been retargeted

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 alters the target architecture (using the ‑‑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.

rmsb – remove a sandbox

The rmsb command is used to remove an existing sandbox. It is normally installed as an alias for mksb. An existing sandbox's corresponding entries will be deleted from the sandbox rc file; however the local sandbox directory structure will not be removed unless the ‑‑force flag is specified. If more than one sandbox name referenced the same sandbox tree, rmsb will refuse to delete the sandbox tree.

usage: rmsb [‑‑force] [‑i] [‑‑rc rcFile] ‑‑sb sandboxName
  --force = remove all files under sandbox tree
  -i = interactive mode
  --rc = specify alternate rc file, default is "$HOME/.sandboxrc"

lsbt – list available backing trees

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} | ‑‑space] {‑‑btroot backingTreeRoot} ...
  -n = list only backing tree name
  -f = list full path name of backing tree (default)
  --btroot = backing tree root, default is "/opt/backingTrees", set by BT_ROOT_PATH
  default output separator: ":"

lssb – list user's sandboxes

The sandboxes maintained by a user can be obtained with the lssb command. One sandbox name is displayed per output line. If verbose mode is selected with the ‑v option, the root directory and description of the sandbox will also be displayed.

usage: lssb [‑v] [‑‑rc rcFile]
  --rc = alternate rc file, default is "$HOME/.sandboxrc"

sbinfo – display information about current sandbox

The sbinfo utility is a convenience program used to display information about the current sandbox. If the ‑p option is passed, the paths to the local sandbox tree and the backing tree chain is also displayed.

usage: sbinfo [‑p]
  -p = show paths

The output looks similar to:

sandbox: sbconv targetArch: Linux.x86_64 buildArch: Linux.x86_64
ST:  /home/{user}/sandboxes/sbconv
BT1: /storage/backingTrees/current

workon – Enter a sandbox work environment

The workon command is the most frequently used sandbox-related command because one only creates a sandbox once, but will frequently workon it. The workon command can be used to run commands in the context of a sandbox, but usually the command argument will not be specified. If a command is not specified, a sub-shell is created with the appropriate environment. The shell to be used will be taken from the SB_SHELL environment variable; if this is not set, the current SHELL will be used.

The SB_USE_SSH_AGENT environment variable can be set to either 1 or 0 (it defaults to 0). If set to 1 or ‑‑ssh is specified, then an ssh‑agent is automatically started if one was not already available and the user's ssh keys are added to it. In contrast, the ‑‑nossh option prevents the launch of an ssh‑agent and loading of the user's ssh keys. In development environments that make use of cross-machine file transfers and have the appropriate public keys distributed amongst the host population, SB_USE_SSH_AGENT will normally be set to 1.

usage: workon ‑‑sb sandboxName [‑‑ta targetArchitecture] [‑‑bt backingTree] [‑‑ba buildArchitecture] [‑‑rc rcFile] [{‑‑ssh | ‑‑nossh}] [‑‑sbroot dir] [‑‑noinit] [[‑c] cmd ....]
  --ta = specify target architecture
  --rc = override sandbox database file, default="$HOME/.sandboxrc"
  --bt = override backing tree
  --ba = specify build architecture (not normally used)
  --ssh = setup ssh keys and start ssh-agent if needed
    Set SB_USE_SSH_AGENT=1 environment variable to enable
  --noinit = do not process BuildEnv/shell_rc.bash file
  --sbroot dir = override sandbox root directory

buildArch – report information about supported architectures

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 | ‑‑avail | ‑‑native | {‑‑base [archName]} | {‑‑subtype [archName]}}]
  --all = list all known architecture configurations
  --avail = list all available architectures on this host
  --native = display native architecture for this host
  --ba = list current build architecture
  --ta = list current target architecture
  --base = display base architecture (filename permitted)
  --subtype = display subtype of architecture (filename permitted)

getsbattr – get sandbox attributes from sandbox rc file

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. The sandbox name is optional if used within a workon session as it defaults to the name of the local sandbox.


usage: getsbattr [‑v] [‑‑null] [‑‑sb sandboxName] [‑‑rc rcFile] attrName ...
  -v = prefix results with attribute name
  --null = report null string rather than [undefined]
 NOTE: exit status will be 1 if any attribute is null

setsbattr – set sandbox attributes in sandbox rc file

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. The sandbox name is optional if used within a workon session as it defaults to the name of the local sandbox.

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 ...

delsbattr – delete sandbox attributes from sandbox rc file

The delsbattr 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. The sandbox name is optional if used within a workon session as it defaults to the name of the local sandbox.

usage: delsbattr [‑‑sb sandboxName] [‑‑rc rcFile] attrName ...

pathedit – Modify a path or list

The pathedit command is a generic convenience utility that can append, prepend or remove elements from a list, typically a colon-separate list of directories.

usage: pathedit [{‑a|‑r|‑p}] [‑‑is inputSeparator] [{‑[‑o]s outputSeparator} | ‑‑space] initialPath arg [...]
  -a = append, -p = prepend, -r = remove, defaults to "-a"
  Note: order of elements in initialPath will not be altered
  --is = specify input separator, defaults to ""
  --os = specify output separator, defaults to input separator
  --space = force output separator to be space
  Hint: reversal of a list can be done via -p "" currentPath

findFile – search a set of directory paths for a file

The findFile command is a generic 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 are displayed, one per line.

The findFile utility is commonly used by utilities outside of the sandbox tool suite and is provided in two forms. There is a findFile.sh script that can be installed but there is also a findFile.cpp variant that can be compiled to yield a native executable. The native executable is preferred for performance purposes. The ‑‑help message will indicate if the native executable is being utilized.

usage: findFile [‑1 | ‑‑all ] [‑s separator] fileOrDirName path [...]
  path can contain contiguous elements, default separator is a colon
  -s separator = define alternate path separator character
  -1 = report first entry found only -2 = report first two, etc.)
  --all = report all entries found (default)
  NOTE:  implemented via native executable

findFileInSB – search a set of sandbox trees for a file

In the context of a sandbox, findFileInSB will search a set of sandbox trees for a file appearing at the corresponding location in the chain of sandbox trees. Any file name paths that are passed as an absolute path name (i.e., beginning with a “/”) or explicitly relative to the current or parent directory are returned as-is; no search will be performed. This utility is commonly used by scripts to locate the Makefile for a sandbox or appropriate configuration files. The ‑‑all option searches all trees whereas ‑‑allbt selects all backing trees but not the local sandbox; ‑‑sb selects the local sandbox tree, ‑bt1 selects for first backing tree, ‑‑bt2 selects the second backing tree, etc.

usage: findFileInSB [‑q] [‑s separator] [‑d additionalDir] {‑‑all | ‑‑allbt | ‑‑sb | ‑‑bt1 | ‑‑bt2 | ... } ... fileName [...]

insb – invoke command using file found in sandbox hierarchy

The insb command is a convenience utility that allows one to invoke a command with file name arguments that are obtained after having located the indicated file using findFileInSB. For example, “insb vi Makefile” will start the vi text editor using the file name of the Makefile corresponding to the current location in the sandbox tree. Arguments and anything that can not be resolved to a file name will be passed as-is. There are two special cases. If a file name begins with the “@” character, the local sandbox will not be searched. If a file name begins with the “%” character, the file name portion will be used as-is. Example usage:

insb vi source.c
insb gvimdiff source.c @source.c
insb lpr -P :printer2 source.h

sbdiff – perform diff against local copy of a sandbox file

The sbdiff command is a sandbox-aware convenience utility that is typically used to display differences between the image of a file in a local sandbox and its original state or current state in a source code repository.

usage: sbdiff [{‑‑svn | ‑‑git}] [{‑r revision | ‑‑local | ‑‑committed }] [‑‑diff] [‑‑nows] [‑‑using prog] {fileName [‑‑against anotherFileName]} ...

By default, the differences between the original state of the file and its current local (‑‑local) state are displayed to highlight the modifications that have been made. An explicit revision can be specified or the most recent committed version can be selected using the ‑‑committed flag.

If differences in white space are not intended to be significant, the ‑‑nows option can be specified.

By default, the gvimdiff program will be used to visually display the contrast between the selected files; however, the ‑‑diff option can be used to select the text-only output from the diff utility and the ‑‑using option can be used to specify an arbitrary comparison program.

The repository type should normally be determined automatically, but can be forced with the ‑‑svn or ‑‑git flags.

sbmake – sandbox-aware interface to make program

The sbmake utility is a cover script for a make-like program that searches the sandbox and backing trees for a corresponding makefile. By default, it will search for sb.Makefile, Makefile and makefile. Note that this order is not identical to that of GNU make, which looks for makefile before Makefile. An arbitrary set of potential file names can be specified using the ‑f option in appropriate combinations.

The desired make command can be provided in the SB_MAKE_COMMAND environment variable or via the ‑m command line option. If not specified, the executable specified by the SB_DEFAULT_MAKE_CMD environment variable (which defaults to make) is located and set as the SB_MAKE_COMMAND environment variable. This allows common settings to be used across machines that have the program installed in different locations, such as /usr/bin and /usr/local/bin.

Note: the absolute path is used to avoid any possibility of sbmake recursively invoking itself, but there is also a nontrivial performance benefit to the use of absolute paths because they avoid any searching of directories to locate the desired executable.

usage: sbmake [‑‑auto] [{‑j jobs|‑l load}] [‑m makeCmd] [‑C dir] [‑f file][...]

Developers who do not want to add sbmake into their repertoire of commands can add an alias for make to sbmake, but this is perhaps best done in $STS/BuildEnv/shell_rc.csh:

setenv SB_MAKE_COMMAND `which make`
alias make sbmake
or $STS/BuildEnv/shell_rc.bash:
SB_MAKE_COMMAND=`which make; export SB_MAKE_COMMAND
alias make sbmake

The sbmake utility works outside of the context of a sandbox, so it is feasible to use it in situations where make would normally have been invoked. For example, as the makeprg in $HOME/.vimrc:

:set makeprg=sbmake\ $*

Several environment variables are honored by sbmake:

Environment variables recognized by sbmake
Variable Description
CLEAR_LD_PATH Defaults to 1. If set to 1, the LD_LIBRARY_PATH environment variable is dropped while spawning child processes. This improves performance, but setting it to 0 may be required if a local build tool is dependent upon the directories in LD_LIBRARY_PATH.
SB_DEFAULT_MAKE_CMD Defaults to make if not set. Normally an unqualified program name that will be resolved into an absolute path if SB_MAKE_COMMAND was not set.
SB_MAKE_COMMAND The make-equivalent command to be used. Should be an absolute path for performance. If not set, SB_DEFAULT_MAKE_CMD is used to locate the desired executable on the local system.
MYVIMRC Intended to be set as a side-effect of invoking sbmake from vim.
SBMAKE_AUTOREGEN If set to 1, a sb.Makefile will be regenerated its original prototype Makefile was modified.

sbrel – report common relative path

The sbrel utilty outputs the subtree path below a sandbox or backing tree. It is most often used on the command line to conveniently switch between directories, but can be used by scripts to determine the context of a directory path. The path to be evaluated is normally taken from the current working directory, but can be provided as a command line argument. The ‑‑showroot argument can be used to output the root of the path rather than the common subtree component. In general, one should expect `pwd` to be equal to `sbrel ‑‑showroot``sbrel`.

usage: sbrel [‑q] [{‑‑showrelative | ‑‑showroot | ‑‑symbolicroot | ‑‑symbolicpath}] [{‑‑shell | ‑‑simpleshell}] [‑‑envvar var] [‑‑suffix extraSuffix] [completeDirPath]
  -q = quiet
  --showrelative = default, show relative path
  --showroot = show just the root path
  --symbolicroot = show the root path using environment variable names
  --symbolicpath = show relative path using environment variable names
  --shell = encapsulate symbolic names with "${" and "}"
  --simpleshell = prefix symbolic names with "$"
  --envvar = add name to list of recognized symbolic environment variables.
    Initially defaults to "HOME"
  --suffix specifies additional subdirectory, defaults to "/src"

Examples:

cd $BT1`sbrel` # change to directory under $BT1
cd $STS`sbrel` # change to sandbox directory
cd $STO`sbrel` # change to object directory

sbscan – search sandbox and backing trees for text pattern in files

The sbscan utility is effectively a sandbox-aware combination of the find and egrep utilities. The default ‑‑top option will search from the root of each selected sandbox and backing tree, whereas the ‑‑rel option restricts the search to only the same relative subtree across the selected sandbox and backing trees. If the default ‑‑partial option is used, only the portion of the path below the root of search trees is output (note that the root will vary depending on whether ‑‑top or ‑‑rel was in effect). In contrast, the ‑‑full option outputs the entire path name of a file. The ‑‑suffix option can be used to specify a file name pattern; it defaults to '*.hc*', which is intended to select C/C++ source and header files.

A set of sandbox and backing tree roots can be specified using ‑‑all or combinations of ‑‑sb, ‑‑allbt, ‑‑bt1, ‑‑bt2, etc. If none are specified, the default behavior is to search only the local sandbox.

usage: sbscan [‑‑top | ‑‑rel] [‑‑full | ‑‑partial] { [‑‑all] | [‑‑allbt] | [‑‑sb] [‑‑bt1] [‑‑bt2] [‑‑bt3] [‑‑bt4] } [‑d dir] ... [‑o file] [[‑‑suffix fileNamePattern] ‑‑suffix2 fileNamePattern] pattern ...
  --top = start search from top of tree
  --rel = start search from relative position within tree
  --full = emit full path names
  --partial = emit partial path below tree root
  --all = search sandbox and all backing trees
  --allbt = search all backing trees
  --sb = search sandbox
  --btN = search backing tree N in chain
  -d dir = add an arbitrary tree to be searched
  -o file = also output result into file
  --suffix = file name search pattern
  --suffix2 = additional file name search pattern
  Default file name pattern is *.[hc] and *.[hc]pp
  Default is to start search from top of tree
  Default is to emit partial path below tree
  Default is to just search local sandbox

Examples:

# display all makefiles that reference CXXFLAGS
sbscan -suffix '*akefile' -all CXXFLAGS

# display all makefiles under the current working directory
# that reference CXXFLAGS
sbscan -suffix '*akefile' -all -rel CXXFLAGS

sbsvnget – Get files from Subversion

The sbsvnget utility is a sandbox-aware interface to Subversion that can make appropriate svn checkout and svn update invocations to retrieve selected source files. Normally, a Subversion checkout will retrieve an entire source tree, which defeats one of the benefits of using sandboxes. If normal svn checkout requests are done on subsets of the source tree, they appear as distinct, unrelated checkouts and commands like svn status, svn diff, svn commit, etc. would have to be invoked against the distinct checkout roots.

In contrast, sbsvnget enables retrieval of just the files of interest, while keeping the directory structure under the sandbox as a single Subversion checkout. The sbsvnget utility is aware of relative position within a sandbox tree and ensures that the directory hierarchy in the sandbox is in parallel with that of the repository.

The host and root path of the repository can be specified via environment variables (SVN_HOST and SVN_PATH), sandbox-specific attributes (sb_svnServer and sb_svnRoot, set by the user via setsbattr) or command-line arguments (‑‑server and ‑‑path).

usage: sbsvnget [‑‑blame] [‑‑server modeAndhostName] [‑‑path pathToRepository] [‑‑force] [‑‑revision revId] dirOrFileName ...

The ‑‑force option can be used to take over an existing directory tree. It is not normally used, but is useful when a sandbox has already had directories and some new files added prior to the first sbsvnget.

Sandbox Environment Variables

Most of the environment variables documented below are set by the workon command, but there are a handful reserved for use by an administrator or user.

Administratively Set Variables

The two key exceptions are the BT_ROOT_DIR and SB_ROOT_DIR variables, which are never set by any of the commands. They are reserved for use by an administrator or user to point the framework at alternate locations. The SB_MAKE_DEFAULT_CMD variable is also not set by any script; if make is not in use, this variable must be set appropriately for correct operation by sbmake.

Administratively Set Environment Variables
Variable Description
BT_ROOT_PATH Specifies the root directory of at least 1 collection of backing trees. Defaults to /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 these directories take a ‑‑btroot argument that can also be used to achieve the required effect.
BT_ROOT_DIR Specifies root of the primary backing tree collection; normally set as the first directory in BT_ROOT_PATH. Most sandbox commands honor the (potentially) multiple directories specified by BT_ROOT_PATH and thus do not reference BT_ROOT_DIR. This variable is normally only used by commands involved in the construction of new backing trees as they need to place the files under the appropriate directory. An example is overlaySBbuilds.
SB_ROOT_DIR Specifies root of user's sandbox collection; defaults to $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, but this is error-prone and intended for use by scripts rather than humans.
SB_MAKE_COMMAND Specifies the full path name of the make (or equivalent) program to be used; if not specified, it defaults to the absolute path determined after resolving the name in SB_DEFAULT_MAKE_CMD.
SB_MAKE_DEFAULT_CMD Defaults to make if not set. If the build system in use does not use make, SB_DEFAULT_MAKE_CMD should be set appropriately to obtain correct operation from sbmake. An absolute path can be used, but normally only the base name of the executable is specified and the local absolute path is automatically resolved to set SB_MAKE_COMMAND.
SB_SHELL Specifies the full path of the command shell to use in a workon session; if not set, defaults to $SHELL.
SB_USE_SSH_AGENT The SB_USE_SSH_AGENT environment variable can be set to either 1 or 0 (it defaults to 0). If set to 1, then an ssh‑agent will be started if necessary and the user's ssh keys will be loaded. In development environments that make use of cross-machine file transfers and have the appropriate public keys distributed amongst the host population, SB_USE_SSH_AGENT will normally be set to 1.
SB_TOOLS_ROOT Specifies the root directory under which the sandbox tool suite was installed. Defaults to /opt/sandboxTools.
SB_TOOLS_BIN_DIR Set to the non-architecture-specific bin holding sandbox utility scripts. Used by debug_core as a fallback to locate the getCompilerVersion utility. Usually set to ${SB_TOOLS_ROOT}/`uname ‑s`/bin.

The following script is normally installed as /etc/profile.d/sandbox_tools.sh by the system administrator so that login shells are automatically populated with appropriate settings. If this is not feasible, an unprivileged user may install the tools under their home directory and set the environment via .bash_profile, .login or other equivalent startup script for their chosen command shell. The values of BT_ROOT_PATH and SB_TOOLS_ROOT are normally tweaked for locally needs and the rest are programmatically determined.

# Path setup for sandbox tools for Bourne/bash shell
# This file is normally installed as /etc/profile.d/sandbox_tools.sh
# NOTE: ensure the settings of BT_ROOT_PATH and SB_TOOLS_ROOT are appropriate
# for the local system.
# The remaining can be altered as an administrator sees fit,
# but the calculated values are normally ideal.

# Local preference for location of backing trees
# ------ EDIT THIS SETTING APPROPRIATELY! ------
BT_ROOT_PATH="${BT_ROOT_PATH:-/storage/backingTrees:/opt/backingTrees}"
export BT_ROOT_PATH


# Point to installation root of sandbox tools suite
# ------ EDIT THIS SETTING APPROPRIATELY! ------
SB_TOOLS_ROOT="${SB_TOOLS_ROOT:-/opt/sandboxTools}"
export SB_TOOLS_ROOT

# Obtain native architecture
_osName=`uname -s`
case "${_osName}" in
CYGWIN* | Win*)
        _osName="Windows"
        ;;
esac

SB_NATIVE_ARCH=${_osName}.`uname -m`
export SB_NATIVE_ARCH

_default_SB_NOARCH_BIN_PATH=${SB_TOOLS_ROOT}/${_osName}.noarch/bin
SB_TOOLS_BIN_DIR=${SB_TOOLS_BIN_DIR:-${_default_SB_NOARCH_BIN_PATH}}
export SB_TOOLS_BIN_DIR

_default_SB_NATIVE_BIN_PATH=${SB_TOOLS_ROOT}/${SB_NATIVE_ARCH}/bin
_default_SB_BIN_PATH=${_default_SB_NATIVE_BIN_PATH}:${_default_SB_NOARCH_BIN_PATH}

SB_TOOLS_BIN_PATH="${SB_TOOLS_BIN_PATH:-${_default_SB_BIN_PATH}}"
export SB_TOOLS_BIN_PATH

# Add to regular PATH
# pathCondense might not be available the first time this is installed
# but eventually should be....
if test -x "${_default_SB_NATIVE_BIN_PATH}/pathCondense"
then
        PATH=`${_default_SB_NATIVE_BIN_PATH}/pathCondense "${PATH}" "${SB_TOOLS_BIN_PATH}"`
else
        PATH="${PATH}${PATH:+:}${SB_TOOLS_BIN_PATH}"
fi
export PATH

# Define primary backing tree root by taking first directory in path
BT_ROOT_DIR=`pathedit --space "${BT_ROOT_PATH}" | awk '{ print $1; }'`
export BT_ROOT_DIR

Automatically set variables

The following variables are automatically set by workon.

Automatically Set Environment Variables
Variable Description
SB_NAME Indicates the short name of current sandbox.
SB_BUILD_ARCH Identifies the local compilation architecture of sandbox environment.
SB_TARGET_ARCH Identifies the target architecture for sandbox environment. Usually, this is a name like Linux.x86_64 or SunOS.sparc, but virtual architectures that represent a collection of compilation settings can be created by appending administrative-defined text. Example: Linux.x86_64.testCoverage, Linux.x86_64.Debug.
BT_PATH Specifies the absolute path names of all backing trees associated with the sandbox. Normally, this is a colon-separated list; however, some platforms may use an alternative separator (such as a semicolon).
BT1 Convenience variable that specifies the root directory of first backing tree associated with the sandbox. It is important to remember that sandboxes are really backed by a path of backing trees (BT_PATH) and are not restricted to a single root directory. Scripts should almost always use BT_PATH rather than BT1 to preserve generality. If present, the second and subsequent backing tree roots are named BT2, BT3, etc.
ST Specifies the root directory of local sandbox, which should be $SB_ROOT_DIR/$SB_NAME.
STS Specifies the root directory of local sandbox source tree, which should be $ST/src.
STO Specifies the root directory of local sandbox object tree for the current build target architecture, which should be $ST/obj/$SB_TARGET_ARCH.
STI Specifies the root directory of local sandbox exported include files, which should be $ST/include.
STL Specifies the root directory of local sandbox exported libraries for the current build target architecture, which should be $ST/${SB_TARGET_ARCH}/lib.
STB Specifies the root directory of local sandbox exported binaries for the current build target architecture, which should be $ST/${SB_TARGET_ARCH}/bin.

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, like deployment utilities. It may also include specification of utilities such as the compiler, assembler, linker, etc., but these are often associated with the target architecture.

Configuration Files

Various global configuration files are maintained in the $SB_TOOLS_ROOT/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 by mkbt, symbolic links of the appropriate files are made from the $SB_TOOLS_ROOT/config 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 primary versions will have immediate effect in all backing trees except those in which effort was made to create unique copies.

Note: backing trees are identified by the existence of their BuildEnv directory; the lsbt command uses the presence of a BuildEnv directory to find appropriate trees rooted under the directories specified in BT_ROOT_PATH.

Supported Architectures

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 ‑‑ba`_supportedArchitectures.txt. In some environments, the backing trees will be placed on a network file system and visible to machines with heterogeneous operating systems and processor architectures and not all platforms will be capable of compiling for non-native targets. The three 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.

Custom Architecture Definitions

Sometimes it is useful to define a virtual custom architecture that is associated with the definition of compiler flags which are incompatible with normal defaults (e.g., ‑‑test-coverage). This can be done by the owner of the build system by editing the $SB_TOOLS_ROOT/config/ALL_supportedArchitectures.txt file, but a developer can define their own variants by creating an $ST/BuildEnv directory and creating one of the three Architectures.txt files. For example, one might add a Linux.x86_64.coverage entry to correspond to a build with test coverage enabled and create a $ST/config/targetEnv.Linux.x86_64.coverage_sh.txt configuration file with all of the desired configuration definitions.

Build and Target Architecture Configuration

There are several (perhaps more accurately characterized as many) optional configuration files consumed by the workon command that can be used to customize the environment. These files all end in “_sh.txt” to indicate they are shell scripts intended to be included rather than executed directly. Since these files are consumed by the workon command, they must be suitable for processing by the /bin/sh interpreter. There are usually more than 20 possible configuration files examined for a fundamental target architecture and at least 15 additional files examined for every specialization selected. This yields a fine level of granularity that helps avoid duplication of content, but can make it a bit of a challenge to decide the best place for configuration logic to be placed. The goal is to choose the most generic criteria, but when in doubt, use the most specialized file name and get on with your work.

The configuration files are generally found in either the ${ST}/BuildEnv or ${STS}/BuildEnv directories, or the corresponding equivalents in any of the members of the backing tree chain. Those in ${ST}/BuildEnv are expected to be copies populated when mkbt was performed, whereas those stored under ${STS}/BuildEnv are intended to be project-specific overrides or additions that are maintained in the chosen source code control system.

There are 4 main classes of files that are consumed: those that prepare the build environment itself, those that are related to the target architecture, those that are specific to the compiler in use and user exits that provide an opportunity for backing tree and sandbox-specific customizations.

  1. buildEnv - setup the build environment
  2. preTreeEnv_sh.txt - user exit after build environment has been configured
  3. targetEnv - setup parameters related to the target
  4. compilerDefaults- setup compiler-specific options
  5. postTreeEnv_sh.txt - user exit for final configuration related to the source tree.
  6. sbEnv_sh.txt - user exit for sandbox-specific customizations

Some of the configuration files have the special keyword ALL as part of the architecture name; these serve as wild cards and will always be consumed if matched. For example, buildEnv_Linux.ALL_sh.txt is always consumed when the local system is running Linux, regardless of the CPU architecture, but it would not be consumed on an MacOS or OpenBSD system. A similarly named file with ANY as part of the architecture name is treated nearly identically, with the significant difference that it will not be read if any specialization file was processed previously; instead, they serve as fall backs of last resort.

The following illustrates the configuration files that would be consumed if the target architecture was specified as ‑‑ta Linux.x86_64.coverage+release. The first collection of files are related to the build environment itself. The references to Linux and x86_64 in the buildEnv files are related to the platform hosting the build, not the intended runtime target. Note that buildEnv_FINAL_sh.txt is always processed last.

After the buildEnv_* files are processed, the preTreeEnv_sh.txt will be consumed before moving on to the targetEnv_* files. These are specific to the target runtime, not the build system. Following the pattern of the buildEnv_* files, targetEnv_FINAL_sh.txt is the last consumed.

Configuration for the particular compiler in use takes place during the next phase. In the list below, g++ is the chosen compiler, but it could have been clang++, em++, x86_64-w64-mingw32-g++, or another alternative compiler. The last file consumed in this phase is compilerDefaults_FINAL_sh.txt.

The final two files consumed are postTreeEnv_sh.txt and sbEnv_sh.txt.

The preTreeEnv_sh.txt file is used by the workon command to setup any specialization specific to the backing tree chain. Often this file will not be present and will only be used when project-specific customization is required. The corresponding postTreeEnv_sh.txt file will be processed after all other configuration files have been consumed. As a final step, a sbEnv_sh.txt file will be processed if present. This file is often used for developer-specific customizations.

Configuration Variables

Several variables are used throughout the configuration files, many of which are subsequently used by make or the equivalent. The included sbMakeRules.template file implements sandbox-aware rules for compiling and linking programs; however, its use is constrained to Makefiles.

The collectBuildFlags command is used obtain flags stored in the environment that begin with the prefix of BLDFLAG and also parses SB_TARGET_ARCH to generate a series of define directives for IS_FOR_TARGET_ macros. Given a workon with a target architecture of .coverage, an invocation of collectBuildFlags similar to:

BLDFLAGmyFlag=aValue collectBuildFlags
 
yields the following output that will be passed to the preprocessor invocation:
-DIS_FOR_TARGET_coverage=1 -DIS_FOR_TARGET_x86_64=1 -DIS_FOR_TARGET_Linux_x86_64=1 -DIS_FOR_TARGET_Linux=1 -DIS_FOR_TARGET_Linux_coverage=1 -DBLDFLAGmyFlag=aValue

Most of the configuration environment variables are utilized by sbMakeRules.template.

Configuration Variables
Variable Name Env make rules Description
ALWAYS_NEEDED_LIBS Y N Locally administered list of libraries that must be included when linking an executable. For example, compilerDefaults_ALL>coverage_sh.txt sets this to ‑lsubc++.
AR Y Y Usually ar or the absolute path to the desired equivalent.
ARFLAGS Y Y Usually cr.
ASAN_OPTIONS Y N Used to pass options to the sanity checking runtime. Usually set to abort_on_error=1.
CC Y Y Specifies the C compiler. Usually either gcc or clang.
CFLAGS Y Y Specifies flags for the C compiler. Normally set by sbMakeRules.template from the values of $(EXTRA_CFLAGS) and $(EXTRA_CFLAGS_$(CONF)).
CONF Y Y Locally administered convention to indicate type of build; usually either Debug or Release. Used to select additional options.
CPPFLAGS Y Y Specifies flags for the preprocessor. Normally set by sbMakeRules.template from the values of $(EXTRA_CPPFLAGS) and $(EXTRA_CPPFLAGS_$(CONF)) as well as paths to all of the include directories and any build flags retrieved by collectBuildFlags.
CROSS_COMPILER_PREFIX Y N If set, usually something like x86_64‑w64‑mingw32‑ or i686‑w64‑mingw32‑.
CXX Y Y Specifies the C++ compiler. Usually either gcc++ or clang++.
CXXFLAGS Y Y Specifies flags for the C++ compiler. Normally set by sbMakeRules.template from the values of $(EXTRA_CXXFLAGS) and $(EXTRA_CXXFLAGS_$(CONF)).
DEFAULT_TARGET_ARCH Y Y Specifies the target architecture options for a compile. Used to set TARGET_ARCH.
DEFAULT_TARGET_ARCH_${CONF} Y Y Specifies additional target architecture options related to a locally-administered configuration. Used to set TARGET_ARCH.
DLL_PREFIX Y Y Usually lib on Unix variants and the null string on Windows targets.
DLL_SUFFIX Y Y Usually .so on Unix variants and lib on Windows targets.
EXE_SUFFIX Y Y Usually the null string on Unix variants and .exe on Windows. This is used with targets.
EXTRA_BUILD_TARGET_LIB_DIRS Y Y Normally the null string, but used with cross compilers to specify additional directories that should be searched.
EXTRA_CFLAGS Y Y Used to set CFLAGS.
EXTRA_CFLAGS_${CONF} Y Y Used to set CFLAGS with configuration-specific entries.
EXTRA_CPPFLAGS Y Y Used to set CPPFLAGS.
EXTRA_CPPFLAGS_${CONF} Y Y Used to set CPPFLAGS with configuration-specific entries.
EXTRA_CXXFLAGS Y Y Used to set CXXFLAGS.
EXTRA_CXXFLAGS_${CONF} Y Y Used to set CXXFLAGS with configuration-specific entries.
EXTRA_CXXFLAGS_Debug Y Y Debug-specific CXXFLAGS.
EXTRA_LDFLAGS Y Y Used to provide default values for LDFLAGS.
EXTRA_LDFLAGS_${CONF} Y Y Used to provide default values for LDFLAGS.
EXTRA_LD_POSTFLAGS Y N
EXTRA_LD_PREFLAGS Y N
EXTRA_NEEDED_LIBS Y N
EXTRA_OPTIMIZE_FLAGS Y N Appended to both EXTRA_CXXFLAGS and EXTRA_CFLAGS by compilerDefaults_FINAL_sh.txt. Treated as a user-exit to adjust the optimization level.Since it is appended and the last seen value is in force, often used to temporarily disable optimization.
LD_LIBRARY_PATH Y N On Linux variants, specifies additional directories from which shared libraries should be loaded. Set by most of the compiler-specific compilerDefaults_*.ALL_sh.txt scripts to include the compiler's runtime library.
LIB_PREFIX Y Y Usually lib.
LIB_SUFFIX Y Y Usually .a on Unix variants and .lib on Windows.
NATIVE_EXE_SUFFIX Y N Usually .exe on Windows and the null string on Unix variants. This is used with executables run by the build system host.
OBJ_SUFFIX Y Y Usually o, but obj on Windows and bc for WebAssembly.
PROMPT_COMMAND Y N Recognized by the bash shell and set in shell_rc.bash to use sbrel to obtain the relative position within the sandbox or backing tree hierarchy and dynamically set the command shell prompt.
RANLIB Y Y Usually ranlib or the absolute path to the desired equivalent.
REMOVE_FROM_LINK_FLAGS Y Y Used by sbMakeRules.template. Specifies any flags that should be stripped from a link step.
RM_BEFORE_LINK Y Y Usually set to /bin/rm ‑f and used to delete an output file before attempting a link that might fail. For incremental linking, set to echo Retain.
SB_MAKE_COMMAND Y N Absolute path of sbmake command. Used for performance.
SBREL_PATH Y N Absolute path of sbrel command. Used for performance.
SB_TARGET_ADDR_SIZE Y N Indicates intended compilation mode. A value of 64 indicates a 64-bit target, whereas a value of 32 corresponds to a 32-bit target.
TARGET_ARCH Y Y Used directly by sbMakeRules.template. If not set, it is the concatenation of $(DEFAULT_TARGET_ARCH) and $(DEFAULT_TARGET_ARCH_$(CONF)).
UNWANTED_CXX_WARNINGS N N Appended to EXTRA_CXXFLAGS by compilerDefaults_FINAL_sh.txt.
UNWANTED_WARNINGS N N Appended to to both EXTRA_CXXFLAGS and EXTRA_CFLAGS by compilerDefaults_FINAL_sh.txt.
_CXX_COMMON_FLAGS N N Appended by compilerDefaults_FINAL_sh.txt to EXTRA_CXXFLAGS. Typically holds flags like ‑pipe, ‑Wall, etc.
_CC_COMMON_FLAGS N N Appended by compilerDefaults_FINAL_sh.txt to EXTRA_CFLAGS. Typically holds flags like ‑pipe, ‑Wall, etc.
_extraDebugInfo N N Appended by targetEnv_FINAL_sh.txt to EXTRA_CXXFLAGS_Debug.
_extraOptArch N N Appended by targetEnv_FINAL_sh.txt to DEFAULT_TARGET_ARCH.

Shell-specific RC Files

Users can use the command shell of their choice. After preparing the sandbox environment, the workon command passes a shell_rc.`basename ${SB_SHELL}` script to the spawned subshell. 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. Customizing the appropriate buildEnv_*_sh.txt or targetEnv_*_sh.txt file is the preferred mechanism as only one set of modifications will be required.

Sandbox RC File Format

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 edited 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, sbname, sbroot and btpath:

Recognized Attribute Names
Attribute Name Description
sbname which identifies the sandbox name,
sbroot which identifies the root directory of the sandbox and
btpath which identifies the path of backing trees associated with the sandbox. While it is common for only a single element to be present in the backing tree path, it should be stressed that a list of several backing trees is permitted. This advanced usage can be used to chain together another user's sandbox, a global backing tree with a subset of content and a primary backing tree.
description maintains a description of the sandbox to help the user recall the purpose of the sandbox.
defaultTargetArch defines the target architecture to be used by workon if none is specified as an argument.
SandboxRetargetted a special flag set by the resb command to indicate that a sandbox has been retargetted to a different architecture. If the workon command sees this flag, it will run the sb_retarget command and delete the attribute.

The format of 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

Sample Usage

mkbt -bt tree1
mksb -sb test1 -bt tree1 -desc “Sample sandbox”
workon -sb test1
resb -sb test1 -ta Windows.i686



Sandbox First Steps

Optional Environment Variables

To get started, one needs to know where the backing trees will be maintained. This will normally be set by the system administrator and, by default, this will be under /opt/backingTrees. If this is not the case, the BT_ROOT_PATH environment variable should be set to point at the appropriate directory. It is possible to pass a ‑‑btroot option to commands that need to be aware of the BT_ROOT_PATH variable, but this is extra effort and prone to error.

The SB_ROOT_DIR environment variable serves to specify the default directory under which a user's sandboxes should be created. If not set and the ‑‑sbroot command line option is not specified, the default of $HOME/sandboxes will be used by the mksb command. Since every sandbox has its root maintained in the sandbox rc file, a sandbox can be stored anywhere. They do not need to share a common root directory.

The location of the user's sandbox rc file that stores the parameters associated with each sandbox is usually $HOME/.sandboxrc. It is possible to specify an alternative configuration file using the ‑‑rc command line option, but it would be rare to find a compelling reason to use an alternate name or file. That said, the mkBTrcFile command is used to do exactly that to permit a backing tree to be accessed with the workon_bt command.

A user can specify the shell they wish to use in workon sessions by setting the SB_NAME environment variable to the full path of the shell (e.g., /bin/csh). If not set, the shell in use at the time of the workon invocation will be used. A typical scenario is one in which the system administrator has mandated the use of /bin/sh for login shells but a developer prefers to use /bin/csh for development work.

The sbsvnget utility can use the environment variables SVN_HOST and SVN_PATH to access a Subversion repository. If only a single repository is in use locally, it can be extremely convenient to set these variables.

Automated backing tree builds

Typically, an administrator sets up an automated process that uses the mkbt command to create a new backing tree, extract the most current source code image from a repository and do a complete build. If successful, a symbolic link with an appropriate name (e.g., current) will be created to point at the new backing tree. Developers can use that symbolic name as a backing tree and have their sandboxes automatically backed by the most recent successful build. In a similar fashion, an image of production releases is maintained, making it easy for developers to immediately compile against any previously released production image. The DoNewBT command can do all of this work. It uses overlaySBbuilds to do builds for multiple architectures using the same source tree, and it in turn uses checkoutNewBT to obtain the source image from the selected source code repository.

One issue with backing trees that get accessed using a generic symbolic name is that updates to their content may not always trigger a needed recompile because the automatically generated Makefile dependencies are not regenerated. The cleanDependencies script can be automatically run by sbmake when it detects an updated backing tree, thus forcing the local regeneration of the dependency files.

Creating a sandbox

Sandboxes are created using the mksb command. One needs to know the name of the sandbox to be created and the backing tree(s) with which it should be associated. One can get a list of the available backing trees by issuing the lsbt command. The name of the sandbox is entirely up to the developer, but must be something representable as a directory name. It should not use white space even if the local filesystem is capable of storing such names.

The mksb command has a simple interactive mode (requested via the ‑i flag) that will prompt for required parameters:

$ mksb -i
/opt/backingTrees/bin/mksb: sandbox name was not specified.

Enter name of sandbox: sbtest
/opt/backingTrees/bin/mksb: no backing trees specified.
Available backing trees: current test1 release
Enter backing tree name or path: current

Developers usually quickly become proficient with the mksb command and will just enter the needed arguments on the command line. A description can be added to annotate the intended usage of the sandbox if the name itself was not sufficiently informative.

$ mksb -sb sbtest -bt current -desc 'Feature 53126'

Once a sandbox is created, a developer makes use of it via a workon command.

Working in a Sandbox

A developer usually issues a workon command to begin a development session:

$ workon -sb sbtest

When a development session is complete, the shell is closed (usually via control-D or an explicit exit).

It is possible to use a workon command to invoke a command in the context of a sandbox. For example:

$ workon -sb sbScan -suffix makefile CXXFLAGS

This usage is most commonly found in scripts.

Each sandbox has a default target architecture, which can be altered with the resb command. It is also possible to set a different target architecture for the duration of the current workon session using the ‑‑ta option. This can be useful when a developer wants to use the same sandbox and compile for multiple machine architectures.

Local Installation

If a developer cannot get the sandbox tools suite installed using administrator privileges, it can be installed under the user's home directory. Assuming the sandboxTools.tar.gz package was stored under $HOME:

  1. cd $HOME
  2. mkdir sandboxTools
  3. cd sandboxTools
  4. tar xvf ../sandboxTools.tar.gz
  5. If the operating system is not Linux, either make a symbolic link to Linux.noarch or simply rename it:
            ln -s `uname -s`.noarch Linux.noarch
            
    or
            mv Linux.noarch `uname -s`.noarch
        

    On Windows, one should just use the text "Windows" in place of the "`uname -s`" usage and do the rename:

            mv Linux.noarch Windows.noarch
        
  6. cd $HOME
  7. cp sandboxTools/etc/sandbox_tools.sh .
  8. Edit $HOME/sandbox_tools.sh to update BT_ROOT_PATH and SB_TOOLS_ROOT. In the fragment below, BT_ROOT_PATH uses a UNC name on Windows to reference backing trees stored on a file server named "fileserver". This would need to be set to something appropriate for the local environment, which might be $HOME/backingTrees if there is no other alternative. The setting for SB_TOOLS_ROOT will be as shown since the sandbox tool suite was installed to $HOME/sandboxTools. Other settings can be changed if desired, but there is probably no need.
    # Local preference for location of backing trees
    # ------ EDIT THIS SETTING APPROPRIATELY! ------
    BT_ROOT_PATH="${BT_ROOT_PATH:-//fileserver/backingTrees}"
    export BT_ROOT_PATH
    
    
    # Point to installation root of sandbox tools suite
    # ------ EDIT THIS SETTING APPROPRIATELY! ------
    SB_TOOLS_ROOT="${SB_TOOLS_ROOT:-${HOME}/sandboxTools}"
    export SB_TOOLS_ROOT
    
    
  9. The login profile should get updated to include the sandbox_tools.sh and pick up some of the shell completion scripts, which probably means adding the following to the end of $HOME/.bash_profile:
    SB_USE_SSH_AGENT=1; export SB_USE_SSH_AGENT
    
    source "$HOME/sandbox_tools.sh"
    source "$SB_TOOLS_ROOT/etc/mksb_completion.sh"
    source "$SB_TOOLS_ROOT/etc/workon_completion.sh"        
    

    If no SSH public keys are in use, the SB_USE_SSH_AGENT value can be set to 0 to avoid the use of the ssh-agent.

    From this point onwards, a new cygwin terminal shell will setup the desired environment during its initialization.

  10. Start a new cygwin terminal to load the prepared environment and build-and-install the performance-sensitive utilities:
    $ cd $SB_TOOLS_ROOT/cmdSource
    $ ./compileSandboxCommands.sh
                

Global Installation

If a system administrator is deploying the sandbox tools suite to be used by all users on the local system, steps similar to those for a local installation are performed, except that a few files are populated to globally-visible locations.

  1. Pick a global directory into which the sandboxTools.tar.gz package will be untar'd. Often this is /opt/sandboxTools, which is the default in the configuration files. Make the chosen directory if needed and untar the contents of sandboxTools.tar.gz into it.
  2. Copy sandbox_tools.sh prototype from the etc directory to /etc/profile.d.
  3. Edit the new /etc/profile.d/sandbox_tools.sh and modify the settings of BT_ROOT_PATH and SB_TOOLS_ROOT appropriately. Verify that the file is readable by regular users, but not writeable. If necessary, fix the permissions using chown.
  4. Source the modified sandbox_tools.sh to pick up the new environment variables.
  5. Copy mksb_completion.sh and workon_completion.sh (and any other completion scripts that might be present) to /etc/bash_completion.d. Verify that these are readable by regular users, but not writeable. If necessary, fix the permissions using chown.
  6. Run the cmdSource/compileSandboxSandboxPathCommand.sh script. This will compile the performance-sensitive filesystem-related commands and place the resulting executables in the appropriate operating system/CPU architecture-specific bin directory. Verify that these are readable and executable by regular users, but not writeable. If necessary, fix the permissions using chown.
  7. If deploying on an alternate operating system, either rename the default Linux.noarch to the local operating system or (preferably) add a symbolic link, similar to this for MacOS:
            # ln -s Darwin.noarch Linux.noarch
    

Configuration for use with Microsoft Visual Studio Code

Microsoft Visual Studio Code must know the path to an executable to be able to invoke it successfully. Unfortunately, cygwin's Unix-like paths of /usr/bin/bash will not work. They need to be translated to the actual Windows path name and the magic utility for this purpose is cygpath. It will be used to convert the path names of executables of interest so that the resolved paths can be placed into the environment.

Assuming an appropriately edited version of sandbox_tools.sh was placed in the home directory along with a copy of the setup_vscode_under_cygwin.sh script below (available as $SB_TOOLS_ROOT/etc/setup_vscode_cygwin.sh:

for _prog in bash gdb g++ clang++
do
        _cyg_path=`which ${_prog} 2>/dev/null`
        if test -z "${_cyg_path}"
        then
                echo Failed to obtain a path for ${_prog} >&2
                continue
        fi
        # convert each "\" to "\\" for later eval
        _exe_path=`cygpath -w "${_cyg_path}" | sed -e 's/\\\\/\\\\\\\\/g' `
        # convert program name to upper case, convert plus signs to PLUS
        _envVar=`echo ${_prog^^} | sed -e 's/++/_PLUSPLUS/'`_EXE_PATH
# If shell lacks support for ,, and ^^ then use instead:
#        _envVar=`echo ${_prog} | tr '[:lower:]' '[:upper:]' | sed -e 's/++/_PLUSPLUS/'`_EXE_PATH
        eval ${_envVar}="${_exe_path}"
        eval export ${_envVar}
done
    

add the following to the end of the $HOME/.bash_profile:

SB_USE_SSH_AGENT=1; export SB_USE_SSH_AGENT

source "$HOME/sandbox_tools.sh"
source "$SB_TOOLS_ROOT/etc/mksb_completion.sh"
source "$SB_TOOLS_ROOT/etc/workon_completion.sh"
source "$SB_TOOLS_ROOT/etc/setup_vscode_under_cygwin.sh"        
    

After doing an appropriate workon, Microsoft Visual Studio Code can be launched via code. The actions requested by Microsoft Visual Studio Code will be performed in the context of the sandbox, but one still needs to integrate with the utilities being used. A build task using sbmake can be added to the tasks.json using an entry similar to:

    "tasks": [
        {
            "label": "sbmake",
            "type": "shell",
            "command": "${env:BASH_EXE_PATH} -c sbmake",
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]

Note how the bash interpreter is really the native executable that is invoked and it is passed the sbmake command as the real work to be performed.

Questions

Questions can be sent to: Geoff Carpenter http://www.fargos.net/gcc.html