Difference: GaudiCMakeConfiguration (1 vs. 29)

Revision 272015-10-21 - MarcoCattaneo

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 9 to 9
  The main drawbacks of CMake are the syntax of its language (not very nice looking) and the lack of support for runtime environment definition, but, thanks to the power of the language and to some home-made Python tools, we can overcome the drawbacks.
Changed:
<
<
Lately we have been developing a CMake-based infrastructure to allow building of Gaudi-based projects is a way similar to what we are used to with CMT. Here I'll describe how to write the CMake configuration for projects and packages.
>
>
Lately we have been developing a CMake-based infrastructure to allow building of Gaudi-based projects is a way similar to what we are used to with CMT. Here I'll describe how to write the CMake configuration for projects and packages. See also the CMakeFAQ
 

Understanding and Writing CMake Code

A minimal introduction on the CMake syntax and conventions is mandatory for people who never used it. Info The syntax highlighting in the code blocks is not correct because SyntaxHighlightingPlugin does not understand the CMake language.

Revision 262015-10-20 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 398 to 398
 %ENDCODE%
Added:
>
>
If you need to checkout (getpack) another package after a build, you must call make configure to ensure that CMake finds it.

make purge is also very useful to ensure that everything in the local directory is built from scratch.

If you need to use the prepared build with lb-run, you must call make install to create all the required files in InstallArea.

 
<!--/twistyPlugin twikiMakeVisibleInline-->
When using the production version of LbScripts one needs a few manual steps. In this case the same exercise as above looks like this:

Revision 252015-07-21 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 391 to 391
 make -j 6

# Test

Changed:
<
<
make test ; make QMTestSummary
>
>
make test
  # Run Gaudi ./run gaudirun.py
Line: 409 to 409
 export NB=$LHCBNIGHTLIES/lhcb-cmake/Fri . $NB/setupSearchPath.sh
Changed:
<
<
# Enamble build with CMake
>
>
# Enable build with CMake
 export USE_CMAKE=1 export CMAKE_PREFIX_PATH=$NB/GAUDI/GAUDI_HEAD/cmake:$CMAKE_PREFIX_PATH
Line: 450 to 450
 # Common environment (usually not needed, but useful in a script) . LbLogin.sh -c x86_64-slc6-gcc48-opt
Deleted:
<
<
# We need the lhcb-cmake nightly build slot export NB=$LHCBNIGHTLIES/lhcb-gaudi-head/Today . $NB/setupSearchPath.sh
 # Enable build with CMake export USE_CMAKE=1
Line: 469 to 465
 make -j 6

# Test

Changed:
<
<
make test ; make QMTestSummary
>
>
make test
  # Run Gaudi build.$CMTCONFIG/run gaudirun.py

Revision 222015-01-22 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 91 to 91
  The first one (toolchain.cmake) is generic (same content for all projects) and is usually generated by getpack, except for a few cases. The code is available at https://svnweb.cern.ch/trac/lhcb/browser/LbScripts/trunk/LbUtils/data/toolchain.cmake.
Added:
>
>
 The second one (CMakeLists.txt) is the main configuration file. It starts with some boilerplate code needed for bootstrapping: %CODE{"sh" num="1"}%
Line: 106 to 107
 
line 5
load the Gaudi CMake modules and functions used later in this file and in the configuration of the packages
Empty lines and lines starting with # are ignored.
Changed:
<
<
This preamble is followed by the function call that declares the project name and version, the dependencies on other projects and the required data packages with an optional version pattern. For example, we can take the configuration of the LHCb project:
>
>
This preamble is followed by the function call that declares the project name and version, the dependencies on other projects and the required data packages with an optional version pattern. For example:
  %CODE{"sh" num="1"}% # Declare project name and version
Changed:
<
<
gaudi_project(LHCb v36r4 USE Gaudi v24r2 DATA Gen/DecFiles Det/SQLDDDB VERSION v7r* FieldMap PRConfig RawEventFormat TCK/HltTCK TCK/L0TCK VERSION v4r*)
>
>
gaudi_project(MyProject v36r4 USE BaseProject v24r2 AnotherBase v5r15 DATA Some/DataPkg SpecialDatPkg VERSION v7r* MoreData)
 %ENDCODE%
line 2
we call the function gaudi_project passing as first two arguments the project name and the version (in the format vXrY[pZ] or the special value HEAD), Note that the following lines are all arguments passed to gaudi_project, until the ) character.
line 3
we start the list of the dependencies on other projects with the keyword USE; the projects have to be specified as a list of pairs name and version (e.g. USE Lbcom v13r6p1 Rec v14r6)
Changed:
<
<
line 4
the keyword DATA defines the start of the optional list of required data packages; each data package is specified by its name, optionally followed by the keyword VERSION and a glob pattern used to select the allowed versions (if the VERSION is not specified, we assume any version)
>
>
line 5
the keyword DATA defines the start of the optional list of required data packages; each data package is specified by its name, optionally followed by the keyword VERSION and a glob pattern used to select the allowed versions (if the VERSION is not specified, we assume any version)
  The current project (and all the subdirectrories it contains) will have access to all the libraries built in the projects it depends on and will have access to the data packages required (via the environment variables defined there).
Line: 152 to 151
  Kernel/LHCbMath) %ENDCODE%
Added:
>
>
 Warning, important gaudi_depends_on_subdirs is only needed to hint to CMake about the order in which it should consider the subdirectories, but this is (in principle) not needed and will be dropped as soon as the correct dependencies discovery will be in place (see LBCORE-226).

What usually follows is a list of external software packages we need to build the targets in the current subdirectory (e.g. ROOT, Boost, etc.). While the functions encountered so far are Gaudi-specific (as the gaudi_ prefix suggests), the code to use external packages is standard CMake code:

Revision 212015-01-22 - AnatolySolomin

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 9 to 9
  The main drawbacks of CMake are the syntax of its language (not very nice looking) and the lack of support for runtime environment definition, but, thanks to the power of the language and to some home-made Python tools, we can overcome the drawbacks.
Changed:
<
<
Lately we have been developing a CMake-based infrastructure to allow building of Gaudi-based projects is a way similar to that we are used to with CMT. Here I'll describe how to write the CMake configuration for projects and packages.
>
>
Lately we have been developing a CMake-based infrastructure to allow building of Gaudi-based projects is a way similar to what we are used to with CMT. Here I'll describe how to write the CMake configuration for projects and packages.
 

Understanding and Writing CMake Code

A minimal introduction on the CMake syntax and conventions is mandatory for people who never used it. Info The syntax highlighting in the code blocks is not correct because SyntaxHighlightingPlugin does not understand the CMake language.
Line: 205 to 205
 

Building a Module (AKA component library)

