Table of Content
|
[up one level]
|
Basic idioms
|
Using SBuild is a matter of running build scripts on the command line (Using SBuild in Eclipse is a matter of configuring workspaces and clicking icons, of course). Build scripts are usually all in one place. They are easy to spot because all having a similar name: build_something.py where something is a build target id.
All build scripts support the same command line options. They all support the option -h to dump a rather large usage message. The rest of this page describes with more words that message. Most options are in the form <key>=<value>; we call them keyword arguments. Also important, the scripts do nothing when run without any argument; they just display some status and short usage message.
[back to top]
|
Actions to perform
|
The most important category of options is telling SBuild what action to take. You can do basically one of four things to targets:
- Build. As you may guess, build_something.py -b will do an incremental build of the default target in this script, most likely named "something". And build_something.py -B will perform a forced build of it (a.k.a. full rebuild).
- Clean. build_something.py -c will just remove all built files. There is no incremental cleaning, just a full clean.
- Run. build_something.py -r will walk the tree and run built executables. More on this in the dedicated section below.
- Inspect. This will print out some information on all targets in the tree and a report at the end. SBuild has a whole bunch of different actions for this purpose. For example, build_something.py action=search(<pattern>) will look for regular expression maches in source files and print them out. More examples throughout this page.
The first two are performed using SCons (we name them SCons actions) and the last two are performed without starting SCons (we name them SBuild actions). The general form of actions is action=myaction(<params>) but many of them have 1-letter abbreviations. For example, build_something.py -S and build_something.py action=print(srcs) will both list source files.
[back to top]
|
What to act upon
|
If no indication, SBuild makes a target tree starting at the default target in the current script and perform the desired action on all nodes in this this tree. You can change that in several ways:
- Specified target. You can say tgt=<my_target_id> and that will change the root of the dependecy tree to my_target_id. You can also say pat=<my_pattern> and/or antipat=<my_anti_pattern> and then an alias is made up on the fly with all matching targets ids in the current script.
- Forced versus incremental: For some actions, you can apply them to all targets in the tree or only to those which are not up to date. For example, build_myscript.py -P will print all command lines and build_myscript.py -p will print only those needed to bring everything up to date.
- Max depth: You can limit the application of SBuild actions to a certain depth in the tree. Particularly useful with the inspect category of actions.
You can learn what targets are described in the current script: build_myscript.py -L. That is also useful to see what your pattern actually selects when you use pat=. You can also find targets in other scripts: build_myscript.py -T or simply grep. Of course, all that is more natural in the Eclipse SBuild plug in. Note that you cannot name a target described in another script using the tgt= keyword argument but we may add that feature later.
[back to top]
|
Specifying flavors
|
All systems support building different flavors of what is to build. In the worst case, one has to specify them as separate targets. But most build tools, like SBuild, allow to build flavors out of the same target specification. The typical example is compilation of a C program for different target platforms or for the same platform but with competing toolchain or just with different optimization options.
SBuild let you build flavors using variants and toolkit parameters. For example you may add to a build command line bldopt=rls and that will perform a so-called realease compilation of the C code. You may say lint_usage=0 and that will disable the check using lint in front of a C compilation. You may also say tgtplatform=armv4_smarphone2003 and that will compile and link your code for that target platform or it will complain that you don't have the propoer toolchain installed or that you don't have the proper platform run-time libraries to link with.
Variants and toolkit parameters can be set on the command line, from shell environment variables and from several customization files on disk. What variants, what parameters are supported, what values are allowed for them by your build at hand will be listed by a dedicated command line option. More on variants and toolkit parameters elsewhere.
[back to top]
|
Running targets
|
Each time you build something, you will immediatley want to test it. SBuild goes a long way to help you with that. Using the option -R or the equivalent action=run() will travel the dependency tree and run targets. Running means starting something that you can specify in the build description in what is called a runner specification. If the target built in that node is an executable, then a runner is made on the fly to run that built executable. There are ways to associate several runners on each target, ways to filter what you run, way to just print out the command line but not run anything (run_filter=print:1), ways to pass parameters to what you run (action=run(<params>)), etc.
As a matter of facts, the most frequent idiom of using SBuild is the sequence build_something.py -b followed by build_something.py -r. That simply builds and then tests something. The option -r is the same as -R but doesn't run things that you mark as interactive, meaning -r is nice for unattended tests.
For example, you may use -b then -R to build a .chm file and then open it (to manually inspect the content).
[back to top]
|
Controlling the process
|
After you told a build script what to perform and on what to act upon, there are still many ways left in which you can run a build. All the alternatives listed here below are inherited by SBuild from SCons.
- Error behavior: you can stop on the first error or continue until you are completely blocked by errors.
- Parallel builds: you can run sequencially ro run in parallel steps that are not dependent on one another.
- Speed-safety flexible compromise: your can decide to sacrify coherence in some corner cases for the sake of faster build
- Others (timings, verbosity)
[back to top]
|
Basic inspection
|
Delivering information about the subject of builds is certainly one of the strong points of SBuild and it opens it to usage scenarios that are completely new for the average build tool. The inspection features (a.k.a. introspection) of SBuild fall in three closely related categories:
- print out
- searches
- checks
[back to top]
|
What and where
|
SBuild scripts have several ways to print out what is built, out of what and where will be the output.
- -T This dumps the SBuild tree (the tree where the nodes are the SBuild targets). It also shows also the hierarchy of build scripts, since targets in this script will most likely have also subtargets in other build scripts in the same SBuild package.
- -t This shows the SCons tree (the tree where the node are the files in the file system). This is significantly larger and slower to show than the SBuild tree. It includes the implicit dependencies as discovered by SCons.
- -O Same SCons tree but without the genuine input. It actually shows the output of the build, with complete absolute paths on disk.
- -U This dumps the "inverse" SBuild tree. That means you see for each target in what other targets is it a subtarget (U stands for "used", each target prints "who is using me").
- -S This lists sources (what a target decides to call sources, most of the time that is exactly the genuine input). The listing is not in format of a tree and every target prints the sources only once.
[back to top]
|
What and why
|
All decent build tools allow you to query what is not up to date and why. Although it is meaningful to list the what and the way separately, SBuild does it with just one option, -W, which maps directly to the feature of SCons. This query is useful for debugging (but limited since there is no roll back and no step-by-step; users usually notice too late that they should have call it first).
[back to top]
|
Searches
|
SBuild lets you search for matches in source files with the typical regular expression patterns: action=search(<pattern>). Like for most actions, a summary is displayed, here just counting the hits. The search is performed on what every target type decides are the sources to search. For example, the C compiled object taget decides that "sources" are both the .c files and the .h files actually included in them for the build at hand. There are also search options, for example you can decide to leave out from the search the comments in source code (search_filter=nocomment:1).
[back to top]
|
Checks and reports
|
There are specific ways to check specific things in different toolkits. Here we mention the action=lines() in the base toolkit. It shows stats on the sources on the following:
- Lines longer than a threshold
- Lines having tab characters
- Lines having trailing spaces
- Lines having characters beyong the ASCII range
The lines action can also be instructed to fail at the first violation instead of printing statistics at the end.
[back to top]
|
Reference information
|
SBuild provides the keyword argument explain=<code> to dump in the stdout reference information with various degrees of verbosity. Here are the supported codes:
- wiki fires a browser to the Intranet SBuild site
- sum list all toolkits and all variants (available for this SBuild package) as well as a summaryof each toolkit and each variant
- tk list all toolkit parameters for all toolkits (a.k.a. toolkit defaults) and their meaning
- tk:<name> to limit the output to toolkit <name>
- var list variant details for all variants available. These details include all allowed values of each variant and the text description of those allowed values, environment variables to control it if any, etc.
- var:<name> for one specific variant
- tgt list exhaustively all target attributes allowed in all target descriptions and their meaning. Useful when writing targets in the build description.
- tgt:<type> to limit the output to the attributes of the target <type>
- all list all the information available
Despite this profusion of information or, more likely because of it, users are occasionally asking for pieces of information already available. SBuild is sadly lacking a searchable form of this information, like a CHM file.
[back to top]
|
C/C++ specific inspection
|
All the options that you may expect are there:
list include directories: action=print(inc) (also -I) shows the list of directories used to search headers for each target
list applied defines: action=print(def) shows the defines that are set in the build description for each C compilation target
list exported symbols: action=print(exp) shows what C function names are intended to be exported from dynamic libraries
list what is linted by default and what not: action=print(lint)
list used SDKs: action=print(sdks) shows the precompiled parts of the current build. This is usually C/C++ code from third parties. Note that it may be also just some code that you own but you decided that it should not be updated by the incremental build.
ignore comments in searches: action=search(<pattern>) search_filter=nocomment:1
show the header inclusion tree: action=preproc(tree)
measure source lines of code (SLOC): action=preproc(lines)
list conditional compilation tests: action=preproc(ifdef) shows all the conditional blocks but no C code. action=preproc(open_def) lists all the unique conditions (used in those tests). Those are usually the defines that a piece of C code expects to come from the build descriptions. Both these preproc actions can be made to consider or to ignore the actually included headers.
list C functions: action=cparser(func) lists the functions that are defined in the source code (and the line numbers corresponding to the beginning and the end of the definition)
- list C macros: action=cparser(mac) shows the defines that are set in the C source code.
There are many more features of the C/C++ toolkit. They are controlled by its toolkit parameters and those can be listed (with explanations) by running explain=tk:ccpp on any build script. Among the trivial ones, as example, you can completely disable lint (lint_usage=0) or fully enforce lint (lint_usage=1). On the more advanced side, you can turn on checking involving the C preprocessor or the C linker included in the C/C++ toolkit.
[back to top]
|
A bit of shellology
|
There is at least one small caveat of the command line: spaces are not tolerated unless you escape them so that the shell is not mislead and still considers one argument what you think is one argument. This is not difficult to understand but the Microsft shell and the Unix shells are very different in that respect and that systematically fools our users. Other than that annoyance, the build command lines are the same on Unix and Windows build machines.
[back to top]
|
Nice to have
|
- Experimental changes. These are ephemeral changes of the build description from the command line. The ability for punctual changes of the build without touching any file is a frequent user request. The challenge is to allow that in a controlled way, without any negative impact on the consistency of past, present or future builds. SBuild is up to the tasks (due to SCons). There are two ways to do it:
- Overwrites: This is the possibility to change particular attribute(s) of particular targets(s) in the tree from the command line. The keyword arguments owtgtattr=<pairs> and owtgtpat=<pat> are provided for that purpose.
- Direct arguments: This is the possibility to pass over directly some command line options to some particular executable used during the build. For example direct_args_ccpp='-DMYDEFINE' will pass -DMYDEFINE to all C and C++ compiler command lines in that build.
- Shell environment script. Once you have a command line to build something, you can ask SBuild to give you a shell script that "captures" those settings in shell environment variables. Two shell syntaxes are supported: bash and cmd. The resulted script can be used to "set" the environment or to "clean" it. This is very useful if you have programs running after the build, like tests, that are using this same set of variables to select which set of the just-built binaries to use.
- New keyword arguments. If desired, any build script can use a newly-invented keyword argument, for example myarg=somevalue. In your build script sb.opts.myarg will be a Python string "myvalue". No special SBuild feature for that (unlike SCons, which uses Optik), just use plain Python in your build script. We saw only once this possibility used and we consider seriously removing it.
[back to top] [up one level]
|