File: SanitizerHelper.cmake

package info (click to toggle)
neuron 8.2.6-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 34,760 kB
  • sloc: cpp: 149,571; python: 58,465; ansic: 50,329; sh: 3,510; xml: 213; pascal: 51; makefile: 35; sed: 5
file content (58 lines) | stat: -rw-r--r-- 3,547 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# Disable some of the more pedantic checks. float-divide-by-zero is undefined in the C/C++ standard
# but defined by (recent?) Clang. This is disabled for convenience because some user MOD files
# trigger it, while the NEURON codebase does not seem to do so itself.
# implicit-signed-integer-truncation does not flagged undefined behaviour, but rather behaviour that
# may be unintentional; unsigned-integer-overflow is similarly not actually undefined -- these
# checks are not enabled because they cause too much noise at the moment.
set(${CODING_CONV_PREFIX}_SANITIZERS_UNDEFINED_EXCLUSIONS
    float-divide-by-zero implicit-signed-integer-truncation unsigned-integer-overflow
    CACHE STRING "" FORCE)
include("${CODING_CONV_CMAKE}/sanitizers.cmake")
# Propagate the sanitizer flags to the NEURON sources
list(APPEND NRN_COMPILE_FLAGS ${NRN_SANITIZER_COMPILER_FLAGS})
list(APPEND NRN_LINK_FLAGS ${NRN_SANITIZER_COMPILER_FLAGS})
if(NRN_SANITIZER_LIBRARY_DIR)
  # At least Clang 14 does not add rpath entries for the sanitizer runtime libraries. Adding this
  # argument saves having to carefully set LD_LIBRARY_PATH and friends.
  list(APPEND NRN_LINK_FLAGS "-Wl,-rpath,${NRN_SANITIZER_LIBRARY_DIR}")
endif()
if(NRN_SANITIZERS)
  # nocmodl is quite noisy when run under LeakSanitizer, so only set the environment variables that
  # enable sanitizers if LeakSanitizer is not among them
  string(REPLACE "," ";" nrn_sanitizers "${NRN_SANITIZERS}") # NRN_SANITIZERS is comma-separated
  if("leak" IN_LIST nrn_sanitizers)
    set(NRN_NOCMODL_SANITIZER_ENVIRONMENT ${NRN_SANITIZER_DISABLE_ENVIRONMENT})
  else()
    set(NRN_NOCMODL_SANITIZER_ENVIRONMENT ${NRN_SANITIZER_ENABLE_ENVIRONMENT})
  endif()
  if("address" IN_LIST nrn_sanitizers)
    list(APPEND NRN_COMPILE_DEFS NRN_ASAN_ENABLED)
  endif()
  # generate and install a launcher script called nrn-enable-sanitizer [--preload] that sets
  # *SAN_OPTIONS variables and, optionally, LD_PRELOAD -- this is useful both in CI configuration
  # and when using the sanitizers "downstream" of NEURON
  string(JOIN " " NRN_SANITIZER_ENABLE_ENVIRONMENT_STRING ${NRN_SANITIZER_ENABLE_ENVIRONMENT})
  # sanitizer suppression files are handled similarly to other data files: we copy them to the same
  # path under the build and installation directories, and then assume the installation path unless
  # the NRNHOME environment variable is set, in which case it is assumed to point to the build
  # directory
  foreach(sanitizer ${nrn_sanitizers})
    if(EXISTS "${PROJECT_SOURCE_DIR}/.sanitizers/${sanitizer}.supp")
      configure_file(".sanitizers/${sanitizer}.supp" "share/nrn/sanitizers/${sanitizer}.supp"
                     COPYONLY)
      install(FILES "${PROJECT_BINARY_DIR}/share/nrn/sanitizers/${sanitizer}.supp"
              DESTINATION "${CMAKE_INSTALL_PREFIX}/share/nrn/sanitizers")
    endif()
  endforeach()
  # sanitizers.cmake uses absolute paths to suppression files in build directories. substitute that
  # with NEURON-specific NRNHOME-enabled logic
  string(REPLACE "${PROJECT_SOURCE_DIR}/.sanitizers/" "\${prefix}/share/nrn/sanitizers/"
                 NRN_SANITIZER_ENABLE_ENVIRONMENT_STRING
                 "${NRN_SANITIZER_ENABLE_ENVIRONMENT_STRING}")
  if(NRN_SANITIZER_LIBRARY_PATH)
    set(NRN_SANITIZER_LD_PRELOAD "LD_PRELOAD=${NRN_SANITIZER_LIBRARY_PATH}")
  endif()
  configure_file(bin/nrn-enable-sanitizer.in bin/nrn-enable-sanitizer @ONLY)
  install(PROGRAMS ${PROJECT_BINARY_DIR}/bin/nrn-enable-sanitizer
          DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
endif()