build-config

Generalities

build-config controls every step of the compilation, pseudo-installation, and packaging process. It is component-based: each project is considered as an independent entity, which has requirements and dependencies on other components (other projects, or system libraries). build-config is an extensible tool: you can create new projects and manage them using build-config.

The most common use of build-config is for compiling existing projects. The standard use of is is:

build-config [global-options] \
    component1 [component1-options] [component2 [component2-options] ...]
Here, component1, component2 etc. are the names of the projects you wish to compile.

A compilation process involves several steps, some of them being optional:

  • components detection and dependencies resolution
  • configuration
  • compilation
  • documentation generation
  • packaging

Dependencies are handled by build-config: here if, for instance, component2 depends on other component3 and component4 components, then component3 and component4 will be added to the list of components to build, and processed/built before component2 is processed. So you don't need to specify them on the commandline: only highest-level terminal components are required explicitly (but it is not a mistake to specify them all, of course).

Some commandline options can control whether and how these steps are done. By default, only detection, configuration and compilation steps are performed. There is also another step meant exclusively for developers: version change, and when requested, is executed just after the component detection step.

Commandline options are either global, or targetted at one or more components. All options passed before the first component is named are considered to be global, and are applied to all components. To aim an option to only a specific component, use it just after this component is named on the commandline. For instance:

build-config --buildMode release cartodata --verbose 1
Here the --buildMode release option is applied to all processed components, whereas the --verbose 1 option is only applied to the cartodata component. As cartodata depends on cartobase, which in turn depends on several system components, these extra components will be processed without the verbose option.

Boolean options, like the --verbose option, have no value if they are passed as global options, but must always have a value if they are passed as component-specific options. This is for technical reasons, because components options types are not known at the moment the commandline is parsed. For instance, you say:

build-config --verbose cartodata
whereas if you want to apply the verbose option only to cartodata, you must type:
build-config cartodata --verbose 1

Portability

At the moment, build-config and the other compilation tools need a sh or bash-like Unix shell. This does not mean that it cannot run on Windows systems: it does actually work on Windows, but in a shell. So on Windows you have to install either MSys and MinGW or Cygwin.

With the previous restrictions, build-config and the other tools work on the following platforms:

  • Linux
  • Mac OS X
  • Windows XP using gcc and a bash shell
  • Solaris
  • Irix
and it should be easy to add support for other Unix systems.

Quick start

