# 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])