KaliVeda
Toolkit for HIC analysis
Appendix: KaliVeda build system

The following is a detailed description of the CMake build system used by KaliVeda.

The build system uses CMake. The top-level CMakeLists.txt file handles the building and installation of:

  • each subproject directory (e.g. KVMultiDet/, FAZIA/, ...) and the associated libraries;
  • the stand-alone executables in the execs/ directory;
  • the configuration files for the different libraries (top-level etc/ directory and etc/ directory in each subproject

Only out-of-source builds are supported. Specific CMake modules used to build KaliVeda, find other packages, generate ROOT dictionaries, etc. etc., are in the cmake/ directory. Various tools for developers are in the tools/ directory.

Top-level cmake options

The list of options which can be used to configure the build are given here, with their default values in brackets. Example of use:

$ cmake [path to source dir] -DCMAKE_INSTALL_PREFIX=[path to installation] -DUSE_FAZIA=yes -Dgnuinstall=yes
Option Default Meaning
USE_INDRA OFF build libraries for INDRA data analysis & simulation
USE_FAZIA OFF build libraries for FAZIA data analysis & simulation
USE_INDRAFAZIA OFF build libraries for INDRA-FAZIA data analysis & simulation
automatically enables USE_INDRA and USE_FAZIA
WITH_INDRA_DATASETS OFF download & install datasets for INDRA experiments
automatically enables USE_INDRA
WITH_FAZIA_DATASETS OFF download & install datasets for FAZIA experiments
automatically enables USE_FAZIA
WITH_INDRAFAZIA_DATASETS OFF download & install datasets for INDRA-FAZIA experiments
automatically enables USE_INDRAFAZIA
USE_MICROSTAT ON build libraries for generation of events with different statistical weights
see MicroStat Package
USE_FITLTG ON build Tassan-Got package for fitting identification grids (see KVTGID)
USE_BUILTIN_GRU ON build own library for reading legacy GANIL acquisition data (not MFM format)
USE_MFM ON use library for reading GANIL acquisition data in MFM format
requires mfmlib package from: https://gitlab.in2p3.fr/jdfcode/mfmlib.git
USE_PROTOBUF ON use Google protocol buffers e.g. for reading raw FAZIA data
USE_MESYTEC ON enable support for reading (INDRA) data from Mesytec DAQ electronics
requires software from: https://gitlab.in2p3.fr/mesytec-ganil/mesytec_data
USE_GEMINI ON if Gemini++ library is installed on system and can be found,
build the KVGemini interface. see Using GEMINI++ with KaliVeda for more details
USE_SQLITE ON enable SQLite database interface KVSQLite, if ROOT compiled with SQLite support
gnuinstall OFF install libraries etc. following a standard GNU directory layout
(see Installation directories below)
CCIN2P3_BUILD OFF configure build for IN2P3 Computing Centre environment

All options are handled by the top-level CMakeLists.txt file, which sets the value of variables

set(WITH_[option] yes)

which are visible in all subprojects, and can be used to control what gets built. These variables are used to set preprocessor directives in the KVConfig.h header file (see Useful C++ Pre-processor Symbols), such as

#define WITH_[option]

which can be used in any C/C++ source with #include "KVConfig.h".

Building subprojects

The subprojects (KVMultiDet, KVIndra, etc.) are each in a subdirectory of the main project. The build system for each is the same. In the top-level CMakeLists.txt file for each subproject is a call to the function

#---------------------------------------------------------------------------------------------------
#---BUILD_KALIVEDA_SUBPROJECT([IGNORE_DIRS dir1 dir2 ...])
#
#---Called by CMakeLists.txt for a KaliVeda subproject i.e. KVMultiDet, KVIndra, ...
#--- + any subdirectory with a CMakeLists.txt is treated as a source directory to be compiled
#--- + any subdirectory with a dataset.rootrc is treated as a dataset directory to be installed
#---
#---IGNORE_DIRS = source or dataset subdirectories to ignore
#---
#---Special directories:
#---etc/ : any *.rootrc files in etc/ are installed with all other configuration files in ${CMAKE_INSTALL_SYSCONFROOTDIR}
#---data/ : everything in data/ is installed in ${CMAKE_INSTALL_DATADIR}
#---examples/ : example classes & other code in examples/ is installed in ${CMAKE_INSTALL_TUTDIR}/${KVSUBPROJECT}
#---factory/ : template files for plugin classes in factory/ are installed in ${CMAKE_INSTALL_TMPLDIR}
#
#---------------------------------------------------------------------------------------------------

which is defined in cmake/KaliVedaMacros.cmake.

As indicated in the comments of the function, the subdirectories of a subproject are treated in the following way:

  • data subdirectory - if it exists, all files in data are copied to the corresponding installation directory (see Installation layout): these are data files needed by various classes, e.g. range tables, nuclear mass or lifetime tables, etc.;
  • etc subdirectory - any *.rootrc files in etc/ are installed with all other configuration files;
  • examples subdirectory - if found, any classes or programmes in this directory will be compiled after all other subdirectories but not included in any library of the subproject: this compilation is just to check that any code modifications do not break existing code. The source code of the examples is on the other hand installed in the examples directory;
  • factory subdirectory - if found, assumed to contain templates for classes which can be generated by the user, which are installed in the appropriate directory (see Installation layout).

Any subdirectory containing a dataset.rootrc file is treated as a dataset directory (containing lists of runs, systems, calibration parameters, etc. for a given experiment) and installed accordingly.

All other subdirectories, if not ignored (by IGNORE_DIRS), are treated as modules of the subproject, from which we build the module libraries {see Subproject modules).

Extra include paths

The call to BUILD_KALIVEDA_SUBPROJECT may be preceded by a call to KALIVEDA_SET_INCLUDE_DIRS in order to augment the search paths for header files used by all modules of this subproject to include those of a previously compiled subproject:

KALIVEDA_SET_INCLUDE_DIRS([other_subproject] MODULES [mod1 mod2 ...])

which is defined in cmake/KaliVedaMacros.cmake and takes the arguments:

  • [other_subproject] - name of previously-built subproject to which the modules belong -KVMultiDet, FAZIA, etc.)
  • MODULES [mod1 mod2 ...] - the list of modules in [other_subproject] where header files are located

