Newer
Older
endmacro( dd4hep_enable_tests )
#---------------------------------------------------------------------------------------------------
macro ( dd4hep_configure_scripts _pkg )
cmake_parse_arguments(MACRO_ARG "DEFAULT_SETUP;WITH_TESTS" "RUN_SCRIPT" "" ${ARGV} )
# PackageName is a variable required by existing LC build scripts.
# Set it here and unset it at the end of the scope...
set( PackageName ${_pkg} )
dd4hep_list_to_string( _dir_entries PREFIX "DIRS:" ENTRIES ${MACRO_ARG_UNPARSED_ARGUMENTS} )
dd4hep_print ( "|++> Setting up test environment for ${PackageName}: Testing:${BUILD_TESTING} Setup:${MACRO_ARG_DEFAULT_SETUP} With Tests(${MACRO_ARG_WITH_TESTS}): ${_dir_entries}" )
if ( (NOT "${MACRO_ARG_DEFAULT_SETUP}" STREQUAL "") OR (NOT "${_pkg}" STREQUAL "") )
configure_file( ${DD4hep_DIR}/cmake/run_test_package.sh ${EXECUTABLE_OUTPUT_PATH}/run_test_${_pkg}.sh @ONLY)
INSTALL(PROGRAMS ${EXECUTABLE_OUTPUT_PATH}/run_test_${_pkg}.sh DESTINATION bin )
#---- configure run environment ---------------
configure_file( ${DD4hep_DIR}/cmake/thisdd4hep_package.sh.in ${EXECUTABLE_OUTPUT_PATH}/this${_pkg}.sh @ONLY)
install(PROGRAMS ${EXECUTABLE_OUTPUT_PATH}/this${_pkg}.sh DESTINATION bin )
#--- install target-------------------------------------
if ( IS_DIRECTORY scripts )
dd4hep_install_dir ( compact scripts DESTINATION examples/${_pkg} )
endif()
if ( IS_DIRECTORY compact )
dd4hep_install_dir ( compact DESTINATION examples/${_pkg} )
endif()
endif()
dd4hep_enable_tests ( ${MACRO_ARG_UPARSED_ARGUMENTS} )
unset( PackageName )
endmacro( dd4hep_configure_scripts )
#---------------------------------------------------------------------------------------------------
# dd4hep_add_test_reg
#
# Add test with regular expression output parsing.
# BUILD_EXEC: Add and build executable with the same name as the test (Default NONE)
# OUTPUT Output file of the test (Default: empty)
# COMMAND Command to execute
# EXEC_ARGS Arguments to the command
# REGEX_PASS Regular expression to indicate that the test succeeded
# REGEX_FAIL Regular expression to indicate that the test failed
#
# \author M.Frank
# \version 1.0
#
#---------------------------------------------------------------------------------------------------
function ( dd4hep_add_test_reg test_name )
cmake_parse_arguments(ARG "BUILD_EXEC" "OUTPUT" "COMMAND;DEPENDS;EXEC_ARGS;REGEX_PASS;REGEX_PASSED;REGEX_FAIL;REGEX_FAILED" ${ARGN} )
dd4hep_print ( "*** Will not build/execute test ${test_name}. Missing dependencies: ${missing} ")
#dd4hep_print ( "Building executable: ${test_name} SOURCES src/${test_name}.cc")
dd4hep_add_executable ( ${test_name} SOURCES src/${test_name}.cc )
endif()
set ( cmd ${ARG_COMMAND} )
if ( "${cmd}" STREQUAL "" )
set ( cmd ${CMAKE_INSTALL_PREFIX}/bin/run_test.sh ${test_name} )
endif()
set ( passed ${ARG_REGEX_PASS} ${ARG_REGEX_PASSED} )
if ( "${passed}" STREQUAL "NONE" )
unset ( passed )
elseif ( "${passed}" STREQUAL "" )
set ( passed "TEST_PASSED" )
endif()
set ( failed ${ARG_REGEX_FAIL} ${ARG_REGEX_FAILED} )
if ( "${failed}" STREQUAL "NONE" )
unset ( failed )
endif()
set ( output ${ARG_OUTPUT} )
set ( args ${ARG_EXEC_ARGS} )
if ( "${args}" STREQUAL "" )
set ( args ${test_name} )
endif()
add_test(NAME t_${test_name} COMMAND ${cmd} ${output} ${args} ${output} )
if ( NOT "${passed}" STREQUAL "" )
set_tests_properties( t_${test_name} PROPERTIES PASS_REGULAR_EXPRESSION "${passed}" )
endif()
if ( NOT "${failed}" STREQUAL "" )
set_tests_properties( t_${test_name} PROPERTIES FAIL_REGULAR_EXPRESSION "${failed}" )
endif()
# Set test dependencies if present
foreach ( _dep ${ARG_DEPENDS} )
set_tests_properties( t_${test_name} PROPERTIES DEPENDS t_${_dep} )
endforeach()
endif()
endfunction()
#---------------------------------------------------------------------------------------------------
# fill_dd4hep_library_path
#
#
# \author M.Petric
# \version 1.0
#
#---------------------------------------------------------------------------------------------------
function ( fill_dd4hep_library_path )
string(REGEX REPLACE "/lib/libCore.*" "" ROOT_ROOT ${ROOT_Core_LIBRARY})
SET( ENV{DD4HEP_LIBRARY_PATH} ${ROOT_ROOT}/lib )
if ( NOT "${Boost_LIBRARY_DIRS}" STREQUAL "" )
SET( ENV{DD4HEP_LIBRARY_PATH} $ENV{DD4HEP_LIBRARY_PATH}:${Boost_LIBRARY_DIRS} )
else()
dd4hep_print("|++> The boost library path cannot be determined. Problems maybe ahead.")
endif()
if ( ${DD4HEP_USE_GEANT4} )
string(REGEX REPLACE "/lib/Geant4.*" "" Geant4_ROOT ${Geant4_DIR})
SET( ENV{DD4HEP_LIBRARY_PATH} ${Geant4_ROOT}/lib:$ENV{DD4HEP_LIBRARY_PATH} )
endif()
if(${DD4HEP_USE_LCIO})
SET( ENV{DD4HEP_LIBRARY_PATH} ${LCIO_DIR}/lib:$ENV{DD4HEP_LIBRARY_PATH} )
endif()
SET( ENV{DD4HEP_LIBRARY_PATH} ${CLHEP_ROOT_DIR}/lib:$ENV{DD4HEP_LIBRARY_PATH} )
if(${DD4HEP_USE_XERCESC})
SET( ENV{DD4HEP_LIBRARY_PATH} ${XERCESC_ROOT_DIR}/lib:$ENV{DD4HEP_LIBRARY_PATH} )
endif()
SET( ENV{DD4HEP_LIBRARY_PATH} ${CMAKE_BINARY_DIR}/lib:$ENV{DD4HEP_LIBRARY_PATH} )
endfunction()
#---------------------------------------------------------------------------------------------------
# dd4hep_add_dictionary
# Arguments
# ---------
# dictionary -> dictionary name
# SOURCES -> Globbing expression to find source files
# EXCLUDE -> Files to exclude if they are found via SOURCES
# LINKDEF -> Last entry when calling rootcling
# USES -> Libraries needed to link the binary
#
# OPTIONS -> Options to pass to rootcling
# INCLUDES -> Additional include directories need to compile the binary
# DEFINITIONS -> Additional compiler definitions to compile the sources
# OUTPUT ->
#
# \author A.Sailer
# \version 1.0
#
#---------------------------------------------------------------------------------------------------
function(dd4hep_add_dictionary dictionary )
cmake_parse_arguments(ARG "" "" "SOURCES;EXCLUDE;LINKDEF;OPTIONS;USES;DEFINITIONS;INCLUDES;OUTPUT" ${ARGN} )
dd4hep_print ( "|++++> Building dictionary ... ${dictionary}" )
file(GLOB headers ${ARG_SOURCES})
file(GLOB excl_headers ${ARG_EXCLUDE})
foreach( f ${excl_headers} )
list( REMOVE_ITEM headers ${f} )
dd4hep_debug ( "|++ exclude: ${f}" )
endforeach()
foreach( f ${headers} )
dd4hep_debug ( "|++ ${dictionary} is using: ${f}" )
endforeach()
set(inc_dirs ${CMAKE_CURRENT_SOURCE_DIR}/include)
foreach(inc ${ARG_INCLUDES})
LIST(APPEND inc_dirs ${inc})
endforeach()
set(comp_defs)
foreach(def ${ARG_DEFINITIONS})
LIST(APPEND comp_defs ${def})
endforeach()
foreach(DEP ${ARG_USES})
# Get INCLUDE DIRECTORIES from Dependencies
LIST(APPEND inc_dirs $<TARGET_PROPERTY:${DEP},INTERFACE_INCLUDE_DIRECTORIES>)
# Get COMPILE DEFINITIONS from Dependencies
LIST(APPEND comp_defs $<TARGET_PROPERTY:${DEP},INTERFACE_COMPILE_DEFINITIONS>)
endforeach()
#
file ( GLOB linkdefs ${ARG_LINKDEF} )
#
dd4hep_debug("|++ Linkdef: '${linkdefs}'" )
dd4hep_debug("|++ Definition: '${comp_defs}'" )
dd4hep_debug("|++ Include: '${inc_dirs}'" )
dd4hep_debug("|++ Files: '${headers}'" )
dd4hep_debug("|++ Unparsed: '${ARG_UNPARSED_ARGUMENTS}'" )
dd4hep_debug("|++ Sources: '${CMAKE_CURRENT_SOURCE_DIR}'" )
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
#
set ( output_dir ${CMAKE_CURRENT_BINARY_DIR}/../lib )
if ( NOT "${ARG_OUTPUT}" STREQUAL "" )
set ( output_dir ${ARG_OUTPUT} )
endif()
SET(COMP_DEFS )
file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${dictionary}_arguments
CONTENT "${ROOT_rootcling_CMD} -cint -f ${dictionary}.cxx -s ${output_dir}/${dictionary} -inlineInputHeader -c -p ${ARG_OPTIONS} -std=c++${CMAKE_CXX_STANDARD} \
$<$<BOOL:${comp_defs}>:-D$<JOIN:${comp_defs}, -D>> \
$<$<BOOL:${inc_dirs}>:-I$<JOIN:${inc_dirs}, -I>> \
$<JOIN:${headers}, > $<JOIN:${linkdefs}, >"
)
add_custom_command(OUTPUT ${dictionary}.cxx ${output_dir}/${dictionary}_rdict.pcm
COMMAND bash ${dictionary}_arguments
DEPENDS ${headers} ${linkdefs}
)
add_custom_target(${dictionary}
DEPENDS ${dictionary}.cxx ${output_dir}/${dictionary}_rdict.pcm
)
set_source_files_properties(${dictionary}.cxx ${output_dir}/${dictionary}_rdict.pcm
PROPERTIES
GENERATED TRUE
COMPILE_FLAGS "-Wno-unused-function -Wno-overlength-strings"
)
# Install the binary to the destination directory
install(FILES ${output_dir}/${dictionary}_rdict.pcm DESTINATION lib)
endfunction()
#---------------------------------------------------------------------------------------------------
#
#
# Arguments
# ---------
# binary -> plugin name
# SOURCES -> Globbing expression to find source files
# GENERATED -> List of source files
# USES -> Libraries needed to link the binary
# INCLUDES -> Additional include directories need to compile the binary
# DEFINITIONS -> Optional compiler definitions to compile the sources
# NOINSTALL -> If set do not install the plugin
# \author A.Sailer
# \version 1.0
#
#---------------------------------------------------------------------------------------------------
function(dd4hep_add_plugin binary)
cmake_parse_arguments(ARG "NOINSTALL" "" "SOURCES;GENERATED;USES;INCLUDES;DEFINITIONS" ${ARGN})
if ( ${ARG_NOINSTALL} )
set(NOINSTALL NOINSTALL)
endif()
file(GLOB SOURCES ${ARG_SOURCES})
add_library(${binary} SHARED ${SOURCES} ${ARG_GENERATED})
target_link_libraries(${binary} PUBLIC ${ARG_USES})
target_include_directories(${binary} PUBLIC ${ARG_INCLUDES})
target_compile_definitions(${binary} PUBLIC ${ARG_DEFINITIONS})
dd4hep_generate_rootmap(${binary})
if(NOT ${ARG_NOINSTALL})
set(install_destination "lib")
if(CMAKE_INSTALL_LIBDIR)
set(install_destination ${CMAKE_INSTALL_LIBDIR})
endif()
install(TARGETS ${binary} LIBRARY DESTINATION ${install_destination})
endif()
endfunction(dd4hep_add_plugin)
#
# Macro to set up ROOT:: targets so that we can use the same code for root 6.8 and for root 6.10 and beyond
# This is called in dd4hep, and in DD4hepConfig
#
macro(DD4HEP_SETUP_ROOT_TARGETS)
#ROOT CXX Flags are a string with quotes, not a list, so we need to convert to a list...
string(REPLACE " " ";" ROOT_CXX_FLAGS ${ROOT_CXX_FLAGS})
IF(NOT TARGET ROOT::Core)
#in ROOT before 6.10 there is no ROOT namespace, so we create ROOT::Core ourselves
ADD_LIBRARY(ROOT::Core INTERFACE IMPORTED GLOBAL)
SET_TARGET_PROPERTIES(ROOT::Core
PROPERTIES
INTERFACE_COMPILE_OPTIONS "${ROOT_CXX_FLAGS}"
INTERFACE_INCLUDE_DIRECTORIES ${ROOT_INCLUDE_DIRS}
)
# there is also no dependency between the targets
TARGET_LINK_LIBRARIES(ROOT::Core INTERFACE Core)
# we list here the targets we use in dd4hep, as later versions of root have the namespace, we do not have to to this
# for ever
foreach(LIB PyROOT Geom GenVector Eve Graf3d RGL Gui RIO MathCore MathMore EG EGL Rint Tree Hist Physics Gdml)
IF(TARGET ${LIB})
ADD_LIBRARY(ROOT::${LIB} INTERFACE IMPORTED GLOBAL)
TARGET_LINK_LIBRARIES(ROOT::${LIB} INTERFACE ${LIB} ROOT::Core)
ENDIF()
endforeach()
ENDIF(NOT TARGET ROOT::Core)
dd4hep_debug("ROOT Libraries ${ROOT_LIBRARIES}")
dd4hep_debug("ROOT CXX_FLAGS ${ROOT_CXX_FLAGS}")
dd4hep_debug("ROOT INCL DIRS ${ROOT_INCLUDE_DIRS}")
dd4hep_debug("ROOT_VERSION: ${ROOT_VERSION}" )
Andre Sailer
committed
ENDMACRO()
#
# Do some processing of the imported Boost Targets
# Some libraries are only needed for cxx std 14
# we also have to make sure the boost library location is known in that case
#
#
MACRO(DD4HEP_SETUP_BOOST_TARGETS)
SET_TARGET_PROPERTIES(Boost::boost
PROPERTIES
INTERFACE_COMPILE_DEFINITIONS BOOST_SPIRIT_USE_PHOENIX_V3
)
Andre Sailer
committed
# Try to compile with filesystem header linking against different FS libraries
SET(HAVE_FILESYSTEM False)
dd4hep_debug("|++> Checking if compiler supports filesystem library")
Andre Sailer
committed
FOREACH(FS_LIB_NAME stdc++fs c++fs )
dd4hep_debug("|++++> linking against ${FS_LIB_NAME}")
try_compile(HAVE_FILESYSTEM ${CMAKE_BINARY_DIR}/try ${CMAKE_CURRENT_LIST_DIR}/cmake/TryFileSystem.cpp
Andre Sailer
committed
CXX_STANDARD ${CMAKE_CXX_STANDARD}
CXX_EXTENSIONS False
OUTPUT_VARIABLE HAVE_FS_OUTPUT
LINK_LIBRARIES ${FS_LIB_NAME}
)
dd4hep_debug("|++++> ${HAVE_FS_OUTPUT}")
Andre Sailer
committed
IF(HAVE_FILESYSTEM)
dd4hep_print("|++> Compiler supports filesystem, linking against ${FS_LIB_NAME}")
Andre Sailer
committed
SET(FS_LIBRARIES ${FS_LIB_NAME})
BREAK()
ENDIF()
dd4hep_debug("|++++> Compiler not compatible when linking against ${FS_LIB_NAME}")
Andre Sailer
committed
ENDFOREACH()
IF(NOT HAVE_FILESYSTEM)
dd4hep_print("|++> Compiler does not have filesystem support, falling back to Boost::filesystem")
Andre Sailer
committed
FIND_PACKAGE(Boost 1.49 REQUIRED COMPONENTS filesystem system)
SET(FS_LIBRARIES Boost::filesystem Boost::system)
SET_TARGET_PROPERTIES(Boost::filesystem
PROPERTIES
INTERFACE_COMPILE_DEFINITIONS USE_BOOST_FILESYSTEM
)
Andre Sailer
committed
GET_TARGET_PROPERTY(BOOST_FILESYSTEM_LOC Boost::filesystem IMPORTED_LOCATION)
GET_FILENAME_COMPONENT(BOOST_DIR ${BOOST_FILESYSTEM_LOC} DIRECTORY)
ENDIF()
#
# Do some processing of the imported Geant4 Targets, CLHEP treatment etc.
# Will only be done once, repeated calls should have no effect
#
Andre Sailer
committed
# only do this once
IF(NOT TARGET Geant4::Interface)
#include( ${Geant4_USE_FILE} ) # do not use the use file, this is not very considerate...
IF((NOT ${Geant4_TLS_MODEL} STREQUAL "global-dynamic") AND NOT ${DD4HEP_IGNORE_GEANT4_TLS})
MESSAGE(FATAL_ERROR "Geant4 was built with ${Geant4_TLS_MODEL}, DD4hep requires 'global-dynamic'! Ignore this ERROR with DD4HEP_IGNORE_GEANT4_TLS=True ")
ENDIF()
Andre Sailer
committed
if(Geant4_builtin_clhep_FOUND)
dd4hep_debug("Using Geant4 internal CLHEP")
Andre Sailer
committed
set(CLHEP "")
else()
IF(NOT TARGET CLHEP::CLHEP)
FIND_PACKAGE(CLHEP REQUIRED)
ENDIF()
Andre Sailer
committed
set(CLHEP CLHEP::CLHEP)
dd4hep_debug("Using External CLHEP")
dd4hep_debug("CLHEP Libraries ${CLHEP_LIBRARIES}")
dd4hep_debug("CLHEP CXX_FLAGS ${CLHEP_CXX_FLAGS}")
dd4hep_debug("CLHEP INCL DIRS ${CLHEP_INCLUDE_DIRS}")
dd4hep_debug("CLHEP_VERSION: ${CLHEP_VERSION}" )
Andre Sailer
committed
endif()
dd4hep_debug("Geant4 Libraries ${Geant4_LIBRARIES}")
dd4hep_debug("Geant4 CXX_FLAGS ${Geant4_CXX_FLAGS}")
dd4hep_debug("Geant4 INCL DIRS ${Geant4_INCLUDE_DIRS}")
dd4hep_debug("Geant4_VERSION: ${Geant4_VERSION}" )
# Geant4 CXX Flags are a string with quotes, not a list, so we need to convert to a list...
# Geant4::10.2.2 at least, not in 10.5 (check where it switches)
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
string(REPLACE " " ";" Geant4_Flags ${Geant4_CXX_FLAGS} ${Geant4_CXX_FLAGS_${CMAKE_BUILD_TYPE}})
SET(Geant4_CXX_FLAGS ${Geant4_Flags})
#Geant4_DEFINITIONS already include -D, we jave to get rid of that so we can join things when creating dictionaries
SET(G4_DEF_TEMP "")
foreach(def ${Geant4_DEFINITIONS})
string(REPLACE "-D" "" def ${def})
LIST(APPEND G4_DEF_TEMP ${def})
endforeach()
SET(Geant4_DEFINITIONS ${G4_DEF_TEMP})
UNSET(G4_DEF_TEMP)
ADD_LIBRARY(Geant4::Interface INTERFACE IMPORTED GLOBAL)
SET_TARGET_PROPERTIES(Geant4::Interface
PROPERTIES
INTERFACE_COMPILE_OPTIONS "${Geant4_CXX_FLAGS}"
INTERFACE_COMPILE_DEFINITIONS "${Geant4_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${Geant4_INCLUDE_DIRS}"
)
IF(CLHEP)
dd4hep_debug("Adding CLHEP to Geant4::Interface Dependencies")
TARGET_LINK_LIBRARIES(Geant4::Interface INTERFACE ${CLHEP})
ENDIF()
# Geant4_LIBRARIES are imported targets, we just add them all to our own interface library for convenience
# Geant4 Libraries do not (yet) use a namespace
foreach(LIB ${Geant4_LIBRARIES})
TARGET_LINK_LIBRARIES(Geant4::Interface INTERFACE ${LIB})
endforeach()
dd4hep_debug("Geant4 Libraries ${Geant4_LIBRARIES};${Geant4_COMPONENT_LIBRARIES}")
dd4hep_debug("Geant4 Location ${Geant4_LOCATION}")
dd4hep_debug("Geant4 Defintitions ${Geant4_DEFINITIONS}")
dd4hep_debug("Geant4 CXX_FLAGS ${Geant4_CXX_FLAGS}")
dd4hep_debug("Geant4 INCL DIRS ${Geant4_INCLUDE_DIRS}")
dd4hep_debug("Geant4_VERSION: ${Geant4_VERSION}" )
#
# Create Interface library for LCIO
#
MACRO(DD4HEP_SETUP_LCIO_TARGETS)
IF(NOT TARGET LCIO::LCIO)
ADD_LIBRARY(LCIO::LCIO INTERFACE IMPORTED GLOBAL)
SET_TARGET_PROPERTIES(LCIO::LCIO
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${LCIO_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${LCIO_LIBRARIES}"
)