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
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
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
)
IF(${CMAKE_CXX_STANDARD} EQUAL 14)
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
)
GET_TARGET_PROPERTY(BOOST_FILESYSTEM_LOC Boost::filesystem IMPORTED_LOCATION)
GET_FILENAME_COMPONENT(BOOST_DIR ${BOOST_FILESYSTEM_LOC} DIRECTORY)
ELSE()
SET(FS_LIBRARIES stdc++fs)
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)
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
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}"
)