Build System

The idea behind the system is that the power of SCons should be exploited, but should be placed behind the more commonly known make. The user should be able to control the build as much as possible from the command line. The system offers ready-made configurations for different compilers in two different modes: release mode and debug mode.

By default, the configuration will be gcc in release mode. The user can configure the compiler, compiler flags et cetera by choosing one of the standard configurations, or, alternatively, the user can use any settings as desired by exporting environment variables that are listed below.

Contrary to the Makefile, users should not need to touch the SConstruct file. The developers of a project should write the SConstruct file, and it should not require any changes. Instead, it should receive its parameters from make.

Developers that want to use the CVMLCPP build system should create a Makefile and an SConstruct file, and let both use the scripts offered by CVMLCPP. An example project is given below.

Users

Pre-defined Configurations

Possible values for the configuration CNF:

  gcc  
Use g++, the C++-compiler from the Gnu Compiler Collection.
  icc  
The Intel compiler.
  open64  
The Open64 compiler.
  clang  
The clang / LLVM compiler.
  sun  
The C++ compiler of the Sun Studio. This compiler has too many bugs to compile CVMLCPP.
  watcom  
The OpenWatcom compiler. This compiler is too outdated to compile CVMLCPP.

Possible values for MODE:

  release  
Enable optimization, disable asserts. This is the default.
  debug  
Disable optimization, enable debugging symbols and asserts.

Environment Variables

Environment variables to control the build:

  CXX  
The C++ compiler to use.
  CXXFLAGS  
The compiler flags.
  LD  
The linker to use. These values will only be used if LINK is not set.
  LINK  
The linker to use. These values will override those of LD.
  LDFLAGS  
Linker flags. These values will only be used if LINKFLAGS is not set.
  LINKFLAGS  
Linker flags. These values will override those of LDFLAGS.

Examples

Default configuration:

$ make; sudo make install

Using the pre-defined configuration for the open64 compiler:

$ make CNF=open64; sudo make CNF=open64 install

Default configuration, but in debugging mode:

$ make MODE=debug; sudo make  MODE=debug install

Explicitly taking the pre-defined gcc configurationin debugging mode:

$ make CNF=gcc MODE=debug; sudo make CNF=gcc MODE=debug install

Use the environment variables to control the build:

$ export CXXFLAGS=-I/path/to/includes -Wall -Os
$ make; sudo make install

Implementors

This section shows how to incorporate the build system into your own project by means of an example.

The Makefile file of an external project, in this case a library, should be the only part users ever have to look into. Potentially users can change some settings here. It could look like this:

##########################
## Parameters for Users ##
##########################

# Install directory (used by CVMLCPP's build system)
TARGET=/where/you/want/this/software/to/be/installed

# Number of jobs to launch in parallel (used by CVMLCPP's build system)
NCPU=2

# Installation directory of CVMLCPP
export CVMLCPP_PREFIX=/where/cvmlcpp/is/currently/installed

#################################
## Users: Do not change below! ##
#################################

# The "EXTRA" parameter of this project is composed of only one thing, a
# parameter that lets users choose a backend. Valid values should be in the
# documentation of this project.
EXTRA=BACKEND=${BACKEND}

# Include the CVMLCPP build system's Makefile part
include ${CVMLCPP_PREFIX}/share/cvmlcpp/build/Makefile.build

# We need to provide our own "uninstall" target
uninstall:
	rm -f $(TARGET)/lib/libili.a $(TARGET)/lib/libili.so
	rm -rf $(TARGET)/include/ililib $(TARGET)/share/doc/ililib

In this example, the build of the software can be controlled from the command line with an extra parameter BACKEND.

As mentioned before, users should not need to touch the SConstruct file. The SConstruct file could look like this:

#####################################
## Users: Do not change this file! ##
#####################################

# Receive from Makefile: Location of CVMLCPP Installation
CVMLCPP_PREFIX = ARGUMENTS.get( 'CVMLCPP_PREFIX',   '/usr/local' )

# Have a building environment contructed by CVMLCPP build system
env = SConscript(CVMLCPP_PREFIX+'/share/cvmlcpp/build/SConscript')

# Receive from Makefile: Directory to install
TARGET = ARGUMENTS.get('TARGET', '/usr/local')

# Receive from Makefile: Which backend should we use ?
backend = ARGUMENTS.get('BACKEND', '')
if backend != '':
	if backend == 'opencv':
		env['CXXFLAGS'] += " -DUSE_OPENCV"
		if env.has_key('LIBS'):
			env['LIBS'] = [env['LIBS'], 'cv', 'highgui']
		else:
			env['LIBS'] = ['cv', 'highgui']
	else:
		if backend == 'magick':
			env['CXXFLAGS'] += " -DUSE_MAGICK"
			if env.has_key('LIBS'):
				env['LIBS'] = [env['LIBS'], 'Magick++']
			else:
				env['LIBS'] = ['Magick++']

# Magick++ is the default
env.SetDefault(LIBS = 'Magick++')


# Install Directories
TARGETLIB = TARGET + '/lib'
TARGETINC = TARGET + '/include/ililib'
TARGETDOC = TARGET + '/share/doc/ililib'

SRC    = ['src/IliLib', 'src/IliLib.hh', 'src/IliLibMagick.h',
	  'src/IliLibMagick.hh', 'src/IliLibOpenCV.h',
	  'src/IliLibToolkit', 'src/IliLibToolkit.hh',
	  'src/IliLibRaw', 'src/IliLibRaw.hh', 'src/Spot', 'src/Locator']
LIBSRC = ['src/IliLib.cc', 'src/IliLibToolkit.cc']

staticIliLib = env.StaticLibrary( 'ili', LIBSRC)
sharedIliLib = env.SharedLibrary( 'ili', LIBSRC)

env.Install( TARGETDOC, 'doc' )
env.Install( TARGETINC, SRC )
env.Install( TARGETLIB, [staticIliLib, sharedIliLib] )
env.Alias('install', [TARGETINC, TARGETLIB])