A module is a container of components of the Gaudi Plugin System, and probably is the most common build target in Gaudi projects (technically speaking it is a shared library that is loaded at run-time).
Changed:
<
<
The declaration that a subdirectory provides for a module is much similar to that of a library:
>
>
The declaration that a subdirectory provides for a module is quite similar to that of a library:
  %CODE{"sh" num="off"}% gaudi_add_module(MyAnalysisAlgs
Line: 322 to 322
 Info Other types of tests are available, but at the moment QMTest is the most powerful option.

Building ROOT Dictionaries

Changed:
<
<
Either to use them in for persistency or interactivity purposes, the creation of ROOT dictionaries can be requested with code like (from GaudiKernel):
>
>
Either to use them for persistency or interactivity purposes, the creation of ROOT dictionaries can be requested with code like (from GaudiKernel):
  %CODE{"sh" num="off"}% gaudi_add_dictionary(GaudiKernel dict/dictionary.h dict/dictionary.xml

Revision 202015-01-21 - AnatolySolomin

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 14 to 14
 

Understanding and Writing CMake Code

A minimal introduction on the CMake syntax and conventions is mandatory for people who never used it. Info The syntax highlighting in the code blocks is not correct because SyntaxHighlightingPlugin does not understand the CMake language.
Changed:
<
<
In CMake every statement is a function call, written as an identifier followed by optional spaces and the arguments to the function as a space-separated list enclosed by parentheses. The arguments to a function can span over several lines and double quotes (") can be used to pass arguments containing spaces and new-lines.
>
>
In CMake every statement is a function call, written as an identifier followed by optional spaces and the arguments to the function as a space-separated list enclosed in parentheses. The arguments to a function can span over several lines, and double quotes (") can be used to pass arguments containing spaces and new-lines.
 Examples of functions: %CODE{"sh"}%
Line: 50 to 50
 %ENDCODE%
Changed:
<
<
Dereferencing of variables can be nested and works also inside between double quotes:
>
>
Dereferencing of variables can be nested and works also in between double quotes:
  %CODE{"sh"}% set(name MyName)
Line: 59 to 59
 %ENDCODE%
Changed:
<
<
There is something special in the way CMake functions are invoked. CMake functions and macros (similar to functions) accept a variable number of arguments and the only separators between arguments are spaces (tabs and new-lines too), so it might not be obvious how to pass optional arguments (like it's done in Python with named arguments). The solution found by CMake developers is to use keyword separated lists of arguments. For example we can imagine a function that requires a mandatory argument name and two optional lists of files, C sources and C++ sources. In CMake you could find it invoked like this:
>
>
There is something special in the way CMake functions are invoked. CMake functions and macros (similar to functions) accept variable number of arguments and the only separators between arguments are spaces (tabs and new-lines too), so it might not be obvious how to pass optional arguments (like it's done in Python with named arguments). The solution found by CMake developers is to use keyword-separated lists of arguments. For example, we can imagine a function that requires a mandatory argument name and two optional lists of files, C sources and C++ sources. In CMake you could find it invoked like this:
  %CODE{"sh"}% make_a_library(MyLibrary)
Line: 85 to 85
 
  • subdirectory (package) configuration

Project Configuration

Changed:
<
<
At the top level directory of a project there must be two file:
>
>
At the top level directory of a project there must be two files:
 
  • toolchain.cmake
  • CMakeLists.txt
Line: 106 to 106
 
line 5
load the Gaudi CMake modules and functions used later in this file and in the configuration of the packages
Empty lines and lines starting with # are ignored.
Changed:
<
<
This preamble is followed by the function call that declares the project name and version, the dependencies on other projects and the required data packages with an optional version pattern. For example we can take the configuration of the LHCb project:
>
>
This preamble is followed by the function call that declares the project name and version, the dependencies on other projects and the required data packages with an optional version pattern. For example, we can take the configuration of the LHCb project:
  %CODE{"sh" num="1"}% # Declare project name and version
Line: 123 to 123
 
line 2
we call the function gaudi_project passing as first two arguments the project name and the version (in the format vXrY[pZ] or the special value HEAD), Note that the following lines are all arguments passed to gaudi_project, until the ) character.
line 3
we start the list of the dependencies on other projects with the keyword USE; the projects have to be specified as a list of pairs name and version (e.g. USE Lbcom v13r6p1 Rec v14r6)
Changed:
<
<
line 4
the keyword DATA defines the start of the optional list of required data packages; each data package is specified by its name, optionally followed by the keyword VERSION and a glob pattern used to select the allowed versions (if the VERSION is not specified we assume any version)
>
>
line 4
the keyword DATA defines the start of the optional list of required data packages; each data package is specified by its name, optionally followed by the keyword VERSION and a glob pattern used to select the allowed versions (if the VERSION is not specified, we assume any version)
 
Changed:
<
<
The current project (and all the subdirectrories it contains) will have access to all the libraries built in the projects it depends on will have access to the data packages required (via the environment variables there defined).
>
>
The current project (and all the subdirectrories it contains) will have access to all the libraries built in the projects it depends on and will have access to the data packages required (via the environment variables defined there).
 
Changed:
<
<
When using the getpack tool to check out the project from the software repository, you will also find a file called Makefile that simplify the interaction with CMake.
>
>
When using the getpack tool to check out the project from the software repository, you will also find a file called Makefile that simplifies the interaction with CMake.
 

Subdirectory Configuration

A subdirectory (also called package) is a directory inside the project top directory that contains a configuration file (CMakeLists.txt) containing build instructions and the source files used in the build, header files or scripts to be installed, etc.
Line: 152 to 152
  Kernel/LHCbMath) %ENDCODE%
Changed:
<
<
Warning, important gaudi_depends_on_subdirs is only needed to hint to CMake about the order in which it should consider the subdirectories, but this is (in principle) not needed and will we be dropped as soon as the correct dependencies discovery will be in place (see LBCORE-226).
>
>
Warning, important gaudi_depends_on_subdirs is only needed to hint to CMake about the order in which it should consider the subdirectories, but this is (in principle) not needed and will be dropped as soon as the correct dependencies discovery will be in place (see LBCORE-226).
 
Changed:
<
<
What usually follow is a list of external software packages we need to build the targets in the current subdirectory (e.g. ROOT, Boost, etc.). While the functions encountered so far are Gaudi-specific (as the gaudi_ prefix suggests), the code to use external packages is standard CMake code:
>
>
What usually follows is a list of external software packages we need to build the targets in the current subdirectory (e.g. ROOT, Boost, etc.). While the functions encountered so far are Gaudi-specific (as the gaudi_ prefix suggests), the code to use external packages is standard CMake code:
 
<!-- SyntaxHighlightingPlugin -->
find_package(ROOT)
find_package(Boost COMPONENTS system)
<!-- end SyntaxHighlightingPlugin -->
Changed:
<
<
The calls to the function find_package are described in the CMake documentation, but, briefly, the lines above tell CMake to find ROOT headers and libraries (line 1) and the headers and the system library of Boost (line 2). If the calls succeed (at configuration time), CMake sets some variables to the location of required header and libraries.
>
>
The calls to the function find_package are described in the CMake documentation, but, briefly, the lines above tell CMake to find ROOT headers and libraries (line 1) and the headers and the system library of Boost (line 2). If the calls succeed (at configuration time), CMake sets some variables to the locations of required headers and libraries.
 Warning, important A call to find_package does not mean that the external package is actually used during the build: it must be explicitly mentioned when declaring the build target.

The rest of the configuration file depends on what the subdirectory contains and/or needs to build (a library, a module, Python modules, headers,...). In the following sections are described the most common use cases.

Line: 169 to 169
 

Building a Library (AKA linker library)

A library is a container of code that can be used by other libraries, applications or modules (see following sections).
Changed:
<
<
The declaration that a subdirectory provides a module looks more or less like this:
>
>
The declaration that a subdirectory provides for a library looks more or less like this:
  %CODE{"sh" num="off"}% gaudi_add_library(MyCommonCode
Line: 180 to 180
 %ENDCODE%
Changed:
<
<
The first argument of the gaudi_add_library function is the name of the module and must be unique in the current project and in all the projects this depends on. Following the arguments is a list of source files (glob patterns are allowed) that must be compiled in the module.
>
>
The first argument of the gaudi_add_library function is the name of the library and must be unique in the current project and in all the projects it depends on. The arguments that follow the name, is a list of source files (glob patterns are allowed) that must be compiled in the module.
  A library must expose header files to the source files of other build targets, which is done specifying the list of directories containing the headers after the keyword PUBLIC_HEADERS. These directories will be also installed after the build (in InstallArea//include), so that they are visible to other projects. More... Close
<!--/twistyPlugin twikiMakeVisibleInline-->
In the very unlikely case we need to produce a library that does not need to export headers we can replace the PUBLIC_HEADERS section with just the keyword NO_PUBLIC_HEADERS.
<!--/twistyPlugin-->
Line: 203 to 203
 the library Lib2 will also have access to ROOT and Boost headers and libraries (even if the libraries are declared in different subdirectories).

Building a Module (AKA component library)

Changed:
<
<
A module is a container of components of the Gaudi Plugin System, and probably the most common build target in Gaudi projects (technically speaking it is a shared library that is loaded at run-time).
>
>
A module is a container of components of the Gaudi Plugin System, and probably is the most common build target in Gaudi projects (technically speaking it is a shared library that is loaded at run-time).
 
Changed:
<
<
The declaration that a subdirectory provides a module is much similar to that of a library:
>
>
The declaration that a subdirectory provides for a module is much similar to that of a library:
  %CODE{"sh" num="off"}% gaudi_add_module(MyAnalysisAlgs

Revision 192015-01-14 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 60 to 60
 

There is something special in the way CMake functions are invoked. CMake functions and macros (similar to functions) accept a variable number of arguments and the only separators between arguments are spaces (tabs and new-lines too), so it might not be obvious how to pass optional arguments (like it's done in Python with named arguments). The solution found by CMake developers is to use keyword separated lists of arguments.

Changed:
<
<
For example we can consider a function that requires a mandatory argument name and two optional lists of files, C sources and C++ sources. In CMake you could find it invoked like this:
>
>
For example we can imagine a function that requires a mandatory argument name and two optional lists of files, C sources and C++ sources. In CMake you could find it invoked like this:
  %CODE{"sh"}% make_a_library(MyLibrary)
Line: 360 to 360
  If some changes are needed only at build or test time (i.e. they do not need to be exposed to other projects), one can use gaudu_build_env instead of gaudi_env.
Changed:
<
<
Warning, important "System" variables like PATH and PYTHONPATH should never be modified explicitly. If you need to give access to scripts or Python modules, install the with the dedicated functions.
>
>
Warning, important "System" variables like PATH and PYTHONPATH should never be modified explicitly. If you need to give access to scripts or Python modules, install them with the dedicated functions.
 

Building with CMake

Work in progress, under construction Work in Progress Work in progress, under construction (see LBCORE-12 and LBCORE-174)

Building a Package

The tools needed to easily work and build with CMake are not final yet, but there is a preliminary version in $LHCBDEV that can be tested.
Changed:
<
<
This shell (bash) script shows the required steps needed to build and test the package Phys/DaVinciTools in the context of the project Phys build in the nightly build slot lhcb-cmake.
>
>
This shell (bash) script shows the required steps needed to build and test the package Phys/DaVinciTools in the context of the project Phys build in the nightly build slot lhcb-gaudi-head.
  %CODE{"bash" num="off"}% # Prepare the local project directory
Changed:
<
<
lb-dev --name MyDevel --nightly lhcb-gaudi-head --user . Phys HEAD
>
>
lb-dev --name MyDevel --nightly lhcb-gaudi-head Phys HEAD
 cd MyDevel

# # An alternative way is: #

Changed:
<
<
# lb-dev --nightly lhcb-gaudi-head Phys HEAD
>
>
# lb-dev --nightly lhcb-gaudi-head --dest-dir $User_release_area Phys HEAD
 # cd $User_release_area/PhysDev_HEAD

# Get the packages to be built

Revision 182014-12-04 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 89 to 89
 
  • toolchain.cmake
  • CMakeLists.txt
Changed:
<
<
The first one (toolchain.cmake) is generic (same content for all projects) and can be taken from LHCb: https://svnweb.cern.ch/trac/lhcb/browser/LHCb/trunk/toolchain.cmake. (See LBCORE-326)
>
>
The first one (toolchain.cmake) is generic (same content for all projects) and is usually generated by getpack, except for a few cases. The code is available at https://svnweb.cern.ch/trac/lhcb/browser/LbScripts/trunk/LbUtils/data/toolchain.cmake.
  The second one (CMakeLists.txt) is the main configuration file. It starts with some boilerplate code needed for bootstrapping:

Revision 172014-11-23 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 448 to 448
 . LbLogin.sh -c x86_64-slc6-gcc48-opt

# We need the lhcb-cmake nightly build slot

Changed:
<
<
export NB=$LHCBNIGHTLIES/lhcb-cmake/Fri
>
>
export NB=$LHCBNIGHTLIES/lhcb-gaudi-head/$(date +%a)
 . $NB/setupSearchPath.sh
Changed:
<
<
# Enamble build with CMake
>
>
# Enable build with CMake
 export USE_CMAKE=1
Deleted:
<
<
export CMAKE_PREFIX_PATH=$NB/GAUDI/GAUDI_HEAD/cmake:$CMAKE_PREFIX_PATH
  # Checkout the project cd $User_release_area
Changed:
<
<
getpack --no-config --no-eclipse -PH DaVinci
>
>
getpack -PH DaVinci
 cd DAVINCI/DAVINCI_HEAD

# Edit the dependencies to use the correct versions

Revision 162014-11-19 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 371 to 371
  %CODE{"bash" num="off"}%
Deleted:
<
<
# Start a shell (bash) with the environment for the CMake-enabled dev tools $LHCBDEV/cmake-dev # Alternatively, you can use the boring "source setup" way with: # . $LHCBDEV/LBSCRIPTS/LBSCRIPTS_sp2/InstallArea/scripts/LbLogin.sh
 # Prepare the local project directory
Changed:
<
<
lb-dev --name MyDevel --nightly lhcb-cmake Phys HEAD cd $User_release_area/MyDevel
>
>
lb-dev --name MyDevel --nightly lhcb-gaudi-head --user . Phys HEAD cd MyDevel

# # An alternative way is: # # lb-dev --nightly lhcb-gaudi-head Phys HEAD # cd $User_release_area/PhysDev_HEAD

  # Get the packages to be built getpack Phys/DaVinciTools trunk

Revision 152014-05-26 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 381 to 381
 cd $User_release_area/MyDevel

# Get the packages to be built

Changed:
<
<
getpack --no-config --no-eclipse Phys/DaVinciTools trunk
>
>
getpack Phys/DaVinciTools trunk
  # Build make -j 6
Line: 390 to 390
 make test ; make QMTestSummary

# Run Gaudi

Changed:
<
<
build.$CMTCONFIG/run gaudirun.py
>
>
./run gaudirun.py
 %ENDCODE%

Revision 142014-05-15 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 371 to 371
  %CODE{"bash" num="off"}%
Changed:
<
<
# Environment for the CMake-enabled dev tools . $LHCBDEV/LBSCRIPTS/LBSCRIPTS_sp2/InstallArea/scripts/LbLogin.sh -c x86_64-slc6-gcc48-opt
>
>
# Start a shell (bash) with the environment for the CMake-enabled dev tools $LHCBDEV/cmake-dev # Alternatively, you can use the boring "source setup" way with: # . $LHCBDEV/LBSCRIPTS/LBSCRIPTS_sp2/InstallArea/scripts/LbLogin.sh
  # Prepare the local project directory lb-dev --name MyDevel --nightly lhcb-cmake Phys HEAD

Revision 132014-05-13 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 366 to 366
 Work in progress, under construction Work in Progress Work in progress, under construction (see LBCORE-12 and LBCORE-174)

Building a Package

Changed:
<
<
The tools needed to easily work and build with CMake are not ready yet, so to be able to develop, build and test a package a few manual steps are needed.
>
>
The tools needed to easily work and build with CMake are not final yet, but there is a preliminary version in $LHCBDEV that can be tested.
 This shell (bash) script shows the required steps needed to build and test the package Phys/DaVinciTools in the context of the project Phys build in the nightly build slot lhcb-cmake.
Added:
>
>
<!-- SyntaxHighlightingPlugin -->
# Environment for the CMake-enabled dev tools
. $LHCBDEV/LBSCRIPTS/LBSCRIPTS_sp2/InstallArea/scripts/LbLogin.sh -c x86_64-slc6-gcc48-opt

# Prepare the local project directory
lb-dev --name MyDevel --nightly lhcb-cmake Phys HEAD
cd $User_release_area/MyDevel

# Get the packages to be built
getpack --no-config --no-eclipse Phys/DaVinciTools trunk

# Build
make -j 6

# Test
make test ; make QMTestSummary

# Run Gaudi
build.$CMTCONFIG/run gaudirun.py
<!-- end SyntaxHighlightingPlugin -->

<!--/twistyPlugin twikiMakeVisibleInline-->
When using the production version of LbScripts one needs a few manual steps. In this case the same exercise as above looks like this:
  %CODE{"bash" num="off"}% # Common environment (usually not needed, but useful in a script)
Line: 409 to 435
 build.$CMTCONFIG/run gaudirun.py %ENDCODE%
Added:
>
>
<!--/twistyPlugin-->
 

Building a Project

To build a whole project is a bit simpler than with a single package (still, improvements can and will be made).

Revision 112014-02-10 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 362 to 362
  Warning, important "System" variables like PATH and PYTHONPATH should never be modified explicitly. If you need to give access to scripts or Python modules, install the with the dedicated functions.
Changed:
<
<

Building a Project

>
>

Building with CMake

 Work in progress, under construction Work in Progress Work in progress, under construction (see LBCORE-12 and LBCORE-174)
Added:
>
>

Building a Package

 The tools needed to easily work and build with CMake are not ready yet, so to be able to develop, build and test a package a few manual steps are needed. This shell (bash) script shows the required steps needed to build and test the package Phys/DaVinciTools in the context of the project Phys build in the nightly build slot lhcb-cmake.
Line: 400 to 401
  # Build make -j 6
Added:
>
>
# Test make test ; make QMTestSummary

# Run Gaudi build.$CMTCONFIG/run gaudirun.py %ENDCODE%

Building a Project

To build a whole project is a bit simpler than with a single package (still, improvements can and will be made). %CODE{"bash" num="off"}% # Common environment (usually not needed, but useful in a script) . LbLogin.sh -c x86_64-slc6-gcc48-opt

# We need the lhcb-cmake nightly build slot export NB=$LHCBNIGHTLIES/lhcb-cmake/Fri . $NB/setupSearchPath.sh

# Enamble build with CMake export USE_CMAKE=1 export CMAKE_PREFIX_PATH=$NB/GAUDI/GAUDI_HEAD/cmake:$CMAKE_PREFIX_PATH

# Checkout the project cd $User_release_area getpack --no-config --no-eclipse -PH DaVinci cd DAVINCI/DAVINCI_HEAD

# Build make -j 6

  # Test make test ; make QMTestSummary

Revision 102014-01-20 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 386 to 386
 cd MyDevel

# Get the packages to be built

Changed:
<
<
getpack --no-config Phys/DaVinciTools trunk # (this is because we need a fix in getpack) rm -fr .svn CMakeLists.txt toolchain.cmake
>
>
getpack --no-config --no-eclipse Phys/DaVinciTools trunk
  # CMake configuration of the local project cp $NB/LHCB/LHCB_HEAD/{toolchain.cmake,Makefile} .

Revision 92013-12-13 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 134 to 134
  All the configuration files of the subdirectories should start with the declaration of the version of the package with something like (taken from Kernel/LHCbKernel):
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 ################################################################################ # Package: LHCbKernel ################################################################################
Line: 145 to 145
  After the declaration of the version we can optionally declare dependencies on other subdirectories with a call to gaudi_depends_on_subdirs, passing to it the list of packages that should be build before this one:
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 gaudi_depends_on_subdirs(GaudiAlg GaudiKernel GaudiObjDesc
Line: 156 to 156
  What usually follow is a list of external software packages we need to build the targets in the current subdirectory (e.g. ROOT, Boost, etc.). While the functions encountered so far are Gaudi-specific (as the gaudi_ prefix suggests), the code to use external packages is standard CMake code:
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 find_package(ROOT) find_package(Boost COMPONENTS system) %ENDCODE%
Line: 171 to 171
  The declaration that a subdirectory provides a module looks more or less like this:
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 gaudi_add_library(MyCommonCode src/*.cpp PUBLIC_HEADERS MyHeaders
Line: 188 to 188
 Optionally, one can specify a list of include directories (after the INCLUDE_DIRS keyword) and of libraries (after LINK_LIBRARIES) needed to compile and link the module. INCLUDE_DIRS accepts paths to directories and names of external packages (found with calls to find_package) which are automatically converted to the list of include directories. LINK_LIBRARIES, similar to INCLUDE_DIRS, accepts paths to libraries and names of external packages, plus names of libraries built in other subdirectories of the current (or required) projects, in which case the other subdirectories must be specified in the gaudi_depends_on_subdirs call. It should be noted that when linking against a library produced in a subdirectory of a Gaudi project, the include directories required by that library are added automatically to the include path (without having to specify them in the INCLUDE_DIRS section). For example, in the code:
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 gaudi_add_library(Lib1 src/lib1/*.cpp PUBLIC_HEADERS Lib1Hdrs
Line: 207 to 207
  The declaration that a subdirectory provides a module is much similar to that of a library:
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 gaudi_add_module(MyAnalysisAlgs src/*.cpp INCLUDE_DIRS Boost ROOT
Line: 224 to 224
 

Installing Headers (without a library)

Sometimes a subdirectory provides public headers but not a library (e.g. for interfaces, purely inlined classes, etc.). In this case we cannot install the headers directory via the PUBLIC_HEADERS argument of gaudi_add_library, but we can use the function gaudi_install_headers:
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 gaudi_install_headers(MyHeaders) %ENDCODE%
Line: 233 to 233
 

Using GaudiObjDesc (LHCb-specific)

Subdirectories using GaudiObjDesc to generate classes from XML files need to first load the GaudiObjDesc CMake functions:
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 # the subdirectory GaudiObjDesc shuold be loaded before this one gaudi_depends_on_subdirs(GaudiObjDesc) # load the GaudiObjDesc CMake module
Line: 242 to 242
  then, assuming that the XML files are in the directory xml, the headers should be created in the directory Event and that we want the dictionaries for the generated classes, we can use a command like:
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 god_build_dictionary(xml/*.xml HEADERS_DESTINATION Event LINK_LIBRARIES GaudiKernel LHCbKernel)
Line: 253 to 253
 
  • generate public headers, but no dictionary
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 god_build_headers(xml/*.xml DESTINATION Event) %ENDCODE%

  • generate private headers
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 god_build_headers(xml/*.xml PRIVATE) %ENDCODE%

  • generate public headers and a dictionary extending existing dictionary files (example from Kernel/LHCbKernel)
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 god_build_dictionary(xml/*.xml HEADERS_DESTINATION Kernel EXTEND dict/LHCbKernelDict.h
Line: 279 to 279
 Info For compatibility with the old build system the following two uses are equivalent:
  • new style
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 god_build_dictionary(xml/*.xml HEADERS_DESTINATION Event LINK_LIBRARIES GaudiKernel LHCbKernel)
Line: 287 to 287
 
  • old style
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 god_build_headers(xml/*.xml DESTINATION Event) god_build_dictionary(xml/*.xml HEADERS_DESTINATION Event
Line: 298 to 298
 

Installing Python Modules

When a subdirectory contains a python directory with Python modules that should be installed to be accessible to other subdirectories and projects, the CMakeLists.txt file should include the line:
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 gaudi_install_python_modules() %ENDCODE%
Line: 306 to 306
 

Installing Scripts

Similar to the case of Python modules, scripts in the directory scripts can be installed with the dedicated command:
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 gaudi_install_scripts() %ENDCODE%
Line: 314 to 314
 

Declaring Tests (QMTest)

When a subdirectory contains the directory tests/qmtest with QMTest tests (see GaudiTestingInfrastructure), CMake should be informed with the line:
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 gaudi_add_test(QMTest QMTEST) %ENDCODE%
Line: 324 to 324
 

Building ROOT Dictionaries

Either to use them in for persistency or interactivity purposes, the creation of ROOT dictionaries can be requested with code like (from GaudiKernel):
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 gaudi_add_dictionary(GaudiKernel dict/dictionary.h dict/dictionary.xml LINK_LIBRARIES GaudiKernel) %ENDCODE%
Line: 333 to 333
 

Building Executables

It is relatively uncommon in a Gaudi project to produce executables, but it can be done with the command gaudi_add_executable which uses the same arguments of gaudi_add_module, as in
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 gaudi_add_executable(mySpecialCommand src/*.cpp INCLUDE_DIRS Boost
Line: 345 to 345
 

Manipulating the Environment

Although it should be avoided as much as possible, it might be needed to set or modify environment variables. It can be done with the function gaudi_env:
Changed:
<
<
%CODE{"sh" num="1"}%
>
>
%CODE{"sh" num="off"}%
 gaudi_env(SET var1 value2 PREPEND my_path some_path UNSET unneeded_var)
Line: 363 to 363
 Warning, important "System" variables like PATH and PYTHONPATH should never be modified explicitly. If you need to give access to scripts or Python modules, install the with the dedicated functions.

Building a Project

Changed:
<
<
TODO
>
>
Work in progress, under construction Work in Progress Work in progress, under construction (see LBCORE-12 and LBCORE-174)

The tools needed to easily work and build with CMake are not ready yet, so to be able to develop, build and test a package a few manual steps are needed. This shell (bash) script shows the required steps needed to build and test the package Phys/DaVinciTools in the context of the project Phys build in the nightly build slot lhcb-cmake. %CODE{"bash" num="off"}% # Common environment (usually not needed, but useful in a script) . LbLogin.sh -c x86_64-slc6-gcc48-opt

# We need the lhcb-cmake nightly build slot export NB=$LHCBNIGHTLIES/lhcb-cmake/Fri . $NB/setupSearchPath.sh

# Enamble build with CMake export USE_CMAKE=1 export CMAKE_PREFIX_PATH=$NB/GAUDI/GAUDI_HEAD/cmake:$CMAKE_PREFIX_PATH

# Prepare the local project directory cd $User_release_area mkdir MyDevel cd MyDevel

# Get the packages to be built getpack --no-config Phys/DaVinciTools trunk # (this is because we need a fix in getpack) rm -fr .svn CMakeLists.txt toolchain.cmake

# CMake configuration of the local project cp $NB/LHCB/LHCB_HEAD/{toolchain.cmake,Makefile} . cat > CMakeLists.txt <<EOF CMAKE_MINIMUM_REQUIRED(VERSION 2.8.5) find_package(GaudiProject)

gaudi_project(MyDevel HEAD USE Phys HEAD) EOF

# Build make -j 6

 
Changed:
<
<
-- MarcoClemencic - 12 Dec 2013
>
>
# Test make test ; make QMTestSummary

# Run Gaudi build.$CMTCONFIG/run gaudirun.py %ENDCODE%

 
Changed:
<
<
<!--
, read by CMake to prepare the low level instructions for the native build system
-->
>
>
-- MarcoClemencic - 13 Dec 2013

Revision 82013-12-12 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 183 to 183
 The first argument of the gaudi_add_library function is the name of the module and must be unique in the current project and in all the projects this depends on. Following the arguments is a list of source files (glob patterns are allowed) that must be compiled in the module.
Changed:
<
<
A library must expose header files to the source files of other build targets, which is done specifying the list of directories containing the headers after the keyword PUBLIC_HEADERS. These directories will be also installed after the build, so that they are visible to other projects. More... Close
<!--/twistyPlugin twikiMakeVisibleInline-->
In the very unlikely case we need to produce a library that does not need to export headers we can replace the PUBLIC_HEADERS section with just the keyword NO_PUBLIC_HEADERS.
<!--/twistyPlugin-->
>
>
A library must expose header files to the source files of other build targets, which is done specifying the list of directories containing the headers after the keyword PUBLIC_HEADERS. These directories will be also installed after the build (in InstallArea//include), so that they are visible to other projects. More... Close
<!--/twistyPlugin twikiMakeVisibleInline-->
In the very unlikely case we need to produce a library that does not need to export headers we can replace the PUBLIC_HEADERS section with just the keyword NO_PUBLIC_HEADERS.
<!--/twistyPlugin-->
  Optionally, one can specify a list of include directories (after the INCLUDE_DIRS keyword) and of libraries (after LINK_LIBRARIES) needed to compile and link the module. INCLUDE_DIRS accepts paths to directories and names of external packages (found with calls to find_package) which are automatically converted to the list of include directories. LINK_LIBRARIES, similar to INCLUDE_DIRS, accepts paths to libraries and names of external packages, plus names of libraries built in other subdirectories of the current (or required) projects, in which case the other subdirectories must be specified in the gaudi_depends_on_subdirs call. It should be noted that when linking against a library produced in a subdirectory of a Gaudi project, the include directories required by that library are added automatically to the include path (without having to specify them in the INCLUDE_DIRS section). For example, in the code:
Line: 220 to 220
 
  • a module cannot be used in the LINK_LIBRARIES section of a target declaration
  • the plugin system of Gaudi is not able to find and load components from libraries
Deleted:
<
<

Installing Python Modules

 
Changed:
<
<

Installing Headers (headers-only subdirectory)

>
>

Installing Headers (without a library)

Sometimes a subdirectory provides public headers but not a library (e.g. for interfaces, purely inlined classes, etc.). In this case we cannot install the headers directory via the PUBLIC_HEADERS argument of gaudi_add_library, but we can use the function gaudi_install_headers:
<!-- SyntaxHighlightingPlugin -->
    1gaudi_install_headers(MyHeaders)
<!-- end SyntaxHighlightingPlugin -->
where MyHeaders is the directory containing the headers, like in the case of PUBLIC_HEADERS.
 

Using GaudiObjDesc (LHCb-specific)

Added:
>
>
Subdirectories using GaudiObjDesc to generate classes from XML files need to first load the GaudiObjDesc CMake functions:
<!-- SyntaxHighlightingPlugin -->
    1# the subdirectory GaudiObjDesc shuold be loaded before this one
    2gaudi_depends_on_subdirs(GaudiObjDesc)
    3# load the GaudiObjDesc CMake module
    4include(GaudiObjDesc)
<!-- end SyntaxHighlightingPlugin -->
then, assuming that the XML files are in the directory xml, the headers should be created in the directory Event and that we want the dictionaries for the generated classes, we can use a command like:
<!-- SyntaxHighlightingPlugin -->
    1god_build_dictionary(xml/*.xml
    2                     HEADERS_DESTINATION Event
    3                     LINK_LIBRARIES GaudiKernel LHCbKernel)
<!-- end SyntaxHighlightingPlugin -->

There are other possible use cases in which we use GaudiObjDesc:

  • generate public headers, but no dictionary
<!-- SyntaxHighlightingPlugin -->
    1god_build_headers(xml/*.xml DESTINATION Event)
<!-- end SyntaxHighlightingPlugin -->

  • generate private headers
<!-- SyntaxHighlightingPlugin -->
    1god_build_headers(xml/*.xml PRIVATE)
<!-- end SyntaxHighlightingPlugin -->

  • generate public headers and a dictionary extending existing dictionary files (example from Kernel/LHCbKernel)
<!-- SyntaxHighlightingPlugin -->
    1god_build_dictionary(xml/*.xml
    2                     HEADERS_DESTINATION Kernel
    3                     EXTEND dict/LHCbKernelDict.h
    4                     INCLUDE_DIRS ROOT Boost
    5                     LINK_LIBRARIES ROOT Boost GaudiKernel GaudiObjDescLib LHCbMathLib LHCbKernel)
<!-- end SyntaxHighlightingPlugin -->

Info For compatibility with the old build system the following two uses are equivalent:

  • new style
<!-- SyntaxHighlightingPlugin -->
    1god_build_dictionary(xml/*.xml
    2                     HEADERS_DESTINATION Event
    3                     LINK_LIBRARIES GaudiKernel LHCbKernel)
<!-- end SyntaxHighlightingPlugin -->
  • old style
<!-- SyntaxHighlightingPlugin -->
    1god_build_headers(xml/*.xml DESTINATION Event)
    2god_build_dictionary(xml/*.xml
    3                     HEADERS_DESTINATION Event
    4                     LINK_LIBRARIES GaudiKernel LHCbKernel)
<!-- end SyntaxHighlightingPlugin -->

Installing Python Modules

When a subdirectory contains a python directory with Python modules that should be installed to be accessible to other subdirectories and projects, the CMakeLists.txt file should include the line:
<!-- SyntaxHighlightingPlugin -->
    1gaudi_install_python_modules()
<!-- end SyntaxHighlightingPlugin -->

Installing Scripts

Similar to the case of Python modules, scripts in the directory scripts can be installed with the dedicated command:
<!-- SyntaxHighlightingPlugin -->
    1gaudi_install_scripts()
<!-- end SyntaxHighlightingPlugin -->

Declaring Tests (QMTest)

When a subdirectory contains the directory tests/qmtest with QMTest tests (see GaudiTestingInfrastructure), CMake should be informed with the line:
<!-- SyntaxHighlightingPlugin -->
    1gaudi_add_test(QMTest QMTEST)
<!-- end SyntaxHighlightingPlugin -->

Info Other types of tests are available, but at the moment QMTest is the most powerful option.

Building ROOT Dictionaries

Either to use them in for persistency or interactivity purposes, the creation of ROOT dictionaries can be requested with code like (from GaudiKernel):
<!-- SyntaxHighlightingPlugin -->
    1gaudi_add_dictionary(GaudiKernel dict/dictionary.h  dict/dictionary.xml
    2                     LINK_LIBRARIES GaudiKernel) 
<!-- end SyntaxHighlightingPlugin -->
 

Building Executables

Added:
>
>
It is relatively uncommon in a Gaudi project to produce executables, but it can be done with the command gaudi_add_executable which uses the same arguments of gaudi_add_module, as in
<!-- SyntaxHighlightingPlugin -->
    1gaudi_add_executable(mySpecialCommand
    2                     src/*.cpp
    3                     INCLUDE_DIRS Boost
    4                     LINK_LIBRARIES Boost)
<!-- end SyntaxHighlightingPlugin -->
which will build the executable mySpecialCommand.exe.

Manipulating the Environment

Although it should be avoided as much as possible, it might be needed to set or modify environment variables. It can be done with the function gaudi_env:
<!-- SyntaxHighlightingPlugin -->
    1gaudi_env(SET var1 value2
    2          PREPEND my_path some_path
    3          UNSET unneeded_var)
<!-- end SyntaxHighlightingPlugin -->
The sub-commands of gaudi_env are:
  • SET
  • UNSET
  • PREPEND
  • APPEND
  • REMOVE
 
Changed:
<
<

Declaring Tests

>
>
If some changes are needed only at build or test time (i.e. they do not need to be exposed to other projects), one can use gaudu_build_env instead of gaudi_env.
 
Added:
>
>
Warning, important "System" variables like PATH and PYTHONPATH should never be modified explicitly. If you need to give access to scripts or Python modules, install the with the dedicated functions.
 

Building a Project

Added:
>
>
TODO
 
Changed:
<
<
-- MarcoClemencic - 11 Dec 2013
>
>
-- MarcoClemencic - 12 Dec 2013
 
<!--
, read by CMake to prepare the low level instructions for the native build system

Revision 72013-12-11 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 166 to 166
  The rest of the configuration file depends on what the subdirectory contains and/or needs to build (a library, a module, Python modules, headers,...). In the following sections are described the most common use cases.
Added:
>
>

Building a Library (AKA linker library)

A library is a container of code that can be used by other libraries, applications or modules (see following sections).

The declaration that a subdirectory provides a module looks more or less like this:

<!-- SyntaxHighlightingPlugin -->
    1gaudi_add_library(MyCommonCode
    2                  src/*.cpp
    3                  PUBLIC_HEADERS MyHeaders
    4                  INCLUDE_DIRS Boost ROOT
    5                  LINK_LIBRARIES Boost ROOT RecEvent TrackEvent GaudiAlgLib)
<!-- end SyntaxHighlightingPlugin -->

The first argument of the gaudi_add_library function is the name of the module and must be unique in the current project and in all the projects this depends on. Following the arguments is a list of source files (glob patterns are allowed) that must be compiled in the module.

A library must expose header files to the source files of other build targets, which is done specifying the list of directories containing the headers after the keyword PUBLIC_HEADERS. These directories will be also installed after the build, so that they are visible to other projects. More... Close

<!--/twistyPlugin twikiMakeVisibleInline-->
In the very unlikely case we need to produce a library that does not need to export headers we can replace the PUBLIC_HEADERS section with just the keyword NO_PUBLIC_HEADERS.
<!--/twistyPlugin-->

Optionally, one can specify a list of include directories (after the INCLUDE_DIRS keyword) and of libraries (after LINK_LIBRARIES) needed to compile and link the module. INCLUDE_DIRS accepts paths to directories and names of external packages (found with calls to find_package) which are automatically converted to the list of include directories. LINK_LIBRARIES, similar to INCLUDE_DIRS, accepts paths to libraries and names of external packages, plus names of libraries built in other subdirectories of the current (or required) projects, in which case the other subdirectories must be specified in the gaudi_depends_on_subdirs call. It should be noted that when linking against a library produced in a subdirectory of a Gaudi project, the include directories required by that library are added automatically to the include path (without having to specify them in the INCLUDE_DIRS section). For example, in the code:

<!-- SyntaxHighlightingPlugin -->
    1gaudi_add_library(Lib1
    2                  src/lib1/*.cpp
    3                  PUBLIC_HEADERS Lib1Hdrs
    4                  INCLUDE_DIRS Boost ROOT
    5                  LINK_LIBRARIES Boost ROOT)
    6gaudi_add_library(Lib2
    7                  src/lib2/*.cpp
    8                  PUBLIC_HEADERS Lib2Hdrs
    9                  LINK_LIBRARIES Lib1)
<!-- end SyntaxHighlightingPlugin -->
the library Lib2 will also have access to ROOT and Boost headers and libraries (even if the libraries are declared in different subdirectories).
 

Building a Module (AKA component library)

A module is a container of components of the Gaudi Plugin System, and probably the most common build target in Gaudi projects (technically speaking it is a shared library that is loaded at run-time).
Changed:
<
<
The declaration that a subdirectory provides a module looks more or less like this:
>
>
The declaration that a subdirectory provides a module is much similar to that of a library:
  %CODE{"sh" num="1"}% gaudi_add_module(MyAnalysisAlgs src/*.cpp INCLUDE_DIRS Boost ROOT
Changed:
<
<
LINK_LIBRARIES Boost ROOT HltEvent L0Event RecEvent TrackEvent GaudiAlgLib)
>
>
LINK_LIBRARIES Boost ROOT RecEvent TrackEvent GaudiAlgLib)
 %ENDCODE%
Added:
>
>
where the function is now gaudi_add_module, to which we cannot pass the keyword PUBLIC_HEADERS.

It should be taken into account that there are other differences between a library and a module. In particular:

  • a module cannot be used in the LINK_LIBRARIES section of a target declaration
  • the plugin system of Gaudi is not able to find and load components from libraries

Installing Python Modules

Installing Headers (headers-only subdirectory)

Using GaudiObjDesc (LHCb-specific)

Building Executables

Declaring Tests

 

Building a Project

Revision 62013-12-11 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 154 to 154
  Warning, important gaudi_depends_on_subdirs is only needed to hint to CMake about the order in which it should consider the subdirectories, but this is (in principle) not needed and will we be dropped as soon as the correct dependencies discovery will be in place (see LBCORE-226).
Changed:
<
<

Common Section

>
>
What usually follow is a list of external software packages we need to build the targets in the current subdirectory (e.g. ROOT, Boost, etc.). While the functions encountered so far are Gaudi-specific (as the gaudi_ prefix suggests), the code to use external packages is standard CMake code:
<!-- SyntaxHighlightingPlugin -->
    1find_package(ROOT)
    2find_package(Boost COMPONENTS system)
<!-- end SyntaxHighlightingPlugin -->
The calls to the function find_package are described in the CMake documentation, but, briefly, the lines above tell CMake to find ROOT headers and libraries (line 1) and the headers and the system library of Boost (line 2). If the calls succeed (at configuration time), CMake sets some variables to the location of required header and libraries.
Warning, important A call to find_package does not mean that the external package is actually used during the build: it must be explicitly mentioned when declaring the build target.

The rest of the configuration file depends on what the subdirectory contains and/or needs to build (a library, a module, Python modules, headers,...). In the following sections are described the most common use cases.

Building a Module (AKA component library)

A module is a container of components of the Gaudi Plugin System, and probably the most common build target in Gaudi projects (technically speaking it is a shared library that is loaded at run-time).

The declaration that a subdirectory provides a module looks more or less like this:

<!-- SyntaxHighlightingPlugin -->
    1gaudi_add_module(MyAnalysisAlgs
    2                 src/*.cpp
    3                 INCLUDE_DIRS Boost ROOT
    4                 LINK_LIBRARIES Boost ROOT HltEvent L0Event RecEvent TrackEvent GaudiAlgLib)
<!-- end SyntaxHighlightingPlugin -->
 

Building a Project

-- MarcoClemencic - 11 Dec 2013

Revision 52013-12-11 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 82 to 82
 

CMake Configuration of a Gaudi-based Project

The configuration of a project is divided in two main concerns:
  • project configuration
Changed:
<
<
  • package configuration
>
>
  • subdirectory (package) configuration
 

Project Configuration

At the top level directory of a project there must be two file:
Line: 122 to 122
 %ENDCODE%
line 2
we call the function gaudi_project passing as first two arguments the project name and the version (in the format vXrY[pZ] or the special value HEAD), Note that the following lines are all arguments passed to gaudi_project, until the ) character.
Changed:
<
<
line 3
we start the argument
>
>
line 3
we start the list of the dependencies on other projects with the keyword USE; the projects have to be specified as a list of pairs name and version (e.g. USE Lbcom v13r6p1 Rec v14r6)
line 4
the keyword DATA defines the start of the optional list of required data packages; each data package is specified by its name, optionally followed by the keyword VERSION and a glob pattern used to select the allowed versions (if the VERSION is not specified we assume any version)
 
Changed:
<
<
A project
>
>
The current project (and all the subdirectrories it contains) will have access to all the libraries built in the projects it depends on will have access to the data packages required (via the environment variables there defined).
  When using the getpack tool to check out the project from the software repository, you will also find a file called Makefile that simplify the interaction with CMake.
Changed:
<
<

Package Configuration

>
>

Subdirectory Configuration

A subdirectory (also called package) is a directory inside the project top directory that contains a configuration file (CMakeLists.txt) containing build instructions and the source files used in the build, header files or scripts to be installed, etc.

All the configuration files of the subdirectories should start with the declaration of the version of the package with something like (taken from Kernel/LHCbKernel):

<!-- SyntaxHighlightingPlugin -->
    1################################################################################
    2# Package: LHCbKernel
    3################################################################################
    4gaudi_subdir(LHCbKernel v14r3)
<!-- end SyntaxHighlightingPlugin -->
Where we call the function gaudi_subdir passing to it the name of the subdirectory/package and its version.
 
Added:
>
>
After the declaration of the version we can optionally declare dependencies on other subdirectories with a call to gaudi_depends_on_subdirs, passing to it the list of packages that should be build before this one:
<!-- SyntaxHighlightingPlugin -->
    1gaudi_depends_on_subdirs(GaudiAlg
    2                         GaudiKernel
    3                         GaudiObjDesc
    4                         Kernel/LHCbMath)
<!-- end SyntaxHighlightingPlugin -->
Warning, important gaudi_depends_on_subdirs is only needed to hint to CMake about the order in which it should consider the subdirectories, but this is (in principle) not needed and will we be dropped as soon as the correct dependencies discovery will be in place (see LBCORE-226).
 
Added:
>
>

Common Section

 

Building a Project

-- MarcoClemencic - 11 Dec 2013

Revision 42013-12-11 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 59 to 59
 %ENDCODE%
Added:
>
>
There is something special in the way CMake functions are invoked. CMake functions and macros (similar to functions) accept a variable number of arguments and the only separators between arguments are spaces (tabs and new-lines too), so it might not be obvious how to pass optional arguments (like it's done in Python with named arguments). The solution found by CMake developers is to use keyword separated lists of arguments. For example we can consider a function that requires a mandatory argument name and two optional lists of files, C sources and C++ sources. In CMake you could find it invoked like this:
<!-- SyntaxHighlightingPlugin -->
make_a_library(MyLibrary)

make_a_library(MyLibrary C_SOURCES file1.c file2.c file3.c)

make_a_library(MyLibrary CXX_SOURCES file1.cpp file2.cpp file3.cpp)

make_a_library(MyLibrary
               C_SOURCES file1.c file2.c file3.c
               CXX_SOURCES file1.cpp file2.cpp file3.cpp)
<!-- end SyntaxHighlightingPlugin -->
 Warning, important Function names are case-insensitive, but variable names are case sensitive as well as string comparison.
Added:
>
>
 

CMake Configuration of a Gaudi-based Project

The configuration of a project is divided in two main concerns:
  • project configuration

Revision 32013-12-11 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 11 to 11
  Lately we have been developing a CMake-based infrastructure to allow building of Gaudi-based projects is a way similar to that we are used to with CMT. Here I'll describe how to write the CMake configuration for projects and packages.
Added:
>
>

Understanding and Writing CMake Code

A minimal introduction on the CMake syntax and conventions is mandatory for people who never used it. Info The syntax highlighting in the code blocks is not correct because SyntaxHighlightingPlugin does not understand the CMake language.

In CMake every statement is a function call, written as an identifier followed by optional spaces and the arguments to the function as a space-separated list enclosed by parentheses. The arguments to a function can span over several lines and double quotes (") can be used to pass arguments containing spaces and new-lines. Examples of functions:

<!-- SyntaxHighlightingPlugin -->
message("hello world!")

if(1 GREATER 0)
  message("this is true")
else()
  message("this is false")
endif()
<!-- end SyntaxHighlightingPlugin -->

One can add comments to the code using # at the beginning of the comment text (spaces preceding # are ignored), like, e.g., in Unix shells and Python:

<!-- SyntaxHighlightingPlugin -->
# I'm a comment
if(TRUE)
     # this is always printed
     message("it's true")
else()
     # this is never printed
     message("it's false")
endif()
<!-- end SyntaxHighlightingPlugin -->

The CMake language supports variables, which are set with the function set and dereferenced with ${...}, e.g.:

<!-- SyntaxHighlightingPlugin -->
set(MyMessage "hello world")
message(${MyMessage})
<!-- end SyntaxHighlightingPlugin -->

Dereferencing of variables can be nested and works also inside between double quotes:

<!-- SyntaxHighlightingPlugin -->
set(name MyName)
set(${name}_msg "This is ${name}")
message(${${name}_msg})
<!-- end SyntaxHighlightingPlugin -->

Warning, important Function names are case-insensitive, but variable names are case sensitive as well as string comparison.

 

CMake Configuration of a Gaudi-based Project

The configuration of a project is divided in two main concerns:
  • project configuration
Line: 21 to 71
 
  • toolchain.cmake
  • CMakeLists.txt
Changed:
<
<
The first one (toolchain.cmake) is generic (same content for all projects) and can be taken from LHCb: https://svnweb.cern.ch/trac/lhcb/browser/LHCb/trunk/toolchain.cmake.
>
>
The first one (toolchain.cmake) is generic (same content for all projects) and can be taken from LHCb: https://svnweb.cern.ch/trac/lhcb/browser/LHCb/trunk/toolchain.cmake. (See LBCORE-326)
  The second one (CMakeLists.txt) is the main configuration file. It starts with some boilerplate code needed for bootstrapping:
Line: 34 to 84
 #--------------------------------------------------------------- %ENDCODE%
Added:
>
>
line 1
mandatory declaration to ensure that the version of CMake being used is recent enough
line 5
load the Gaudi CMake modules and functions used later in this file and in the configuration of the packages
Empty lines and lines starting with # are ignored.

This preamble is followed by the function call that declares the project name and version, the dependencies on other projects and the required data packages with an optional version pattern. For example we can take the configuration of the LHCb project:

<!-- SyntaxHighlightingPlugin -->
    1# Declare project name and version
    2gaudi_project(LHCb v36r4
    3              USE Gaudi v24r2
    4              DATA Gen/DecFiles
    5                   Det/SQLDDDB VERSION v7r*
    6                   FieldMap
    7                   PRConfig
    8                   RawEventFormat
    9                   TCK/HltTCK
   10                   TCK/L0TCK VERSION v4r*)
<!-- end SyntaxHighlightingPlugin -->
line 2
we call the function gaudi_project passing as first two arguments the project name and the version (in the format vXrY[pZ] or the special value HEAD), Note that the following lines are all arguments passed to gaudi_project, until the ) character.
line 3
we start the argument
 
Added:
>
>
A project
  When using the getpack tool to check out the project from the software repository, you will also find a file called Makefile that simplify the interaction with CMake.

Revision 22013-12-11 - MarcoClemencic

Line: 1 to 1
 
META TOPICPARENT name="LHCbComputing"
Line: 23 to 23
  The first one (toolchain.cmake) is generic (same content for all projects) and can be taken from LHCb: https://svnweb.cern.ch/trac/lhcb/browser/LHCb/trunk/toolchain.cmake.
Changed:
<
<
The second one (CMakeLists.txt) is the main configuration file, read by CMake to prepare the low level instruction for the
>
>
The second one (CMakeLists.txt) is the main configuration file. It starts with some boilerplate code needed for bootstrapping:
<!-- SyntaxHighlightingPlugin -->
    1CMAKE_MINIMUM_REQUIRED(VERSION 2.8.5)
    2
    3#---------------------------------------------------------------
    4# Load macros and functions for Gaudi-based projects
    5find_package(GaudiProject)
    6#---------------------------------------------------------------
    7
<!-- end SyntaxHighlightingPlugin -->
 
Line: 35 to 45
 

Building a Project

-- MarcoClemencic - 11 Dec 2013

Added:
>
>
<!--
, read by CMake to prepare the low level instructions for the native build system
-->
 \ No newline at end of file

Revision 12013-12-11 - MarcoClemencic

Line: 1 to 1
Added:
>
>
META TOPICPARENT name="LHCbComputing"

Introduction

CMake is an Open Source, cross-platform configuration and build tool used in several projects around the world.

Among its advantages we can count the support that comes from a large user base and the CMake configuration language that doubles as a portable and powerful scripting language.

The main drawbacks of CMake are the syntax of its language (not very nice looking) and the lack of support for runtime environment definition, but, thanks to the power of the language and to some home-made Python tools, we can overcome the drawbacks.

Lately we have been developing a CMake-based infrastructure to allow building of Gaudi-based projects is a way similar to that we are used to with CMT. Here I'll describe how to write the CMake configuration for projects and packages.

CMake Configuration of a Gaudi-based Project

The configuration of a project is divided in two main concerns:
  • project configuration
  • package configuration

Project Configuration

At the top level directory of a project there must be two file:
  • toolchain.cmake
  • CMakeLists.txt

The first one (toolchain.cmake) is generic (same content for all projects) and can be taken from LHCb: https://svnweb.cern.ch/trac/lhcb/browser/LHCb/trunk/toolchain.cmake.

The second one (CMakeLists.txt) is the main configuration file, read by CMake to prepare the low level instruction for the

When using the getpack tool to check out the project from the software repository, you will also find a file called Makefile that simplify the interaction with CMake.

Package Configuration

Building a Project

-- MarcoClemencic - 11 Dec 2013

 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright & 2008-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback