Warning, /npsim/CMakeLists.txt is written in an unsupported language. File is not indexed.
0001 cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
0002
0003 project(npsim
0004 VERSION 1.0.0
0005 LANGUAGES CXX)
0006
0007 # C++ standard
0008 set(CMAKE_CXX_STANDARD 20)
0009 set(CMAKE_CXX_STANDARD 20 CACHE STRING "Set the C++ standard to be used")
0010 if(NOT CMAKE_CXX_STANDARD MATCHES "^(20|23)$")
0011 message(FATAL_ERROR "Unsupported C++ standard: ${CMAKE_CXX_STANDARD}")
0012 endif()
0013 set(CMAKE_CXX_STANDARD_REQUIRED ON)
0014 set(CMAKE_CXX_EXTENSIONS OFF)
0015
0016 # Install prefix
0017 if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
0018 set(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT FALSE)
0019 set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH "Install prefix" FORCE)
0020 message(STATUS "Setting default install prefix: ${CMAKE_INSTALL_PREFIX}")
0021 endif()
0022
0023 # Use GNU install dirs
0024 include(GNUInstallDirs)
0025 include(CheckCXXCompilerFlag)
0026 include(CTest)
0027
0028 # Build type
0029 if (NOT CMAKE_BUILD_TYPE)
0030 set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Build type configuration" FORCE)
0031 message(STATUS "Setting default build type: ${CMAKE_BUILD_TYPE}")
0032 endif()
0033
0034 # Error on all warnings
0035 if(NOT CMAKE_BUILD_TYPE STREQUAL "Release")
0036 add_compile_options(-Wall -Wextra -Werror -pedantic)
0037 endif()
0038
0039 # Export compile commands as json for run-clang-tidy
0040 set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
0041
0042 # ---------------------------------------------------------------------------
0043 # Feature options
0044
0045 option(USE_GEOCAD "build the geocad library. Requires opencascade" ON)
0046
0047 # ---------------------------------------------------------------------------
0048 # Sanitizers options
0049
0050 option(USE_ASAN "Compile with address sanitizer" OFF)
0051 option(USE_TSAN "Compile with thread sanitizer" OFF)
0052 option(USE_UBSAN "Compile with undefined behavior sanitizer" OFF)
0053
0054 if(USE_ASAN)
0055 add_compile_options(-fsanitize=address -fno-omit-frame-pointer -g -O1)
0056 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
0057 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
0058 set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fsanitize=address")
0059 # Clang does not link the full ASAN runtime into shared/module libs by default;
0060 # it only adds bootstrap stubs that require the runtime from the main binary.
0061 # Since DD4hep binaries are not ASAN-instrumented, link the shared ASAN DSO directly.
0062 if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
0063 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -shared-libasan")
0064 set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -shared-libasan")
0065 # Clang's ASAN DSO has an architecture-specific name
0066 execute_process(
0067 COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libclang_rt.asan-${CMAKE_SYSTEM_PROCESSOR}.so
0068 OUTPUT_VARIABLE PRELOAD_SANITIZER_LIB_ASAN
0069 OUTPUT_STRIP_TRAILING_WHITESPACE)
0070 else()
0071 execute_process(
0072 COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libasan.so
0073 OUTPUT_VARIABLE PRELOAD_SANITIZER_LIB_ASAN
0074 OUTPUT_STRIP_TRAILING_WHITESPACE)
0075 endif()
0076 get_filename_component(ASAN_RUNTIME_DIR "${PRELOAD_SANITIZER_LIB_ASAN}" DIRECTORY)
0077 list(APPEND CMAKE_BUILD_RPATH "${ASAN_RUNTIME_DIR}")
0078 list(APPEND SANITIZER_RUNTIME_DIRS "${ASAN_RUNTIME_DIR}")
0079 list(PREPEND PRELOAD_SANITIZER_LIB ${PRELOAD_SANITIZER_LIB_ASAN})
0080 endif()
0081
0082 if(USE_TSAN)
0083 add_compile_options(-fsanitize=thread -g -O1)
0084 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread")
0085 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=thread")
0086 set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fsanitize=thread")
0087 if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
0088 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -shared-libsan")
0089 set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -shared-libsan")
0090 execute_process(
0091 COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libclang_rt.tsan-${CMAKE_SYSTEM_PROCESSOR}.so
0092 OUTPUT_VARIABLE PRELOAD_SANITIZER_LIB_TSAN
0093 OUTPUT_STRIP_TRAILING_WHITESPACE)
0094 else()
0095 execute_process(
0096 COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libtsan.so
0097 OUTPUT_VARIABLE PRELOAD_SANITIZER_LIB_TSAN
0098 OUTPUT_STRIP_TRAILING_WHITESPACE)
0099 endif()
0100 get_filename_component(TSAN_RUNTIME_DIR "${PRELOAD_SANITIZER_LIB_TSAN}" DIRECTORY)
0101 list(APPEND CMAKE_BUILD_RPATH "${TSAN_RUNTIME_DIR}")
0102 list(APPEND SANITIZER_RUNTIME_DIRS "${TSAN_RUNTIME_DIR}")
0103 list(PREPEND PRELOAD_SANITIZER_LIB ${PRELOAD_SANITIZER_LIB_TSAN})
0104 endif()
0105
0106 if(USE_UBSAN)
0107 foreach(sanitizer undefined float-divide-by-zero unsigned-integer-overflow implicit-conversion local-bounds nullability)
0108 check_cxx_compiler_flag("-fsanitize=${sanitizer}" CXX_COMPILER_HAS_sanitize_${sanitizer})
0109 if(CXX_COMPILER_HAS_sanitize_${sanitizer})
0110 add_compile_options(-fsanitize=${sanitizer})
0111 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=${sanitizer}")
0112 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=${sanitizer}")
0113 set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fsanitize=${sanitizer}")
0114 endif()
0115 endforeach()
0116 add_compile_options(-g -O1)
0117 if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
0118 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -shared-libsan")
0119 set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -shared-libsan")
0120 execute_process(
0121 COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libclang_rt.ubsan_standalone-${CMAKE_SYSTEM_PROCESSOR}.so
0122 OUTPUT_VARIABLE PRELOAD_SANITIZER_LIB_UBSAN
0123 OUTPUT_STRIP_TRAILING_WHITESPACE)
0124 else()
0125 execute_process(
0126 COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libubsan.so
0127 OUTPUT_VARIABLE PRELOAD_SANITIZER_LIB_UBSAN
0128 OUTPUT_STRIP_TRAILING_WHITESPACE)
0129 endif()
0130 get_filename_component(UBSAN_RUNTIME_DIR "${PRELOAD_SANITIZER_LIB_UBSAN}" DIRECTORY)
0131 list(APPEND CMAKE_BUILD_RPATH "${UBSAN_RUNTIME_DIR}")
0132 list(APPEND SANITIZER_RUNTIME_DIRS "${UBSAN_RUNTIME_DIR}")
0133 # With Clang, the ASAN runtime already integrates UBSAN; preloading
0134 # libclang_rt.ubsan_standalone alongside libclang_rt.asan causes runtime
0135 # conflicts (both provide overlapping interceptors). Skip the UBSAN preload
0136 # when ASAN is also active — ASAN handles both.
0137 if(NOT (USE_ASAN AND CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
0138 list(PREPEND PRELOAD_SANITIZER_LIB ${PRELOAD_SANITIZER_LIB_UBSAN})
0139 endif()
0140 endif()
0141
0142 # ---------------------------------------------------------------------------
0143 # Load additional OS dependent settings
0144
0145 if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
0146 ## OSX/homebrew version of root6 installs its cmake macros in a non-standard
0147 ## location. This might be an issue on other systems as well.
0148 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} $ENV{ROOTSYS}/etc/root/cmake)
0149
0150 ## Get rid of rpath warning on OSX
0151 set(CMAKE_MACOSX_RPATH 1)
0152 endif()
0153
0154 #----------------------------------------------------------------------------
0155 # Find Libraries
0156 #----------------------------------------------------------------------------
0157
0158 # DD4hep
0159 find_package(DD4hep 1.18 REQUIRED COMPONENTS DDCore DDG4)
0160 include(${DD4hep_DIR}/cmake/DD4hep.cmake)
0161 include(${DD4hep_DIR}/cmake/DD4hepBuild.cmake)
0162
0163 # Redefine for sanitizer support
0164 function(dd4hep_generate_rootmap library)
0165 if(APPLE)
0166 set(ENV_VAR DYLD_LIBRARY_PATH)
0167 else()
0168 set(ENV_VAR LD_LIBRARY_PATH)
0169 endif()
0170 set(${ENV_VAR}_VALUE $<TARGET_FILE_DIR:${library}>:$<TARGET_FILE_DIR:DD4hep::DD4hepGaudiPluginMgr>:$ENV{${ENV_VAR}})
0171
0172 set(rootmapfile ${CMAKE_SHARED_MODULE_PREFIX}${library}.components)
0173
0174 # Build the listcomponents invocation. When sanitizers are active we must
0175 # LD_PRELOAD the runtime so ASAN initialises before any allocation occurs;
0176 # loading it lazily via dlopen (RPATH) after DD4hep has already allocated
0177 # memory causes a crash. To prevent LeakSanitizer from scanning the entire
0178 # DD4hep/ROOT heap at process exit (which hangs the build), we force
0179 # detect_leaks=0 for this helper invocation only.
0180 string(JOIN ":" LD_PRELOAD_VALUE ${PRELOAD_SANITIZER_LIB})
0181 if(LD_PRELOAD_VALUE)
0182 set(EXTRA_ENV
0183 "LD_PRELOAD=${LD_PRELOAD_VALUE}"
0184 "ASAN_OPTIONS=detect_leaks=0:verify_asan_link_order=0"
0185 "LSAN_OPTIONS=detect_leaks=0"
0186 )
0187 endif()
0188
0189 add_custom_command(OUTPUT ${rootmapfile}
0190 DEPENDS ${library}
0191 COMMAND ${CMAKE_COMMAND} -E env
0192 "${ENV_VAR}=${${ENV_VAR}_VALUE}"
0193 ${EXTRA_ENV}
0194 $<TARGET_FILE:DD4hep::listcomponents> -o ${rootmapfile} $<TARGET_FILE_NAME:${library}>
0195 WORKING_DIRECTORY ${LIBRARY_OUTPUT_PATH}
0196 COMMAND_EXPAND_LISTS
0197 )
0198
0199 add_custom_target(Components_${library} ALL DEPENDS ${rootmapfile})
0200 set(install_destination "lib")
0201 if(CMAKE_INSTALL_LIBDIR)
0202 set(install_destination ${CMAKE_INSTALL_LIBDIR})
0203 endif()
0204 install(FILES $<TARGET_FILE_DIR:${library}>/${rootmapfile}
0205 DESTINATION ${install_destination}
0206 )
0207 endfunction()
0208
0209 dd4hep_configure_output()
0210 dd4hep_set_compiler_flags()
0211
0212 # Opencascade
0213 if(USE_GEOCAD)
0214 find_package(OpenCASCADE REQUIRED)
0215 endif()
0216
0217 # libfmt
0218 find_package(fmt REQUIRED)
0219
0220 # nlohmann-json (header-only, for DDG4 plugin JSON property parsing)
0221 find_package(nlohmann_json REQUIRED)
0222
0223 #-----------------------------------------
0224 # add the library sub directories
0225 add_subdirectory(src/plugins)
0226 add_subdirectory(src/python)
0227 add_subdirectory(src/geocad)
0228 add_subdirectory(src/config)
0229 add_subdirectory(src/tools)
0230
0231 #----------------------------------------------------------------------------
0232 # Install and export targets
0233 install(EXPORT NPDetTargets
0234 FILE NPDetTargets.cmake
0235 NAMESPACE NPDet::
0236 DESTINATION lib/NPDet
0237 )
0238
0239 include(CMakePackageConfigHelpers)
0240
0241 set(TARGETS_INSTALL_PATH lib/NPDet/NPDetTargets.cmake)
0242 CONFIGURE_PACKAGE_CONFIG_FILE(
0243 cmake/NPDetConfig.cmake.in
0244 ${CMAKE_CURRENT_BINARY_DIR}/NPDetConfig.cmake
0245 INSTALL_DESTINATION lib/NPDet
0246 PATH_VARS CMAKE_INSTALL_INCLUDEDIR CMAKE_INSTALL_LIBDIR TARGETS_INSTALL_PATH
0247 )
0248
0249 write_basic_package_version_file("NPDetConfigVersion.cmake"
0250 VERSION ${NPDet_VERSION}
0251 COMPATIBILITY SameMajorVersion
0252 )
0253
0254 install(FILES
0255 ${CMAKE_CURRENT_BINARY_DIR}/NPDetConfig.cmake
0256 ${CMAKE_CURRENT_BINARY_DIR}/NPDetConfigVersion.cmake
0257 DESTINATION lib/NPDet
0258 )
0259
0260 install(PROGRAMS
0261 scripts/sanitize_hepmc3.py DESTINATION bin RENAME sanitize_hepmc3
0262 )