Evolution of ROOT’s CMake Build System
G. Amadio for the ROOT Team
ROOT Data Analysis Framework https://root.cern Installing ROOT What’s the easiest way to install ROOT?
▶ Linux ● Arch 6.14/02 → https://aur.archlinux.org/packages/root ● CentOS 6.14/02 → https://fedoraproject.org/wiki/EPEL ● Fedora 6.14/04 → https://apps.fedoraproject.org/packages/root ● Gentoo 6.14/04 → https://packages.gentoo.org/packages/sci-physics/root ● Ubuntu 6.14/04 → https://root.cern.ch/content/release-61404 ▶ Mac OS X ● Homebrew 6.14/02 → https://formulae.brew.sh/formula/root ▶ Windows ● Preview binaries 6.14/04 → https://root.cern.ch/content/release-61402
G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 3 I need to customize ROOT to my needs!
# Install dependencies from your OS # An up to date list for your distro can be found in # https://github.com/root-project/root-docker $ git clone http://root.cern/git/root.git -b v6-14-04 $ mkdir build && cd build $ cmake ../root -DCMAKE_CXX_FLAGS=”-march=native” [...] $ cmake --build .
G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 4 Anaconda and ROOT
▶ Avoid building ROOT with Anaconda if you can ▶ Many people use system GCC to compile against Anaconda Python ▶ C++ ABI of your system libraries and Anaconda may differ ▶ libPyROOT.so needs to link to C++ standard library and Python ▶ Bad experience and sadness, because the two are not compatible
G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 5 How to install ROOT with Anaconda?
▶ Install GCC from Anaconda and use that to build ROOT ▶ Do not mix system with Anaconda packages ▶ Ensure no ROOT dependencies come from your system ▶ Set PYTHONPATH, PATH, etc, to use Anaconda ▶ It’s not ROOT’s fault it’s difficult to make this work!
Do not mix system + anaconda dependencies, pick everything from only one of them, including Python and the compiler itself
G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 6 ROOT is also available on CVMFS
▶ LCG Releases — http://lcginfo.cern.ch/pkg/ROOT ● All the work has already been done for you ● Just source the right setup script ● source /cvmfs/sft.cern.ch/lcg/views/LCG_93/
G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 7 Modern CMake 9 10 Motivation
▶ Reduce complexity of the build system ▶ Make it easier to maintain for developers ▶ Make it easier to understand for contributors ▶ Improve experience of those who need to build ROOT ▶ Improve modularization of the project ▶ Improve performance when running CMake
G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 11 Modern CMake Resources
▶ Daniel Pfiffer’s talk at cppcon https://www.youtube.com/watch?v=bsXLMQ6WgIk ▶ Manuel Binna’s Gist on Modern CMake https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1 ▶ An Introduction to Modern CMake https://cliutils.gitlab.io/modern-cmake ▶ Kitware’s Blog on CMake Superbuilds https://blog.kitware.com/cmake-superbuilds-git-submodules
G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 12 What is modern CMake?
▶ Available starting with CMake 3.0 ▶ Think in targets rather than variables ▶ Treat CMake code like production code, it is code afterall ▶ Keep off CMAKE_CXX_FLAGS and don’t use custom variables ▶ Don’t abuse usage requirements: -Wall is not a requirement ▶ Forget global commands like include_directories, link_directories, link_libraries, etc ▶ Write a
G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 13 How is ROOT doing?
▶ Available starting with CMake 3.0 ✔ ▶ Think in targets rather than variables ✔ ▶ Treat CMake code like production code, it is code afterall ✔ ▶ Keep off CMAKE_CXX_FLAGS and don’t use custom variables ✘ ▶ Don’t abuse usage requirements: -Wall is not a requirement ✘ ▶ Forget global commands like include_directories, link_directories, link_libraries, etc ✘ ▶ Write a
G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 14 What is modern CMake?
▶ Put CI-specific settings in CTest scripts, not in the project
▶ Use exported targets of external packages when available
▶ Write a Find
▶ Do not use file(GLOB), but watch out for CONFIGURE_DEPENDS
▶ Use toolchain files to support cross compilation
G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 15 How is ROOT doing?
▶ Put CI-specific settings in CTest scripts, not in the project ✘
▶ Use exported targets of external packages when available ✔
▶ Write a Find
▶ Do not use file(GLOB), but watch out for CONFIGURE_DEPENDS ✔
▶ Use toolchain files to support cross compilation ✘
G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 16 Future Plans Things that we want to improve
▶ Follow the filesystem hierarchy standard
▶ Make it easier to install and use multiple versions of ROOT
▶ Do not mix ExternalProject_Add and regular CMake targets
▶ Wrap find_package for builtins and use add_subdirectory with same effect
▶ Do not rely on ROOTSYS, LD_LIBRARY_PATH, etc
▶ Reduce complexity of configuration options (all=ON, fail-on-missing)
▶ Increase modularity of ROOT’s sub-packages
▶ Avoid usage from the build directory, install instead, and test install
G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 18 Better macros to generate dictionaries
▶ ROOT already has ROOT_STANDARD_LIBRARY_PACKAGE function
● Creates library with rootcling dictionary attached
▶ Current CMake functions to generate dictionary are not optimal
● Generate dictionary sources (.cxx files) from headers
● Use generated sources to add into call to add_library
● Cannot inherit target properties (e.g. include directories) from the library target ▶ Add new add_dictionary macro that can be used after library target is created
● Create library target with add_library
● Generate dictionary using target properties of library target
● Add dictionary source to the library target with target_sources
G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 19 Example usage for ROOT’s Davix Library
cmake_minimum_required(VERSION 3.6 FATAL_ERROR) list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules) option(BUILD_SHARED_LIBS "Build shared libraries" ON)
find_package(Davix 0.6.7 REQUIRED) find_package(ROOT 6.14 REQUIRED COMPONENTS RIO Net)
include(ROOTMacros) # contains add_dictionary function
add_library(RDAVIX TDavixFile.cxx TDavixSystem.cxx) target_link_libraries(RDAVIX PUBLIC Davix::Davix ROOT::Net ROOT::RIO)
add_dictionary(TARGET RDAVIX HEADERS TDavixFile.h TDavixSystem.h LINKDEF LinkDef.h)
Example available at https://gitlab.cern.ch/amadio/root-davix
G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 20 Future dictionary generation functions
▶ Proof of concept for now ▶ Need to further discuss interface, installation ▶ Target 6.16/00 for integration into ROOT ▶ Becomes usable by dependent projects ▶ Use similar style in ROOT to make packages independent
G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 21 Summary
▶ ROOT is moving towards modern CMake
▶ Future macros will make it easier for dependent projects to use ROOT
● Find ROOT and use compatible settings
● Create libraries with dictionaries
▶ More modularity
● Allow parts of ROOT to be updated without rebuilding ROOT
● Faster development
▶ New CMake super build to simplify process of building ROOT
▶ Making an effort to make ROOT available in official distribution channels
G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 22 Backup slides New add_dictionary function
function(add_dictionary) cmake_parse_arguments(G "" "TARGET;LINKDEF" "HEADERS;OPTIONS" "${ARGN}") set(G_DEFINES "$
target_include_directories(${G_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(${G_TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/G_${G_TARGET}.cxx BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/G_${G_TARGET}.cxx DEPENDS ${G_HEADERS} COMMAND ${ROOT_rootcling_CMD} -f ${CMAKE_CURRENT_BINARY_DIR}/G_${G_TARGET}.cxx ${G_OPTIONS} "$<$
G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 24