This lesson is still being designed and assembled (Pre-Alpha version)

The Package CMakeLists.txt

Overview

Teaching: 20 min
Exercises: 20 min
Questions
  • How do I compile my package?

Objectives
  • Use ATLAS CMake macros to specify an executable and library targets.

  • Add ATLAS packages as dependencies.

In this section, we will write two CMakeLists.txt files; one for the JetSelectionHelper package and one for the AnalysisPayload package. The contents will tell CMake how to compile each package. The former will teach you how to define a library and the latter how to define an executable program.

The approach we will take is to slowly construct the CMakeLists.txt incrementaly adding blocks and building each time. Quite often, this will result in an error. We will then analyze the error and implement the next block that fixes it.

Compiling JetSelectionHelper

Start by creating a new file at source/JetSelectionHelper/CMakeLists.txt with the following contents. The ATLAS_SUBDIR line identifies your directory as an ATLAS package with the name JetSelectionHelper.

# The name of the package
ATLAS_SUBDIR(JetSelectionHelper)

Let’s see what this will do. At this point, you need to run cmake build again for CMake to learn about the new CMakeLists.txt file. After this, you only need to run cmake --build to process any changes.

cmake build
cmake --build build
# Boring CMake output
Scanning dependencies of target Package_JetSelectionHelper_tests
[  0%] Built target Package_JetSelectionHelper_tests
Scanning dependencies of target atlas_tests
[  0%] Built target atlas_tests
Scanning dependencies of target Package_JetSelectionHelper
[100%] Built package JetSelectionHelper
JetSelectionHelper: Package build succeeded
[100%] Built target Package_JetSelectionHelper

You can see that now the package is being picked up by make. Great! However your binary is not being compiled. Not so great. This is because we have not defined what should be compile using what source code. This is done using the ATLAS_ADD_LIBRARY command. It is the equivalent of the standard CMake ADD_LIBRARY command, but with convenience added in for handling dependencies.

Add the following line to tell CMake that you want to compile a library called JetSelectionHelperLib using the source file src/JetSelectionHelper.cxx. It also copies your header files, that will be used by other packages depending on JetSelectionHelperLib (ie: AnalysisPayload) to a central place.

# Add binary
ATLAS_ADD_LIBRARY ( JetSelectionHelperLib JetSelectionHelper/JetSelectionHelper.h src/JetSelectionHelper.cxx
		  PUBLIC_HEADERS JetSelectionHelper )

Let’s see what this will do. Note that you only need to run cmake --build build this time. CMake already knows about your JetSelectionHelper/CMakeLists.txt from the previous step, allowing the build command to automatically look for updates.

cmake --build build
Scanning dependencies of target JetSelectionHelperHeaderInstall
[ 25%] Generating ../x86_64-centos7-gcc8-opt/include/JetSelectionHelper
[ 25%] Built target JetSelectionHelperHeaderInstall
Scanning dependencies of target JetSelectionHelperLib
[ 50%] Building CXX object JetSelectionHelper/CMakeFiles/JetSelectionHelperLib.dir/src/JetSelectionHelper.cxx.o
In file included from /home/kkrizka/Bootcamp/v1-gitlab-finished-code/source/JetSelectionHelper/src/JetSelectionHelper.cxx:1:
/home/kkrizka/Bootcamp/v1-gitlab-finished-code/source/JetSelectionHelper/JetSelectionHelper/JetSelectionHelper.h:1:10: fatal error: xAODJet/Jet.h: No such file or directory
 #include "xAODJet/Jet.h"
          ^~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [JetSelectionHelper/CMakeFiles/JetSelectionHelperLib.dir/src/JetSelectionHelper.cxx.o] Error 1
make[1]: *** [JetSelectionHelper/CMakeFiles/JetSelectionHelperLib.dir/all] Error 2
make: *** [all] Error 2

Here we have our first error, fatal error: xAODJet/Jet.h: No such file or directory , telling us that we are missing something. Without any arguments, ATLAS_ADD_LIBRARY thinks that our library does not depend on any extra packages. But we are using quite a few central packages, like xAODJet for storing the jet representation. To find the name of the package, just look at the directory where the header file is stored.

The dependency can be added by using the LINK_LIBRARIES option with a list of packages. Update the call to ATLAS_ADD_LIBRARY to look like this:

ATLAS_ADD_LIBRARY ( JetSelectionHelperLib JetSelectionHelper/JetSelectionHelper.h src/JetSelectionHelper.cxx
		  PUBLIC_HEADERS JetSelectionHelper
		  LINK_LIBRARIES xAODEventInfo
				 xAODRootAccess
				 xAODJet)

Now build again and you should see it complete sucessfully.

cmake --build build
# Boring output from cmake detecting an updated and being automatically rerun
# Boring compilation output
Scanning dependencies of target JetSelectionHelperLib
[ 25%] Building CXX object JetSelectionHelper/CMakeFiles/JetSelectionHelperLib.dir/src/JetSelectionHelper.cxx.o
[ 50%] Linking CXX shared library ../x86_64-centos7-gcc8-opt/lib/libJetSelectionHelperLib.so
Detaching debug info of libJetSelectionHelperLib.so into libJetSelectionHelperLib.so.dbg
[ 50%] Built target JetSelectionHelperLib
Scanning dependencies of target JetSelectionHelperHeaderInstall
[ 75%] Generating ../x86_64-centos7-gcc8-opt/include/JetSelectionHelper
[ 75%] Built target JetSelectionHelperHeaderInstall
Scanning dependencies of target Package_JetSelectionHelper
[100%] Built package JetSelectionHelper
JetSelectionHelper: Package build succeeded
[100%] Built target Package_JetSelectionHelper

Compiling AnalysisPayload

Now that our helper library is compiled, let’s turn our attention to the executable that runs our analysis. Start by creating a CMakaLists.txt file. This time, we will use the ATLAS_ADD_EXECUTABLE command to declare an executable target. It has the same syntax as ATLAS_ADD_LIBRARY, but creates a binary instead of a library.

Try writing the CMakeLists.txt file on your own! Don’t forget that our AnalysisPayload program depends on functions from the JetSelectionHelper package.

Solution

The contents of ../source/AnalysisPayload/CMakeLists.txt should be the following:

# The name of the package
ATLAS_SUBDIR(AnalysisPayload)

# Add binary
ATLAS_ADD_EXECUTABLE ( AnalysisPayload util/AnalysisPayload.cxx
                     LINK_LIBRARIES  xAODEventInfo
                                     xAODRootAccess
                                     xAODJet
                                     JetSelectionHelperLib)

On success, you should see the following when you try to build.

cmake build
cmake --build build
# Boring CMake output
# Boring output
Scanning dependencies of target AnalysisPayload
[ 42%] Building CXX object AnalysisPayload/CMakeFiles/AnalysisPayload.dir/util/AnalysisPayload.cxx.o
[ 57%] Linking CXX executable ../x86_64-centos7-gcc8-opt/bin/AnalysisPayload
# Boring Output

Now try running it. Note that the executable is in your PATH, so you can call it directly. Prefereably from within your run/ directory.

# Run from run/ directory
AnalysisPayload

We now have a working package! It is a good time to checkpoint and commit all of your changes.

Key Points

  • Use ATLAS macros. They specify a structure to your build/ directory that makes your life easy!