1 # =========================================================================== 2 # http://www.gnu.org/software/autoconf-archive/ax_sanitizers.html 3 # =========================================================================== 4 # 5 # SYNOPSIS 6 # 7 # AX_SANITIZERS([SANITIZERS], [ENABLED-BY-DEFAULT], [ACTION-SUCCESS]) 8 # 9 # DESCRIPTION 10 # 11 # Offers users to enable one or more sanitizers (see 12 # https://github.com/google/sanitizers) with the corresponding 13 # --enable-<sanitizer>-sanitizer option. 14 # 15 # SANITIZERS is a whitespace-separated list of sanitizers to offer via 16 # --enable-<sanitizer>-sanitizer options, e.g. "address memory" for the 17 # address sanitizer and the memory sanitizer. If SANITIZERS is not specified, 18 # all known sanitizers to AX_SANITIZERS will be offered, which at the time of 19 # writing are "address memory undefined". 20 # NOTE that SANITIZERS is expanded at autoconf time, not at configure time, 21 # i.e. you cannot use shell variables in SANITIZERS. 22 # 23 # ENABLED-BY-DEFAULT is a whitespace-separated list of sanitizers which 24 # should be enabled by default, e.g. "memory undefined". Note that not all 25 # sanitizers can be combined, e.g. memory sanitizer cannot be enabled when 26 # address sanitizer is already enabled. 27 # Set ENABLED-BY-DEFAULT to a single whitespace in order to disable all 28 # sanitizers by default. 29 # ENABLED-BY-DEFAULT is expanded at configure time, so you can use shell 30 # variables. 31 # 32 # ACTION-SUCCESS allows to specify shell commands to execute on success, i.e. 33 # when one of the sanitizers was successfully enabled. This is a good place 34 # to call AC_DEFINE for any precompiler constants you might need to make your 35 # code play nice with sanitizers. 36 # 37 # The variable ax_enabled_sanitizers contains a whitespace-separated list of 38 # all enabled sanitizers, so that you can print them at the end of configure, 39 # if you wish. 40 # 41 # The additional --enable-sanitizers option allows users to enable/disable 42 # all sanitizers, effectively overriding ENABLED-BY-DEFAULT. 43 # 44 # EXAMPLES 45 # 46 # AX_SANITIZERS([address]) 47 # dnl offer users to enable address sanitizer via --enable-address-sanitizer 48 # 49 # is_debug_build=… 50 # if test "x$is_debug_build" = "xyes"; then 51 # default_sanitizers="address memory" 52 # else 53 # default_sanitizers= 54 # fi 55 # AX_SANITIZERS([address memory], [$default_sanitizers]) 56 # dnl enable address sanitizer and memory sanitizer by default for debug 57 # dnl builds, e.g. when building from git instead of a dist tarball. 58 # 59 # AX_SANITIZERS(, , [ 60 # AC_DEFINE([SANITIZERS_ENABLED], 61 # [], 62 # [At least one sanitizer was enabled])]) 63 # dnl enable all sanitizers known to AX_SANITIZERS by default and set the 64 # dnl SANITIZERS_ENABLED precompiler constant. 65 # 66 # AX_SANITIZERS(, [ ]) 67 # dnl provide all sanitizers, but enable none by default. 68 # 69 # LICENSE 70 # 71 # Copyright (c) 2016 Michael Stapelberg <michael@i3wm.org> 72 # Copyright (c) 2021 Raymond Li <i3lock-color@raymond.li> 73 # 74 # Copying and distribution of this file, with or without modification, 75 # are permitted in any medium without royalty provided the copyright 76 # notice and this notice are preserved. This file is offered as-is, 77 # without any warranty. 78 79 AC_DEFUN([AX_SANITIZERS], 80 [AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG]) 81 AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) 82 AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) 83 AC_ARG_ENABLE(sanitizers, 84 AS_HELP_STRING( 85 [--enable-sanitizers], 86 [enable all known sanitizers]), 87 [ax_sanitizers_default=$enableval], 88 [ax_sanitizers_default=]) 89 ax_enabled_sanitizers= 90 m4_foreach_w([mysan], m4_default($1, [address memory undefined]), [ 91 dnl If ax_sanitizers_default is unset, i.e. the user neither explicitly 92 dnl enabled nor explicitly disabled all sanitizers, we get the default value 93 dnl for this sanitizer based on whether it is listed in ENABLED-BY-DEFAULT. 94 AS_IF([test "x$ax_sanitizers_default" = "x"], [dnl 95 ax_sanitizer_default= 96 for mycheck in m4_default([$2], [address memory undefined]); do 97 AS_IF([test "x$mycheck" = "x[]mysan"], [ax_sanitizer_default=yes]) 98 done 99 AS_IF([test "x$ax_sanitizer_default" = "x"], [ax_sanitizer_default=no]) 100 ], 101 [ax_sanitizer_default=$ax_sanitizers_default]) 102 AC_ARG_ENABLE(mysan[]-sanitizer, 103 AS_HELP_STRING( 104 [--enable-[]mysan[]-sanitizer], 105 [enable -fsanitize=mysan]), 106 [ax_sanitizer_enabled=$enableval], 107 [ax_sanitizer_enabled=$ax_sanitizer_default]) 108 109 AS_IF([test "x$ax_sanitizer_enabled" = "xyes"], [ 110 dnl Not using AX_APPEND_COMPILE_FLAGS and AX_APPEND_LINK_FLAGS because they 111 dnl lack the ability to specify ACTION-SUCCESS. 112 AX_CHECK_COMPILE_FLAG([-fsanitize=[]mysan], [ 113 AX_CHECK_LINK_FLAG([-fsanitize=[]mysan], [ 114 AX_APPEND_FLAG([-fsanitize=[]mysan], []) 115 dnl If and only if libtool is being used, LDFLAGS needs to contain -Wc,-fsanitize=…. 116 dnl See e.g. https://sources.debian.net/src/systemd/231-7/configure.ac/?hl=128#L135 117 dnl TODO: how can recognize that situation and add -Wc,? 118 AX_APPEND_FLAG([-fsanitize=[]mysan], [LDFLAGS]) 119 dnl TODO: add -fPIE -pie for memory 120 # -fno-omit-frame-pointer results in nicer stack traces in error 121 # messages, see http://clang.llvm.org/docs/AddressSanitizer.html#usage 122 AX_CHECK_COMPILE_FLAG([-fno-omit-frame-pointer], [ 123 AX_APPEND_FLAG([-fno-omit-frame-pointer], [])]) 124 dnl TODO: at least for clang, we should specify exactly -O1, not -O2 or -O0, so that performance is reasonable but stacktraces are not tampered with (due to inlining), see http://clang.llvm.org/docs/AddressSanitizer.html#usage 125 m4_default([$3], :) 126 ax_enabled_sanitizers="[]mysan $ax_enabled_sanitizers" 127 ]) 128 ]) 129 ]) 130 ])dnl 131 ])dnl AX_SANITIZERS