Subproject modules

Each module subdirectory contains:

  • class source code (.h and .cpp files);
  • LinkDef.h file for dictionary generation
  • CMakeLists.txt file for the module

The CMakeLists.txt file contains a call to the function

BUILD_KALIVEDA_MODULE([name] PARENT [subproject]
                      [KVMOD_DEPENDS kvmod1 kvmod2...] [EXTRA_LIBS lib1 lib2...] 
                      [DICT_EXCLUDE toto.h titi.h ...] [LIB_EXCLUDE Class1 Class2...]
                     )

which is defined in cmake/KaliVedaMacros.cmake, and which takes the mandatory arguments:

  • [name] - name of the module, usually the name of the subdirectory
  • PARENT [subproject] - name of the subproject to which the module belongs

The call to BUILD_KALIVEDA_MODULE may be preceded by a call to KALIVEDA_SET_INCLUDE_DIRS in order to augment the search paths for header files used by this module (see Extra include paths).

The optional arguments of BUILD_KALIVEDA_MODULE are:

  • [KVMOD_DEPENDS kvmod1 kvmod2...] - list of other modules in the same subproject on which this module depends (i.e. uses one or more classes defined in those modules). This list determines the order in which the modules of the subproject are built: if geometry depends on base and stopping, those two modules will have to be built first before geometry can be built. Note that adding a module to this list automatically adds its directory to the include search path for .h files.
  • [EXTRA_LIBS lib1 lib2...] - list of any module library targets outside of the current subproject on which this module depends (see Library target names). Obviously the subproject and module in question must be built before this one. The module library will be dynamically linked to these targets. Note that the corresponding directories are not automatically added to the include search path for .h files: it may be necessary to add a call to KALIVEDA_SET_INCLUDE_DIRS (see Extra include paths).
  • [DICT_EXCLUDE toto.h titi.h ...] - any header files in the module directory which should not be used for dictionary generation. By default, all .h files in the directory are used, along with the LinkDef.h file.
  • [LIB_EXCLUDE Class1 Class2...] - classes to be excluded from the build, they will not be compiled, and autmatically excluded from dictionary generation (no need to add e.g. Class1.h to DICT_EXCLUDE argument). Note that the names of the classes are used, without .cpp|.h file extension.

Useful build variables

