cmake_minimum_required(VERSION 3.14) project(snmalloc CXX) if (NOT CMAKE_BUILD_TYPE) message(STATUS "No build type selected, default to: Release") set(CMAKE_BUILD_TYPE "Release") endif() include(CheckCXXCompilerFlag) include(CheckCXXSourceCompiles) include(CheckIncludeFileCXX) include(CheckIPOSupported) include(CMakeDependentOption) # Name chosen for compatibility with CTest. option(SNMALLOC_BUILD_TESTING "Build test programs as well as shims" ON) option(SNMALLOC_HEADER_ONLY_LIBRARY "Use snmalloc has a header-only library" OFF) # Options that apply globally option(SNMALLOC_CI_BUILD "Disable features not sensible for CI" OFF) option(SNMALLOC_QEMU_WORKAROUND "Disable using madvise(DONT_NEED) to zero memory on Linux" Off) option(SNMALLOC_USE_CXX17 "Build as C++17 for legacy support." OFF) option(SNMALLOC_TRACING "Enable large quantities of debug output." OFF) option(SNMALLOC_NO_REALLOCARRAY "Build without reallocarray exported" ON) option(SNMALLOC_NO_REALLOCARR "Build without reallocarr exported" ON) option(SNMALLOC_LINK_ICF "Link with Identical Code Folding" ON) option(SNMALLOC_IPO "Link with IPO/LTO support" OFF) option(SNMALLOC_BENCHMARK_INDIVIDUAL_MITIGATIONS "Build tests and ld_preload for individual mitigations" OFF) option(SNMALLOC_ENABLE_DYNAMIC_LOADING "Build such that snmalloc can be dynamically loaded. This is not required for LD_PRELOAD, and will harm performance if enabled." OFF) option(SNMALLOC_ENABLE_WAIT_ON_ADDRESS "Use wait on address backoff strategy if it is available" ON) option(SNMALLOC_ENABLE_FUZZING "Enable fuzzing instrumentation tests" OFF) # Options that apply only if we're not building the header-only library cmake_dependent_option(SNMALLOC_RUST_SUPPORT "Build static library for rust" OFF "NOT SNMALLOC_HEADER_ONLY_LIBRARY" OFF) cmake_dependent_option(SNMALLOC_STATIC_LIBRARY "Build static libraries" ON "NOT SNMALLOC_HEADER_ONLY_LIBRARY" OFF) cmake_dependent_option(SNMALLOC_CHECK_LOADS "Perform bounds checks on the source argument to memcpy with heap objects" OFF "NOT SNMALLOC_HEADER_ONLY_LIBRARY" OFF) cmake_dependent_option(SNMALLOC_OPTIMISE_FOR_CURRENT_MACHINE "Compile for current machine architecture" Off "NOT SNMALLOC_HEADER_ONLY_LIBRARY" OFF) cmake_dependent_option(SNMALLOC_PAGEID "Set an id to memory regions" OFF "NOT SNMALLOC_PAGEID" OFF) if (NOT SNMALLOC_HEADER_ONLY_LIBRARY) # Pick a sensible default for the thread cleanup mechanism if (${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) set(SNMALLOC_CLEANUP_DEFAULT THREAD_CLEANUP) elseif (UNIX AND NOT APPLE) set(SNMALLOC_CLEANUP_DEFAULT PTHREAD_DESTRUCTORS) else () set(SNMALLOC_CLEANUP_DEFAULT CXX11_DESTRUCTORS) endif() # Specify the thread cleanup mechanism to use. set(SNMALLOC_CLEANUP ${SNMALLOC_CLEANUP_DEFAULT} CACHE STRING "The mechanism that snmalloc will use for thread destructors. Valid options are: CXX11_DESTRUCTORS (use C++11 destructors, may depend on the C++ runtime library), PTHREAD_DESTRUCTORS (use pthreads, may interact badly with C++ on some platforms, such as macOS) THREAD_CLEANUP (depend on an explicit call to _malloc_thread_cleanup on thread exit, supported by FreeBSD's threading implementation and possibly elsewhere)") set_property(CACHE SNMALLOC_CLEANUP PROPERTY STRINGS THREAD_CLEANUP PTHREAD_DESTRUCTORS CXX11_DESTRUCTORS) set(SNMALLOC_STATIC_LIBRARY_PREFIX "sn_" CACHE STRING "Static library function prefix") set(SNMALLOC_COMPILER_SUPPORT_IPO FALSE) else () unset(SNMALLOC_STATIC_LIBRARY_PREFIX CACHE) unset(SNMALLOC_CLEANUP CACHE) endif () if (NOT SNMALLOC_CLEANUP STREQUAL CXX11_DESTRUCTORS) set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "") endif() set(SNMALLOC_SANITIZER "" CACHE STRING "Use sanitizer type (undefined|thread|...)") if (SNMALLOC_SANITIZER) message(STATUS "Using sanitizer=${SNMALLOC_SANITIZER}") endif() set(SNMALLOC_MIN_ALLOC_SIZE "" CACHE STRING "Minimum allocation bytes (power of 2)") set(SNMALLOC_MIN_ALLOC_STEP_SIZE "" CACHE STRING "Minimum allocation step (power of 2)") set(SNMALLOC_PAGESIZE "" CACHE STRING "Page size in bytes") set(SNMALLOC_DEALLOC_BATCH_RING_ASSOC "" CACHE STRING "Associativity of deallocation batch cache; 0 to disable") set(SNMALLOC_DEALLOC_BATCH_RING_SET_BITS "" CACHE STRING "Logarithm of number of deallocation batch cache associativity sets") if(MSVC AND SNMALLOC_STATIC_LIBRARY AND (SNMALLOC_STATIC_LIBRARY_PREFIX STREQUAL "")) message(FATAL_ERROR "Empty static library prefix not supported on MSVC") endif() # If CheckLinkerFlag doesn't exist then provide a dummy implementation that # always fails. The fallback can be removed when we move to CMake 3.18 as the # baseline. include(CheckLinkerFlag OPTIONAL RESULT_VARIABLE CHECK_LINKER_FLAG) if (NOT CHECK_LINKER_FLAG) function(check_linker_flag) endfunction() endif () if (NOT MSVC AND NOT (SNMALLOC_CLEANUP STREQUAL CXX11_DESTRUCTORS)) # If the target compiler doesn't support -nostdlib++ then we must enable C at # the global scope for the fallbacks to work. check_linker_flag(CXX "-nostdlib++" SNMALLOC_LINKER_SUPPORT_NOSTDLIBXX) if (NOT SNMALLOC_LINKER_SUPPORT_NOSTDLIBXX AND NOT SNMALLOC_HEADER_ONLY_LIBRARY) enable_language(C) endif() endif() # Define a generator expression for things that will be enabled in either CI # builds or debug mode. set(ci_or_debug "$,$>") # malloc.h will error if you include it on FreeBSD, so this test must not # unconditionally include it. CHECK_CXX_SOURCE_COMPILES(" #if __has_include() #include #endif #if __has_include() #include #else #include #endif size_t malloc_usable_size(const void* ptr) { return 0; } int main() { return 0; } " CONST_QUALIFIED_MALLOC_USABLE_SIZE) # Some libcs might not have getentropy, e.g. it appeared in glibc 2.25 # so we need to fallback if we cannot compile this CHECK_CXX_SOURCE_COMPILES(" #if __has_include() # include #endif #if __has_include() # include #endif int main() { int entropy = 0; int res = getentropy(&entropy, sizeof(entropy)); return res; } " SNMALLOC_PLATFORM_HAS_GETENTROPY) # check if linux/random.h is available # older libcs might not have sys/random.h # but some might provide the necessary flags via linux/random.h # the __has_include macro isn't working properly on all platforms for that header # this is why we check its existence here CHECK_INCLUDE_FILE_CXX(linux/random.h SNMALLOC_HAS_LINUX_RANDOM_H) # check if futex.h is available CHECK_INCLUDE_FILE_CXX(linux/futex.h SNMALLOC_HAS_LINUX_FUTEX_H) # Provide as function so other projects can reuse # FIXME: This modifies some variables that may or may not be the ones that # provide flags and so is broken by design. It should be removed once Verona # no longer uses it. function(warnings_high) if(MSVC) # Force to always compile with W4 if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]") string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") endif() # /Wv18 is required for the annotation to force inline a lambda. add_compile_options(/WX /wd4127 /wd4324 /wd4201) else() if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wsign-conversion -Wconversion) endif () add_compile_options(-Wall -Wextra -Werror -Wundef) endif() endfunction() function(clangformat_targets) # The clang-format tool is installed under a variety of different names. Try # to find a sensible one. Only look for versions 9 explicitly - we don't # know whether our clang-format file will work with newer versions of the # tool. It does not work with older versions as AfterCaseLabel is not supported # in earlier versions. find_program(CLANG_FORMAT NAMES clang-format150 clang-format-15) # If we've found a clang-format tool, generate a target for it, otherwise emit # a warning. if (${CLANG_FORMAT} STREQUAL "CLANG_FORMAT-NOTFOUND") message(WARNING "Not generating clangformat target, no clang-format tool found") else () message(STATUS "Generating clangformat target using ${CLANG_FORMAT}") file(GLOB_RECURSE ALL_SOURCE_FILES CONFIGURE_DEPENDS src/*.cc src/*.h src/*.hh) # clangformat does not yet understand concepts well; for the moment, don't # ask it to format them. See https://reviews.llvm.org/D79773 list(FILTER ALL_SOURCE_FILES EXCLUDE REGEX "src/[^/]*/[^/]*_concept\.h$") add_custom_target( clangformat COMMAND ${CLANG_FORMAT} -i ${ALL_SOURCE_FILES}) endif() endfunction() # The main target for snmalloc. This is the exported target for the # header-only configuration and is used as a dependency for all of the builds # that compile anything. add_library(snmalloc INTERFACE) if(SNMALLOC_USE_CXX17) target_compile_features(snmalloc INTERFACE cxx_std_17) else() target_compile_features(snmalloc INTERFACE cxx_std_20) endif() if(SNMALLOC_ENABLE_WAIT_ON_ADDRESS) target_compile_definitions(snmalloc INTERFACE SNMALLOC_USE_WAIT_ON_ADDRESS=1) else() target_compile_definitions(snmalloc INTERFACE SNMALLOC_USE_WAIT_ON_ADDRESS=0) endif() # https://learn.microsoft.com/en-us/cpp/build/reference/zc-cplusplus if(MSVC) target_compile_options(snmalloc INTERFACE "/Zc:__cplusplus") endif() # Add header paths. target_include_directories(snmalloc INTERFACE $ $) if(NOT MSVC) find_package(Threads REQUIRED COMPONENTS snmalloc) target_link_libraries(snmalloc INTERFACE ${CMAKE_THREAD_LIBS_INIT} $<$:atomic>) endif() if (WIN32) set(WIN8COMPAT FALSE CACHE BOOL "Avoid Windows 10 APIs") target_compile_definitions(snmalloc INTERFACE $<$:WINVER=0x0603>) # VirtualAlloc2 is exposed by mincore.lib, not Kernel32.lib (as the # documentation says) target_link_libraries(snmalloc INTERFACE $<$>:mincore>) message(STATUS "snmalloc: Avoiding Windows 10 APIs is ${WIN8COMPAT}") endif() # Detect support for cmpxchg16b; Werror is needed to make sure mcx16 must be used by targets check_cxx_compiler_flag("-Werror -Wextra -Wall -mcx16" SNMALLOC_COMPILER_SUPPORT_MCX16) if(SNMALLOC_COMPILER_SUPPORT_MCX16) target_compile_options(snmalloc INTERFACE $<$:-mcx16>) endif() if (NOT SNMALLOC_HEADER_ONLY_LIBRARY AND SNMALLOC_IPO) check_ipo_supported(RESULT HAS_IPO) if (HAS_IPO) set(SNMALLOC_COMPILER_SUPPORT_IPO TRUE) endif() endif() # Helper function that conditionally defines a macro for the build target if # the CMake variable of the same name is set. function(add_as_define FLAG) target_compile_definitions(snmalloc INTERFACE $<$:${FLAG}>) endfunction() function(add_as_define_value KEY) if (NOT ${${KEY}} STREQUAL "") target_compile_definitions(snmalloc INTERFACE ${KEY}=${${KEY}}) endif () endfunction() add_as_define(SNMALLOC_QEMU_WORKAROUND) add_as_define(SNMALLOC_TRACING) add_as_define(SNMALLOC_CI_BUILD) add_as_define(SNMALLOC_PLATFORM_HAS_GETENTROPY) add_as_define(SNMALLOC_HAS_LINUX_RANDOM_H) add_as_define(SNMALLOC_HAS_LINUX_FUTEX_H) if (SNMALLOC_NO_REALLOCARRAY) add_as_define(SNMALLOC_NO_REALLOCARRAY) endif() if (SNMALLOC_NO_REALLOCARR) add_as_define(SNMALLOC_NO_REALLOCARR) endif() add_as_define_value(SNMALLOC_MIN_ALLOC_SIZE) add_as_define_value(SNMALLOC_MIN_ALLOC_STEP_SIZE) add_as_define_value(SNMALLOC_DEALLOC_BATCH_RING_ASSOC) add_as_define_value(SNMALLOC_DEALLOC_BATCH_RING_SET_BITS) add_as_define_value(SNMALLOC_PAGESIZE) target_compile_definitions(snmalloc INTERFACE $<$:MALLOC_USABLE_SIZE_QUALIFIER=const>) # In debug and CI builds, link the backtrace library so that we can get stack # traces on errors. find_package(Backtrace) if(${Backtrace_FOUND}) target_compile_definitions(snmalloc INTERFACE $<${ci_or_debug}:SNMALLOC_BACKTRACE_HEADER="${Backtrace_HEADER}">) target_link_libraries(snmalloc INTERFACE $<${ci_or_debug}:${Backtrace_LIBRARIES}>) target_include_directories(snmalloc INTERFACE $<${ci_or_debug}:${Backtrace_INCLUDE_DIRS}>) endif() if(MSVC) target_compile_definitions(snmalloc INTERFACE -D_HAS_EXCEPTIONS=0) else() # All symbols are always dynamic on haiku and -rdynamic is redundant (and unsupported). if (NOT CMAKE_SYSTEM_NAME STREQUAL "Haiku") # Get better stack traces in CI and debug builds. target_link_options(snmalloc INTERFACE $<${ci_or_debug}:-rdynamic>) endif() endif() if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") check_linker_flag(CXX "-Wl,--no-undefined" SNMALLOC_LINKER_SUPPORT_NO_ALLOW_SHLIB_UNDEF) endif() function(add_warning_flags name) target_compile_options(${name} PRIVATE $<$:/Zi /W4 /WX /wd4127 /wd4324 /wd4201> $<$,$>>:-fno-exceptions -fno-rtti -Wall -Wextra -Werror -Wundef> $<$:-Wsign-conversion -Wconversion>) target_link_options(${name} PRIVATE $<$:-Wl,--no-undefined> $<$:$<${ci_or_debug}:/DEBUG>>) endfunction() # To build with just the header library target define SNMALLOC_HEADER_ONLY_LIBRARY if(NOT SNMALLOC_HEADER_ONLY_LIBRARY) function(subdirlist result curdir) file(GLOB children CONFIGURE_DEPENDS LIST_DIRECTORIES true RELATIVE ${curdir} ${curdir}/* ) set(dirlist "") foreach(child ${children}) if(IS_DIRECTORY ${curdir}/${child}) list(APPEND dirlist ${child}) endif() endforeach() set(${result} ${dirlist} PARENT_SCOPE) endfunction() set(TESTDIR ${CMAKE_CURRENT_SOURCE_DIR}/src/test) if(SNMALLOC_BUILD_TESTING) enable_testing() subdirlist(TEST_CATEGORIES ${TESTDIR}) else() set(TEST_CATEGORIES "") endif() list(REVERSE TEST_CATEGORIES) if (${SNMALLOC_CLEANUP} STREQUAL THREAD_CLEANUP) set(TEST_CLEANUP PTHREAD_DESTRUCTORS) else () set(TEST_CLEANUP ${SNMALLOC_CLEANUP}) endif() function(make_tests TAG DEFINES) foreach(TEST_CATEGORY ${TEST_CATEGORIES}) message(STATUS "Adding ${TAG}/${TEST_CATEGORY} tests") subdirlist(TESTS ${TESTDIR}/${TEST_CATEGORY}) foreach(TEST ${TESTS}) unset(SRC) aux_source_directory(${TESTDIR}/${TEST_CATEGORY}/${TEST} SRC) set(TESTNAME "${TEST_CATEGORY}-${TEST}-${TAG}") add_executable(${TESTNAME} ${SRC}) if(SNMALLOC_SANITIZER) target_compile_options(${TESTNAME} PRIVATE -g -fsanitize=${SNMALLOC_SANITIZER} -fno-omit-frame-pointer) target_link_libraries(${TESTNAME} -fsanitize=${SNMALLOC_SANITIZER}) if (${SNMALLOC_SANITIZER} MATCHES "thread") target_compile_definitions(${TESTNAME} PRIVATE SNMALLOC_THREAD_SANITIZER_ENABLED) endif() endif() add_warning_flags(${TESTNAME}) target_link_libraries(${TESTNAME} snmalloc) target_compile_definitions(${TESTNAME} PRIVATE "SNMALLOC_USE_${TEST_CLEANUP}") if (NOT DEFINES STREQUAL " ") target_compile_definitions(${TESTNAME} PRIVATE ${DEFINES}) endif() if (${TEST} MATCHES "release-.*") message(VERBOSE "Adding test: ${TESTNAME} only for release configs") add_test(NAME ${TESTNAME} COMMAND ${TESTNAME} CONFIGURATIONS "Release") else() message(VERBOSE "Adding test: ${TESTNAME}") add_test(${TESTNAME} ${TESTNAME}) endif() if (${TEST_CATEGORY} MATCHES "perf") message(VERBOSE "Single threaded test: ${TESTNAME}") set_tests_properties(${TESTNAME} PROPERTIES PROCESSORS 4) endif() if(WIN32) # On Windows these tests use a lot of memory as it doesn't support # lazy commit. if (${TEST} MATCHES "two_alloc_types") message(VERBOSE "Single threaded test: ${TESTNAME}") set_tests_properties(${TESTNAME} PROPERTIES PROCESSORS 4) endif() if (${TEST} MATCHES "fixed_region") message(VERBOSE "Single threaded test: ${TESTNAME}") set_tests_properties(${TESTNAME} PROPERTIES PROCESSORS 4) endif() if (${TEST} MATCHES "memory") message(VERBOSE "Single threaded test: ${TESTNAME}") set_tests_properties(${TESTNAME} PROPERTIES PROCESSORS 4) endif() endif() endforeach() endforeach() endfunction() if(NOT (DEFINED SNMALLOC_LINKER_FLAVOUR) OR ("${SNMALLOC_LINKER_FLAVOUR}" MATCHES "^$")) # Linker not specified externally; probe to see if we can make lld work set(CMAKE_REQUIRED_LINK_OPTIONS -fuse-ld=lld -Wl,--icf=all) check_cxx_source_compiles("int main() { return 1; }" LLD_WORKS) if (LLD_WORKS) message(STATUS "Using LLD to link snmalloc shims") endif() elseif(SNMALLOC_LINKER_FLAVOUR STREQUAL "lld") # Linker specified externally to be lld; assume it works and that the flags # have also been set for us set(LLD_WORKS TRUE) else() # Linker specified externally as something other than lld; presume it # doesn't work and don't add its flags, below set(LLD_WORKS FALSE) endif() function(add_shim name type) add_library(${name} ${type} ${ARGN}) target_link_libraries(${name} snmalloc) set_target_properties(${name} PROPERTIES CXX_VISIBILITY_PRESET hidden INTERPROCEDURAL_OPTIMIZATION ${SNMALLOC_COMPILER_SUPPORT_IPO}) target_compile_definitions(${name} PRIVATE "SNMALLOC_USE_${SNMALLOC_CLEANUP}") add_warning_flags(${name}) if(NOT MSVC) target_compile_definitions(${name} PRIVATE "SNMALLOC_EXPORT=__attribute__((visibility(\"default\")))") target_compile_options(${name} PRIVATE -fomit-frame-pointer -ffunction-sections) check_cxx_compiler_flag("-Werror -Wextra -Wall -mprfchw" SUPPORT_PREFETCH_WRITE) if (SUPPORT_PREFETCH_WRITE) target_compile_options(${name} PRIVATE -mprfchw) endif() # Static TLS model is unsupported on Haiku. if ((NOT CMAKE_SYSTEM_NAME STREQUAL "Haiku") AND (NOT SNMALLOC_ENABLE_DYNAMIC_LOADING)) message(STATUS "snmalloc: Using static TLS model") target_compile_options(${name} PRIVATE -ftls-model=initial-exec) target_compile_options(${name} PRIVATE $<$:-g>) endif() if(SNMALLOC_OPTIMISE_FOR_CURRENT_MACHINE) check_cxx_compiler_flag(-march=native SUPPORT_MARCH_NATIVE) if (SUPPORT_MARCH_NATIVE) target_compile_options(${name} PRIVATE -march=native) else() message(WARNING "Compiler does not support `-march=native` required by SNMALLOC_OPTIMISE_FOR_CURRENT_MACHINE") endif() endif() # Ensure that we do not link against C++ stdlib when compiling shims. # If the compiler supports excluding the C++ stdlib implementation, use # it. Otherwise, fall back to linking the library as if it were C, which # has roughly the same effect. if (NOT ${SNMALLOC_CLEANUP} STREQUAL CXX11_DESTRUCTORS) check_linker_flag(CXX "-nostdlib++" SNMALLOC_LINKER_SUPPORT_NOSTDLIBXX) if (SNMALLOC_LINKER_SUPPORT_NOSTDLIBXX) target_link_options(${name} PRIVATE -nostdlib++) else() set_target_properties(${name} PROPERTIES LINKER_LANGUAGE C) endif() endif() # Remove all the duplicate new/malloc and free/delete definitions target_link_options(${name} PRIVATE $<$:$<$:-Wl,--icf=all> -fuse-ld=lld>) endif() target_compile_definitions(${name} PRIVATE SNMALLOC_CHECK_LOADS=$,true,false>) target_compile_definitions(${name} PRIVATE SNMALLOC_PAGEID=$,true,false>) install(TARGETS ${name} EXPORT snmallocConfig) endfunction() set(SHIM_FILES src/snmalloc/override/malloc.cc src/snmalloc/override/new.cc) set(SHIM_FILES_MEMCPY src/snmalloc/override/memcpy.cc) add_shim(snmalloc-new-override STATIC src/snmalloc/override/new.cc) if (SNMALLOC_STATIC_LIBRARY) add_shim(snmallocshim-static STATIC ${SHIM_FILES}) target_compile_definitions(snmallocshim-static PRIVATE SNMALLOC_STATIC_LIBRARY_PREFIX=${SNMALLOC_STATIC_LIBRARY_PREFIX}) endif () if(NOT WIN32) add_shim(snmallocshim SHARED ${SHIM_FILES}) add_shim(snmallocshim-checks-memcpy-only SHARED ${SHIM_FILES} ${SHIM_FILES_MEMCPY}) add_shim(snmallocshim-checks SHARED ${SHIM_FILES} ${SHIM_FILES_MEMCPY}) target_compile_definitions(snmallocshim-checks PRIVATE SNMALLOC_CHECK_CLIENT) endif() if(SNMALLOC_RUST_SUPPORT) add_shim(snmallocshim-rust STATIC src/snmalloc/override/rust.cc) add_shim(snmallocshim-checks-rust STATIC src/snmalloc/override/rust.cc) target_compile_definitions(snmallocshim-checks-rust PRIVATE SNMALLOC_CHECK_CLIENT) endif() if (SNMALLOC_BUILD_TESTING) if (WIN32 OR (CMAKE_SYSTEM_NAME STREQUAL NetBSD) OR (CMAKE_SYSTEM_NAME STREQUAL OpenBSD) OR (CMAKE_SYSTEM_NAME STREQUAL SunOS)) # Windows does not support aligned allocation well enough # for pass through. # NetBSD, OpenBSD and DragonFlyBSD do not support malloc*size calls. set(FLAVOURS fast;check) else() set(FLAVOURS fast;check;malloc) endif() foreach(FLAVOUR ${FLAVOURS}) if (${FLAVOUR} STREQUAL "malloc") set(DEFINES SNMALLOC_PASS_THROUGH) endif() if (${FLAVOUR} STREQUAL "check") set(DEFINES SNMALLOC_CHECK_CLIENT) endif() if (${FLAVOUR} STREQUAL "fast") set(DEFINES " ") endif() make_tests(${FLAVOUR} ${DEFINES}) endforeach() endif() if (SNMALLOC_BENCHMARK_INDIVIDUAL_MITIGATIONS) set (MITIGATIONS metadata_protection; pal_enforce_access; random_pagemap; sanity_checks; freelist_forward_edge; freelist_backward_edge; freelist_teardown_validate; reuse_LIFO; random_larger_thresholds; random_initial; random_preserve; random_extra_slab) foreach (MITIGATION ${MITIGATIONS}) set(DEFINES "SNMALLOC_CHECK_CLIENT_MITIGATIONS=${MITIGATION}") add_shim(snmallocshim-${MITIGATION} SHARED ${SHIM_FILES}) target_compile_definitions(snmallocshim-${MITIGATION} PRIVATE ${DEFINES}) if (SNMALLOC_BUILD_TESTING) make_tests(${MITIGATION} ${DEFINES}) endif() endforeach() set(MITIGATIONSET "no_checks") set(COUNT 0) foreach (MITIGATION ${MITIGATIONS}) MATH(EXPR COUNT "${COUNT} + 1") set(MITIGATIONNAME "mitigations-${COUNT}") set(MITIGATIONSET "${MITIGATIONSET}+${MITIGATION}") message(STATUS "MITIGATIONSET: ${COUNT} -> ${MITIGATIONSET}") set(DEFINES "-DSNMALLOC_CHECK_CLIENT_MITIGATIONS=${MITIGATIONSET}") add_shim(snmallocshim-${MITIGATIONNAME} SHARED ${SHIM_FILES}) target_compile_definitions(snmallocshim-${MITIGATIONNAME} PRIVATE ${DEFINES}) if (SNMALLOC_BUILD_TESTING) make_tests(${MITIGATIONNAME} ${DEFINES}) endif() endforeach() endif() if (SNMALLOC_BUILD_TESTING) clangformat_targets() endif () endif() install(TARGETS snmalloc EXPORT snmallocConfig) install(TARGETS EXPORT snmallocConfig DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/snmalloc) install(DIRECTORY src/snmalloc/aal DESTINATION include/snmalloc) install(DIRECTORY src/snmalloc/ds DESTINATION include/snmalloc) install(DIRECTORY src/snmalloc/override DESTINATION include/snmalloc) install(DIRECTORY src/snmalloc/backend DESTINATION include/snmalloc) install(DIRECTORY src/snmalloc/mem DESTINATION include/snmalloc) install(DIRECTORY src/snmalloc/pal DESTINATION include/snmalloc) install(FILES src/test/measuretime.h src/test/opt.h src/test/setup.h src/test/usage.h src/test/xoroshiro.h DESTINATION include/snmalloc/test ) install(FILES src/snmalloc/snmalloc.h;src/snmalloc/snmalloc_core.h;src/snmalloc/snmalloc_front.h DESTINATION include/snmalloc) install(EXPORT snmallocConfig FILE snmalloc-config.cmake NAMESPACE snmalloc:: DESTINATION "share/snmalloc" ) if (SNMALLOC_ENABLE_FUZZING) add_subdirectory(fuzzing) endif()