Evolution of ROOT's Cmake Build System.Pdf
Total Page:16
File Type:pdf, Size:1020Kb
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/<platform>/setup.sh ▶ Gentoo Prefix on CVMFS ● Linux /cvmfs/sft.cern.ch/lcg/contrib/gentoo/linux/x86_64/startprefix ● Mac OS X /cvmfs/sft.cern.ch/lcg/contrib/gentoo/macos/10.13/startprefix ● More information: Robust Linux Binaries, CHEP 2018, Sofia 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 <PKG>Config.cmake file for dependent projects 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 <PKG>Config.cmake file for dependent projects ✔ 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<PKG>.cmake for dependencies that don’t provide it ▶ 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<PKG>.cmake for dependencies that don’t provide it ✔ ▶ 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_PROPERTY:${G_TARGET},COMPILE_DEFINITIONS>") set(G_INCLUDES "$<TARGET_PROPERTY:${G_TARGET},INCLUDE_DIRECTORIES>") 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} "$<$<BOOL:${G_DEFINES}>:-D$<JOIN:${G_DEFINES},;-D>>" "$<$<BOOL:${G_INCLUDES}>:-I$<JOIN:${G_INCLUDES},;-I>>" ${G_HEADERS} ${G_LINKDEF} COMMAND_EXPAND_LISTS) target_sources(${G_TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/G_${G_TARGET}.cxx) endfunction() G. Amadio, Evolution of ROOT’s CMake Build System, ROOT Workshop 2018, Sarajevo 24.