To build anatomist on a Linux system, follow the following steps:

  • Download all sources and uncompress them in the same base directory, let us say, /home/toto/devel for instance.
  • cd to this directory:
    cd /home/toto/devel
    You should see the various projects source trees:
    gargamel:toto% ls
    aimsalgo-3.1/
    aimsdata-3.1/
    anatomist-3.1/
    brainvisa-3.1/
    cartobase-3.1/
    cartodata-3.1/
    ecat-3.1/
    ecat+-3.1/
    graph-3.1/
    pyaimsalgo-3.1/
    pyaims-3.1/
    pyanatomist-3.1/
    shared-3.1/
    soma-3.1/
    util-3.1/
    vidaIO-3.1/
    
  • use build-config to compile everything:
    build-config --version 3.1 --buildMode release pyanatomist pyaimsalgo shared brainvisa
    (it takes several hours, maybe a full day depending on the power of your computer)
  • The configuration and compilation processes create a build directory tree, here build-3.1-linux-release which contains all compiled files, and especially the dynamic libraries, in build-3.1-linux-release/lib, the executable programs in build-3.1-linux-release/bin, and the shared data needed by the programs in build-3.1-linux-release/share:
    gargamel:toto% ls
    aimsalgo-3.1/
    aimsdata-3.1/
    anatomist-3.1/
    brainvisa-3.1/
    build-3.1-linux-release/
    cartobase-3.1/
    cartodata-3.1/
    ecat-3.1/
    ecat+-3.1/
    graph-3.1/
    pyaimsalgo-3.1/
    pyaims-3.1/
    pyanatomist-3.1/
    shared-3.1/
    soma-3.1/
    util-3.1/
    vidaIO-3.1/
    gargamel:toto% ls build-3.1-linux-release
    aimsalgo-3.1-linux-release/
    aimsdata-3.1-linux-release/
    anatomist-3.1-linux-release/
    bin/
    brainvisa/
    brainvisa-3.1-linux-release/
    cartobase-3.1-linux-release/
    cartodata-3.1-linux-release/
    ecat-3.1-linux-release/
    ecat+-3.1-linux-release/
    examples/
    graph-3.1-linux-release/
    include/
    lib/
    pyaimsalgo-3.1-linux-release/
    pyaims-3.1-linux-release/
    pyanatomist-3.1-linux-release/
    python/
    scripts/
    share/
    shared-3.1-linux-release/
    soma-3.1-linux-release/
    tests/
    vidaIO-3.1-linux-release/
    
  • To run the programs, you will need to add the lib directory of the build tree to the LD_LIBRARY_PATH environment variable, the bin directory to the PATH variable, and to set the SHFJ_SHARED_PATH variable to the share directory of the build tree. In a sh or bash shell, it will look like:
    LD_LIBRARY_PATH=/home/toto/devel/build-3.1-linux-release/lib:$LD_LIBRARY_PATH
    PATH=/home/toto/devel/build-3.1-linux-release/bin:$PATH
    SHFJ_SHARED_PATH=/home/toto/devel/build-3.1-linux-release/share
    export PATH LD_LIBRARY_PATH SHFJ_SHARED_PATH
    In a csh or tcsh shell, it will be:
    setenv LD_LIBRARY_PATH /home/toto/devel/build-3.1-linux-release/lib:$LD_LIBRARY_PATH
    setenv PATH /home/toto/devel/build-3.1-linux-release/bin:$PATH
    setenv SHFJ_SHARED_PATH /home/toto/devel/build-3.1-linux-release/share
  • Now you can run the anatomist.bin program and the various Aims commands.

Commandline options

To get the classical commandline help, use the -h (or --help) option:

build-config -h

Here is a list of the most common options:

optiondescription
-h / --helpdisplay help: list all options and components
--buildMode <mode>select optimization mode: default, release or debug
--version build the specified version of the component(s). By default, build-config will try to guess it if there is no ambiguity.
Version can be specified either as a numeric version (the value read in the VERSION file of projects directories), or as an alias which is read as the suffix of the component directory name, ie main is a valid version for a cartobase component in the directory cartobase-main.
--verbose print messages while detecting and processing components. I mean, really verbose. Be warned.
--sources <path> search path list for all components. Components names will be appended to path elements when looking for sources / libraries Several directories can be specified (using ":" as a separator like in Unix PATH, or ";" on Windows). The default search path is the current directory, and a number of system directories is also used to look for system libraries. Specifying the --sources option overrides the default setting (current directory).
--source <path> source directory for a single (specific) component: ie: /home/toto/devel/aimsdata-3.1
--no-configure don't perform the configure step. Only useful only if you know configuration is up to date and you just want to build (or pack) the programs.
--no-build don't perform the compilation step.
--doc perform the documentation step.
--without-<component> disable an optional component dependency, ie: --without-anaalgo, --without-anaqwt, --without-dicom, --without-jpeg, --without-vida, --without-dlopen, --without-aimsgui, ...
--makeOptions <option> options passed to make, ie -j2 or -j40 to use parallel make for 2 or 40 cpus (very useful with distcc)

Components detection and dependencies step

A component represents a software bundle: either a system library (with corresponding include files), a langage (such as python), or a project directory tree designed for build-config. Each component has corresponding files on the disk that build-config has to find and identify. Each component is searched in a specific path list. The default path list contains the current working directory (the directory from which you run build-config), plus some standard system paths such as /usr and /usr/local. Some specific system components can follow their own search rules: for instance the Qt library is searched first by looking at the QTDIR environment variable.

Because the current working directory is the first path to look for components, it is generally convenient to run build-config from the directory containing the projects sources:

gargamel:appli% pwd
/home/appli
gargamel:appli% ls
cartobase-3.1/
cartobase-main/
cartodata-3.1/
cartodata-main/
gargamel:appli% build-config --version 3.1 cartodata

If you have libraries or build-config projects in "non-standard" locations, you can specify the search paths using the --sources commandline option:

