# - Finds ROOT instalation # This module sets up ROOT information # It defines: # ROOT_FOUND If the ROOT is found # ROOT_INCLUDE_DIR PATH to the include directory # ROOT_INCLUDE_DIRS PATH to the include directories (not cached) # ROOT_LIBRARIES Most common libraries # ROOT__LIBRARY Full path to the library # ROOT_LIBRARY_DIR PATH to the library directory # ROOT_DEFINITIONS Compiler definitions and flags # ROOT_LINK_FLAGS Linker flags # # The modern CMake 3 imported targets are also created: # ROOT::Libraries (Most common libraries) # ROOT:: (The library with name) # # Updated by K. Smith (ksmith37@nd.edu) to properly handle # dependencies in ROOT_GENERATE_DICTIONARY # Updated by H. Schreiner (hschrein@cern.ch) to support CMake 3 syntax find_program(ROOT_CONFIG_EXECUTABLE root-config PATHS $ENV{ROOTSYS}/bin) if(ROOT_CONFIG_EXECUTABLE) execute_process( COMMAND ${ROOT_CONFIG_EXECUTABLE} --prefix OUTPUT_VARIABLE ROOTSYS OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process( COMMAND ${ROOT_CONFIG_EXECUTABLE} --version OUTPUT_VARIABLE ROOT_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process( COMMAND ${ROOT_CONFIG_EXECUTABLE} --incdir OUTPUT_VARIABLE ROOT_INCLUDE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) set(ROOT_INCLUDE_DIRS ${ROOT_INCLUDE_DIR}) execute_process( COMMAND ${ROOT_CONFIG_EXECUTABLE} --libdir OUTPUT_VARIABLE ROOT_LIBRARY_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) set(ROOT_LIBRARY_DIRS ${ROOT_LIBRARY_DIR}) execute_process( COMMAND ${ROOT_CONFIG_EXECUTABLE} --cflags OUTPUT_VARIABLE ROOT_DEFINITIONS OUTPUT_STRIP_TRAILING_WHITESPACE) string(REGEX REPLACE "(^|[ ]*)-I[^ ]*" "" ROOT_DEFINITIONS ${ROOT_DEFINITIONS}) set(ROOT_DEF_LIST ${ROOT_DEFINITIONS}) separate_arguments(ROOT_DEF_LIST) execute_process( COMMAND ${ROOT_CONFIG_EXECUTABLE} --ldflags OUTPUT_VARIABLE ROOT_LINK_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE) set(ROOT_LINK_LIST ${ROOT_LINK_FLAGS}) separate_arguments(ROOT_LINK_LIST) # Needed because ROOT on Mac does not use Mac conventions set(CMAKE_SHARED_LIBRARY_SUFFIX .so) file(GLOB ROOT_LIBFILELIST LIST_DIRECTORIES false RELATIVE "${ROOT_LIBRARY_DIR}" "${ROOT_LIBRARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}*${CMAKE_SHARED_LIBRARY_SUFFIX}") if(NOT ROOT_LIBFILELIST) message(FATAL_ERROR "ROOT libraries not found at ${ROOT_LIBRARY_DIR}") endif() set(ROOT_ALLLIBS "") foreach(_file ${ROOT_LIBFILELIST}) string(REGEX REPLACE "^${CMAKE_SHARED_LIBRARY_PREFIX}" "" _newer ${_file}) string(REGEX REPLACE "${CMAKE_SHARED_LIBRARY_SUFFIX}$" "" _newest ${_newer}) list(APPEND ROOT_ALLLIBS ${_newest}) endforeach() set(ROOT_CORELIBS Core RIO Net Hist Graf Graf3d Gpad Tree Rint Postscript Matrix Physics MathCore Thread MultiProc) add_library(ROOT::Libraries INTERFACE IMPORTED) set(ROOT_LIBRARIES) foreach(_cpt ${ROOT_ALLLIBS}) find_library(ROOT_${_cpt}_LIBRARY ${_cpt} HINTS ${ROOT_LIBRARY_DIR}) if(ROOT_${_cpt}_LIBRARY) mark_as_advanced(ROOT_${_cpt}_LIBRARY) add_library(ROOT::${_cpt} SHARED IMPORTED) set_target_properties(ROOT::${_cpt} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${ROOT_INCLUDE_DIRS}" IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" IMPORTED_LOCATION "${ROOT_${_cpt}_LIBRARY}" INTERFACE_COMPILE_OPTIONS "$<$>:${ROOT_DEF_LIST}>" INTERFACE_LINK_LIBRARIES "${ROOT_LINK_LIST}") endif() endforeach() set(targetlist) foreach(_cpt ${ROOT_CORELIBS} ${ROOT_FIND_COMPONENTS}) if(ROOT_${_cpt}_LIBRARY) list(APPEND ROOT_LIBRARIES "${ROOT_${_cpt}_LIBRARY}") list(REMOVE_ITEM ROOT_FIND_COMPONENTS ${_cpt}) list(APPEND targetlist ROOT::${_cpt}) endif() endforeach() set_target_properties(ROOT::Libraries PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${ROOT_INCLUDE_DIRS}") set_target_properties(ROOT::Libraries PROPERTIES INTERFACE_LINK_LIBRARIES "${targetlist}") unset(targetlist) list(REMOVE_DUPLICATES ROOT_LIBRARIES) execute_process( COMMAND ${ROOT_CONFIG_EXECUTABLE} --features OUTPUT_VARIABLE _root_options OUTPUT_STRIP_TRAILING_WHITESPACE) foreach(_opt ${_root_options}) set(ROOT_${_opt}_FOUND TRUE) endforeach() endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(ROOT DEFAULT_MSG ROOT_CONFIG_EXECUTABLE ROOTSYS ROOT_VERSION ROOT_INCLUDE_DIR ROOT_LIBRARIES ROOT_LIBRARY_DIR) mark_as_advanced(ROOT_CONFIG_EXECUTABLE) include(CMakeParseArguments) find_program(ROOTCINT_EXECUTABLE rootcint PATHS $ENV{ROOTSYS}/bin) find_program(GENREFLEX_EXECUTABLE genreflex PATHS $ENV{ROOTSYS}/bin) find_package(GCCXML) if(EXISTS "$ENV{ROOTSYS}/cmake/modules/RootNewMacros.cmake") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} $ENV{ROOTSYS}/cmake/modules) include(RootNewMacros) elseif(EXISTS "${ROOTSYS}/cmake/modules/RootNewMacros.cmake") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ROOTSYS}/cmake/modules) include(RootNewMacros) else() #---------------------------------------------------------------------------- # function ROOT_GENERATE_DICTIONARY( dictionary # header1 header2 ... # LINKDEF linkdef1 ... # OPTIONS opt1...) function(ROOT_GENERATE_DICTIONARY dictionary) CMAKE_PARSE_ARGUMENTS(ARG "" "" "LINKDEF;OPTIONS" "" ${ARGN}) #---Get the list of include directories------------------ get_directory_property(incdirs INCLUDE_DIRECTORIES) set(includedirs) foreach( d ${incdirs}) set(includedirs ${includedirs} -I${d}) endforeach() #---Get the list of header files------------------------- set(headerfiles) foreach(fp ${ARG_UNPARSED_ARGUMENTS}) if(${fp} MATCHES "[*?]") # Is this header a globbing expression? file(GLOB files ${fp}) foreach(f ${files}) if(NOT f MATCHES LinkDef) # skip LinkDefs from globbing result set(headerfiles ${headerfiles} ${f}) endif() endforeach() else() find_file(headerFile ${fp} PATHS ${incdirs}) set(headerfiles ${headerfiles} ${headerFile}) unset(headerFile CACHE) endif() endforeach() #---Get LinkDef.h file------------------------------------ set(linkdefs) foreach( f ${ARG_LINKDEF}) find_file(linkFile ${f} PATHS ${incdirs}) set(linkdefs ${linkdefs} ${linkFile}) unset(linkFile CACHE) endforeach() #---call rootcint------------------------------------------ add_custom_command(OUTPUT ${dictionary}.cxx ${dictionary}.h COMMAND ${ROOTCINT_EXECUTABLE} -cint -f ${dictionary}.cxx -c ${ARG_OPTIONS} ${includedirs} ${headerfiles} ${linkdefs} DEPENDS ${headerfiles} ${linkdefs} VERBATIM) endfunction() #---------------------------------------------------------------------------- # function REFLEX_GENERATE_DICTIONARY(dictionary # header1 header2 ... # SELECTION selectionfile ... # OPTIONS opt1...) function(REFLEX_GENERATE_DICTIONARY dictionary) CMAKE_PARSE_ARGUMENTS(ARG "" "" "SELECTION;OPTIONS" "" ${ARGN}) #---Get the list of header files------------------------- set(headerfiles) foreach(fp ${ARG_UNPARSED_ARGUMENTS}) file(GLOB files ${fp}) if(files) foreach(f ${files}) set(headerfiles ${headerfiles} ${f}) endforeach() else() set(headerfiles ${headerfiles} ${fp}) endif() endforeach() #---Get Selection file------------------------------------ if(IS_ABSOLUTE ${ARG_SELECTION}) set(selectionfile ${ARG_SELECTION}) else() set(selectionfile ${CMAKE_CURRENT_SOURCE_DIR}/${ARG_SELECTION}) endif() #---Get the list of include directories------------------ get_directory_property(incdirs INCLUDE_DIRECTORIES) set(includedirs) foreach( d ${incdirs}) set(includedirs ${includedirs} -I${d}) endforeach() #---Get preprocessor definitions-------------------------- get_directory_property(defs COMPILE_DEFINITIONS) foreach( d ${defs}) set(definitions ${definitions} -D${d}) endforeach() #---Nanes and others--------------------------------------- set(gensrcdict ${dictionary}.cpp) if(MSVC) set(gccxmlopts "--gccxmlopt=\"--gccxml-compiler cl\"") else() #set(gccxmlopts "--gccxmlopt=\'--gccxml-cxxflags -m64 \'") set(gccxmlopts) endif() #set(rootmapname ${dictionary}Dict.rootmap) #set(rootmapopts --rootmap=${rootmapname} --rootmap-lib=${libprefix}${dictionary}Dict) #---Check GCCXML and get path----------------------------- if(GCCXML) get_filename_component(gccxmlpath ${GCCXML} PATH) else() message(WARNING "GCCXML not found. Install and setup your environment to find 'gccxml' executable") endif() #---Actual command---------------------------------------- add_custom_command(OUTPUT ${gensrcdict} ${rootmapname} COMMAND ${GENREFLEX_EXECUTABLE} ${headerfiles} -o ${gensrcdict} ${gccxmlopts} ${rootmapopts} --select=${selectionfile} --gccxmlpath=${gccxmlpath} ${ARG_OPTIONS} ${includedirs} ${definitions} DEPENDS ${headerfiles} ${selectionfile}) endfunction() endif() mark_as_advanced(ROOTCINT_EXECUTABLE GENREFLEX_EXECUTABLE) # Modern add dictionary command # Call with the name of the output dictionary # Followed by sources (usually header files) # with an optional LinkDef.h at the end # # Add the created dictionary target to the linked libraries # root_add_dictionary(MyDict MyClass.h LinkDef.h) function(root_add_dictionary OUTNAME) add_custom_command( OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${OUTNAME}.cxx" COMMAND "${ROOTCINT_EXECUTABLE}" -v4 -f "${CMAKE_CURRENT_BINARY_DIR}/${OUTNAME}.cxx" ${ARGN} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" DEPENDS ${ARN} ) add_library(${OUTNAME} STATIC "${CMAKE_CURRENT_BINARY_DIR}/${OUTNAME}.cxx") target_link_libraries(${OUTNAME} PUBLIC ROOT::Libraries) endfunction()