During the build some global cmake variables are set/incremented with the following information:

  • KALIVEDA_SUBPROJ_LIST - list of all subprojects in current build
  • KALIVEDA_LIB_LIST - the list of all library targets of all built subprojects
  • KALIVEDA_CONF_FILES - list of configuration files found in all etc directories
  • [subproject]_MOD_LIST - the list of all modules in [subproject]
  • [subproject]_LIB_LIST - the list of all library targets for [subproject] (see Library target names)
  • [subproject]_EXFUNCS - list of all examples for [subproject]
  • [subproject]_EXFUNCS_[name]_FILE - source file for example [name] in [subproject]
  • [subproject]_EXFUNCS_[name]_DESC - description of example [name] in [subproject]

Library target names

Each library corresponding to a given module in a subproject has a CMake target name (which can be used e.g. for linking with the library) of the form:

[subproject][module]

and the corresponding shared library will be called

lib[subproject][module].so

For example, for the module base in subproject KVMultiDet the library name is libKVMultiDetbase.so and the CMake target for linking with this library is KVMultiDetbase.

Module dependencies

We try to be as conservative as possible when determining the dependencies of each module, in order to declare only the strict minimum of dependencies. This is to avoid circular dependencies (which would stop the build), and also to optimise the speed of building in parallel mode (i.e. doing make -jN with N>1). This is true concerning intra-subproject dependencies (i.e. argument list KVMOD_DEPENDS), and also dependencies on modules in other subprojects (argument EXTRA_LIBS).

For example, here is the CMakeLists.txt file for KVIndra/calibration:

BUILD_KALIVEDA_MODULE(calibration
    PARENT ${KVSUBPROJECT}
    EXTRA_LIBS KVMultiDetcalibration KVMultiDetexp_events
)

It depends on the libraries for modules calibration and exp_events in the (previously compiled) subproject KVMultiDet. Note that the include paths to find headers in all KVMultiDet modules are set in the top-level CMakeLists.txt of the KVIndra subproject, so there is no need to call KALIVEDA_SET_INCLUDE_HEADERS (see Extra include paths). We could have (lazily) made this module depend on all of the KVMultiDet libraries, by replacing the EXTRA_LIBS line above with

EXTRA_LIBS ${KVMultiDet_LIB_LIST}

as KVMultiDet_LIB_LIST contains the names of all module library targets for the KVMultiDet subproject (see Useful build variables). But in this case, parallel builds would be less efficient, as the whole KVMultiDet subproject would need to be built before KVIndra/calibration.

Here is another example, for module FAZIA/geometry:

#---set paths to find all KVIndra headers
KALIVEDA_SET_INCLUDE_DIRS(KVIndra MODULES ${KVIndra_MOD_LIST})

BUILD_KALIVEDA_MODULE(geometry
    PARENT ${KVSUBPROJECT}
    EXTRA_LIBS KVIndraexp_events
)

The dependency on module KVIndra/exp_events requires adding the paths to find the corresponding header files using KALIVEDA_SET_INCLUDE_DIRS (see Extra include paths). The full list of modules in KVIndra is added to the search path, as the classes in KVIndra/exp_events themselves depend on classes in other modules of KVIndra, otherwise we could have used

KALIVEDA_SET_INCLUDE_DIRS(KVIndra MODULES exp_events)

Note that adding "too many" directories to the include search paths has no detrimental effect on build efficiency.

Installation layout

Depending on the option gnuinstall given to CMake (see Top-level cmake options), two installation architectures are possible. The default layout (i.e. with gnuinstall=off|no) is

bin/
etc/
examples/
include/
KVFiles/
  data/
  [dataset1]/
  [dataset2]/
  classTemplate1.{h,cpp}
  classTemplate2.{h,cpp}
lib/
man/
tools/

Note that this layout must not be used if you are installing in a read-only directory i.e. if the value of CMAKE_INSTALL_PREFIX is a system directory, because available datasets files and experimental database files which may be generated during use of KaliVeda will be written inside this installation directory.

When option gnuinstall=on|yes the installation follows near-standard GNU conventions:

bin/
include/
  kaliveda/
lib/
  kaliveda/
share/
  kaliveda/
    [dataset1]/
    [dataset2]/
    examples/
    data/
    etc/
    templates/
    man/

This type of installation can be used with system directories, e.g. /usr/local, as any files generated during use of KaliVeda are written in a user-specific "working directory" which by default is created in $HOME/.kaliveda.