build-config --sources /usr/local/software:/home/toto/devel cartodata
on Windows, the path separator character is ; instead of :
build-config --sources "C:\Program Files;C:\mingw;D:\devel" cartodata
(and you may have to double the backslashes in a bash-like shell like MSys)

For build-config specific projects, it may be a little bit more complex if you have several versions of the same project: then build-config will not be able to guess by itself which one you wish to use and compile. In this case you have to specify a version option:

build-config --version 3.1 cartodata
Here all components are looked for with version 3.1. If you wish to specify a different version for a given component, you can use component-wide options:
build-config --version 3.1 cartodata cartobase --version 4.0
Here all components will be looked for with version 3.1, except cartobase which we expect version 4.0.

Version information can be specified either as a numeric value, this value is read from the VERSION file in the root of projects directories, or as a symbolic extension to the projects directories names: in the previous example, "main" is a possible value for the version passed to build-config:

build-config --version main cartodata
will look for projects named <project>-main, even if their VERSION file contains a different numeric value.

Dependencies between components are taken into account by build-config: some components may depend on others. Dependencies may be either strong (if a dependency component is missing, then the dependent component cannot be built) or optional. Optional dependencies typically handle plugins that can be absent, or parts of a project that can be condidionally compiled.

Version change step

This step and corresponding commandline options are meant only for us. Don't use them.

Configuration step

The configuration step creates the build tree and the needed subdirectories in the build tree. For projects with a compilation step (C and C++ projects), a configuration file is processed and written in the build tree. This configuration file is meant for maker and summaries in project file variables all the compilation options, including libraries the project depends on, optional compilation flags and macros, etc. Then configure is called to generate appropriate Makefiles.

Once done and up to date, the configuration step can be avoided: use the --no-configure commandline option to disable it. To re-enable it (for a specific component, for instance), use the --configure option.

Compilation step

The compilation step is normally merely a matter of running make in the build subtree of each component. This step can be done by hand by experts without the help of build-config, once the configuration is done and up to date, to recompile a sub-part of the programs.

The compilation step can be disabled: to do so, use the --no-build commandline option. To re-enable it (for a specific component, for instance), use the --build option.

Documentation generation step

The documentation step is not performed by default. To enable it, use the --doc commandline option. To disable it again (for a specific component, for instance), use the --no-doc option.

For now, three different documentation tools are known and used by build-config if they are detected on the building system:

  • doxygen for C or C++ sources
  • epydoc for python modules (either as python sources or compiled modules)
  • buildDoc for DocBook XML documentation. This tool in turn uses other XML tools to perform HTML and/or PDF documents generation.

All documentation is generated in the build tree, in the share/doc directory. Subdirectories are created there for each project.

Packaging step

Packaging consists in copying all files of the required components in an installable directory tree, and making it ready to use. A setup program is bundled with the package. The packaging step is (of course) not performed in normal use, and is triggered via the --pack option.

The package directory is normally created in the current directory, but build-config can create it anywhere else if the --packdir option is used (for instance: --packdir /tmp.

Other options control some aspects of packaging:

optiondescription
--packname basename to assign to a package, [default: cartopack]
--packversion version to assign to a package, [default: current date]
--tar / --no-tar tar/zip the package, [default: yes]
--i2bm build a I2BM-specific package, [default: no].
In a I2BM package, the package files filter are changed, and all our private and development programs are also shipped with the package (this means, well, no, we do not provide everything in the public downloadable packages; but almost everything, I promise).

Developing new projects using build-config

New projects may use the build-config dependency and build system. In this case, the project source directory name must match the new component name, and a ".bcg" file ("dot Build-Config") is looked for and included in build-config: it must be a Python source file which defines a new class inheriting the Component class.

The source code of build-config is a complete mess, it needs to be re-written, but we just don't have time for it, so for now, as long as it works... But as a consequence it may be unclear to find out how to make a complex new component. Just stay simple, and follow examples...

A simple example is the "MyProject" sample project, which is an almost empty project, only defining a source tree and appropriate config files. It defines no new library but only commandlines, and depends on AimsData.

To be continued... A complete doc would take several pages.