From 49f3b682b2baa79c169999254546a196b18b6d42 Mon Sep 17 00:00:00 2001 From: Henry Fredrick Schreiner Date: Tue, 1 May 2018 17:18:27 +0200 Subject: [PATCH] Adding updates for ROOT --- .gitlab-ci.yml | 2 +- SUMMARY.md | 1 + chapters/packages/ROOT.md | 25 ++++++++------------- examples/CMakeLists.txt | 1 + examples/root-simple-3.11/CMakeLists.txt | 16 ++++++++++++-- examples/root-simple/CMakeLists.txt | 28 ++++++++++++++++++------ examples/root-usefile/CMakeLists.txt | 23 +++++++++++++++++++ examples/root-usefile/README.md | 10 +++++++++ examples/root-usefile/SimpleExample.cxx | 7 ++++++ 9 files changed, 87 insertions(+), 26 deletions(-) create mode 100644 examples/root-usefile/CMakeLists.txt create mode 100644 examples/root-usefile/README.md create mode 100644 examples/root-usefile/SimpleExample.cxx diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 320f263..52bb655 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,7 +10,7 @@ test_code: - mkdir -p build - cd build - cmake ../examples - - cmake --build . + - VERBOSE=1 cmake --build . - ctest - cd .. diff --git a/SUMMARY.md b/SUMMARY.md index 6a14377..0312cbb 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -35,6 +35,7 @@ * [Boost](chapters/packages/Boost.md) * [MPI](chapters/packages/MPI.md) * [ROOT](chapters/packages/ROOT.md) + * [UseFile Example](examples/root-usefile/README.md) * [Simple Example](examples/root-simple/README.md) * [Simple Example CMake 3.11+](examples/root-simple-3.11/README.md) * [Dictionary Example](examples/root-dict/README.md) diff --git a/chapters/packages/ROOT.md b/chapters/packages/ROOT.md index d369f95..6a7a3af 100644 --- a/chapters/packages/ROOT.md +++ b/chapters/packages/ROOT.md @@ -13,31 +13,24 @@ to attempt to find ROOT. If you don't have your paths set up, you can pass `-DRO ## The too-simple way -ROOT [provaides a utility](https://root.cern.ch/how/integrate-root-my-project-cmake) to set up a ROOT project, which you can activate using `include(${ROOT_USE_FILE})`. This will automatically make ugly global variables for you. It will save you a little time setting up, and will waste massive amounts of time later if you try to do anything tricky. As long as you aren't making a library, it's probably fine for simple scripts. Includes and flags are set globally, but you'll still need to link to `${ROOT_LIBRARIES}` yourself. +ROOT [provaides a utility](https://root.cern.ch/how/integrate-root-my-project-cmake) to set up a ROOT project, which you can activate using `include("${ROOT_USE_FILE}")`. This will automatically make ugly directory level and global variables for you. It will save you a little time setting up, and will waste massive amounts of time later if you try to do anything tricky. As long as you aren't making a library, it's probably fine for simple scripts. Includes and flags are set globally, but you'll still need to link to `${ROOT_LIBRARIES}` yourself, along with possibly `ROOT_EXE_LINKER_FLAGS` (You will have to `separate_arguments` first before linking or you will get an error if there are multiple flags, like on macOS). Here's what it would look like: -```cmake -cmake_minimum_required(VERSION 3.11) - -project(Simple LANGUAGES CXX) - -find_package(ROOT CONFIG REQUIRED COMPONENTS Minuit) -include("${ROOT_USE_FILE}") - -add_executable(simple simple.cxx simple.h) -target_link_libraries(simple ${ROOT_LIBRARIES}) -``` +[import:'main', lang:'cmake'](../../examples/root-usefile/CMakeLists.txt) ## The right way (Targets) -ROOT does not correctly set up it's imported targets. To fix this error, you'll need something like: +ROOT 6.12 and earlier do not add the include directory for imported targets. The latest git master has corrected this error. To fix this error for older ROOT versions, you'll need something like: -[import:'setup_properties', lang:'cmake'](../../examples/root-simple/CMakeLists.txt) +[import:'setup_includes', lang:'cmake'](../../examples/root-simple/CMakeLists.txt) + +You will also often want the compile flags and definitions: + +[import:'setup_flags', lang:'cmake'](../../examples/root-simple/CMakeLists.txt) In CMake 3.11, you can replace that last function call with: - [import:'modern_fix', lang:'cmake'](../../examples/root-simple-3.11/CMakeLists.txt) All the ROOT targets will require `ROOT::Core`, so this will be enough regardless of which ROOT targets you need. @@ -48,7 +41,7 @@ To link, just pick the libraries you want to use: ## Components -Find ROOT allows you to specify components. It will add anything you list to ${ROOT_LIBRARIES}, so you might want to build your own target using that to avoid listing the components twice. +Find ROOT allows you to specify components. It will add anything you list to ${ROOT_LIBRARIES}, so you might want to build your own target using that to avoid listing the components twice. This does not solve dependencies though; so it is an error to list `RooFit` but not `RooFitCore`. If you link to `ROOT::RooFit` instead of `${ROOT_LIBRARIES}`, then `RooFitCore` is not required. ## Dictionary generation diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index c2d9e28..8424905 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -4,6 +4,7 @@ project(ModernCMakeExamples) enable_testing() +add_subdirectory(root-usefile) add_subdirectory(root-simple) add_subdirectory(root-simple-3.11) add_subdirectory(root-dict) diff --git a/examples/root-simple-3.11/CMakeLists.txt b/examples/root-simple-3.11/CMakeLists.txt index b066590..4b64e25 100644 --- a/examples/root-simple-3.11/CMakeLists.txt +++ b/examples/root-simple-3.11/CMakeLists.txt @@ -8,14 +8,26 @@ find_package(ROOT CONFIG REQUIRED) message(STATUS "Found ROOT: ${ROOT_VERSION} at ${ROOT_DIR}") separate_arguments(ROOT_CXX_FLAGS) +separate_arguments(ROOT_DEFINITIONS) +message(STATUS "ROOT_DEFINITIONS ${ROOT_DEFINITIONS}") + +# This is required on if there is more than one flag (like on macOS) +# and this also fixes a bug in the linker flags +string(REPLACE "-L " "-L" ROOT_EXE_LINKER_FLAGS "${ROOT_EXE_LINKER_FLAGS}") +separate_arguments(ROOT_EXE_LINKER_FLAGS) ## [modern_fix] target_include_directories(ROOT::Core INTERFACE "${ROOT_INCLUDE_DIRS}") -target_compile_options(ROOT::Core INTERFACE "${ROOT_CXX_FLAGS}") + +add_library(ROOT::Flags_CXX IMPORTED INTERFACE) +target_compile_options(ROOT::Flags_CXX INTERFACE ${ROOT_CXX_FLAGS}) +target_compile_definitions(ROOT::Flags_CXX INTERFACE ${ROOT_DEFINITIONS}) +set_property(TARGET ROOT::Flags_CXX PROPERTY + INTERFACE_LINK_LIBRARIES ${ROOT_EXE_LINKER_FLAGS}) ## [modern_fix] add_executable(RootSimpleExample311 SimpleExample.cxx) -target_link_libraries(RootSimpleExample311 PUBLIC ROOT::Physics) +target_link_libraries(RootSimpleExample311 PUBLIC ROOT::Physics ROOT::Flags_CXX) ## [main] enable_testing() diff --git a/examples/root-simple/CMakeLists.txt b/examples/root-simple/CMakeLists.txt index 2e00890..308ca61 100644 --- a/examples/root-simple/CMakeLists.txt +++ b/examples/root-simple/CMakeLists.txt @@ -11,20 +11,34 @@ find_package(ROOT CONFIG REQUIRED) message(STATUS "Found ROOT: ${ROOT_VERSION} at ${ROOT_DIR}") # ROOT targets are missing includes and flags -## [setup_properties] -# Fix for ROOT_CXX_FLAGS not actually being a CMake list -separate_arguments(ROOT_CXX_FLAGS) - +## [setup_includes] set_property(TARGET ROOT::Core PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${ROOT_INCLUDE_DIRS}") -set_property(TARGET ROOT::Core APPEND PROPERTY +## [setup_includes] + +## [setup_flags] +# Fix for ROOT_CXX_FLAGS not actually being a CMake list +separate_arguments(ROOT_CXX_FLAGS) +separate_arguments(ROOT_DEFINITIONS) + +# This is required on if there is more than one flag (like on macOS) +# and this also fixes a bug in the linker flags +string(REPLACE "-L " "-L" ROOT_EXE_LINKER_FLAGS "${ROOT_EXE_LINKER_FLAGS}") +separate_arguments(ROOT_EXE_LINKER_FLAGS) + +add_library(ROOT::Flags_CXX IMPORTED INTERFACE) +set_property(TARGET ROOT::Flags_CXX APPEND PROPERTY INTERFACE_COMPILE_OPTIONS ${ROOT_CXX_FLAGS}) -## [setup_properties] +set_property(TARGET ROOT::Flags_CXX APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS ${ROOT_DEFINITIONS}) +set_property(TARGET ROOT::Flags_CXX APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${ROOT_EXE_LINKER_FLAGS}) +## [setup_flags] # Adding an exectuable program and linking to needed ROOT libraries ## [add_and_link] add_executable(RootSimpleExample SimpleExample.cxx) -target_link_libraries(RootSimpleExample PUBLIC ROOT::Physics) +target_link_libraries(RootSimpleExample PUBLIC ROOT::Physics ROOT::Flags_CXX) ## [add_and_link] ## [main] diff --git a/examples/root-usefile/CMakeLists.txt b/examples/root-usefile/CMakeLists.txt new file mode 100644 index 0000000..2df4014 --- /dev/null +++ b/examples/root-usefile/CMakeLists.txt @@ -0,0 +1,23 @@ + +## [main] +cmake_minimum_required(VERSION 3.1) + +project(RootUseFileExample LANGUAGES CXX) + +find_package(ROOT CONFIG REQUIRED) +message(STATUS "Found ROOT: ${ROOT_VERSION} at ${ROOT_DIR}") + +include("${ROOT_USE_FILE}") + +# This is required on if there is more than one flag (like on macOS) +# and this also fixes a bug in the linker flags +string(REPLACE "-L " "-L" ROOT_EXE_LINKER_FLAGS "${ROOT_EXE_LINKER_FLAGS}") +separate_arguments(ROOT_EXE_LINKER_FLAGS) + +add_executable(RootUseFileExample SimpleExample.cxx) +target_link_libraries(RootUseFileExample PUBLIC ${ROOT_LIBRARIES} ${ROOT_EXE_LINKER_FLAGS}) + +## [main] + +enable_testing() +add_test(NAME RootUseFileExample COMMAND RootUseFileExample) diff --git a/examples/root-usefile/README.md b/examples/root-usefile/README.md new file mode 100644 index 0000000..70a0d09 --- /dev/null +++ b/examples/root-usefile/README.md @@ -0,0 +1,10 @@ +# A Simple ROOT Project + +This is a minimal example of a ROOT project using the UseFile system and without a dictionary. + +#### examples/root-usefile/CMakeLists.txt +[import:'main', lang:'cmake'](CMakeLists.txt) + +#### examples/root-usefile/SimpleExample.cxx + +[import](SimpleExample.cxx) diff --git a/examples/root-usefile/SimpleExample.cxx b/examples/root-usefile/SimpleExample.cxx new file mode 100644 index 0000000..9534202 --- /dev/null +++ b/examples/root-usefile/SimpleExample.cxx @@ -0,0 +1,7 @@ +#include + +int main() { + TLorentzVector v(1,2,3,4); + v.Print(); + return 0; +}