CMake cleanup. (#384)

Modernise and tidy the CMake a bit:

 - Use generator expressions for a lot of conditionals so that things
   are more reliable with multi-config generators (and less verbose).
 - Remove C as a needed language.  None of the code was C but we were
   using C to test if headers worked.  This was fragile because a build
   with `CMAKE_CXX_COMPILER` set might have checked things compiled with
   the system C compiler and then failed when the specified C++ compiler
   used different headers.
 - Rename the `BACKTRACE_HEADER` macro to `SNMALLOC_BACKTRACE_HEADER`.
   This is exposed into code that consumes snmalloc and so should be
   'namespaced' (to the degree that's possible with C macros).
 - Clean up the options and use dependent options to hide options 
   that are not always relevant.
 - Use functions instead of macros for better variable scoping.
 - Factor out some duplicated bits into functions.
 - Update to the latest way of telling CMake to use C++17 or C++20.
 - Migrate everything that's setting global properties to setting only
   per-target properties.
 - Link with -nostdlib++ if it's available.  If it isn't, fall back to
   enabling the C language and linking with the C compiler.
 - Make the per-test log messages verbose outputs.  These kept scrolling
   important messages off the top of the screen for me.
 - Make building as a header-only library a public option.
 - Add install targets that install all of the headers and provide a
   config option.  This works with the header-only configuration for
   integration with things like vcpkg.
 - Fix a missing `#endif` in the `malloc_useable_size` check.  This was
   failing co compile on all platforms because of the missing `#endif`.
 - Bump the minimum version to 3.14 so that we have access to
   target_link_options.  This is necessary to use generator expressions
   for linker flags.
 - Make the linker error if the shim libraries depend on symbols that
   are not defined in the explicitly-provided libraries.
 - Make the old-Ubuntu CI jobs use C++17 explicitly (previously CMake 
   was silently ignoring the fact that the compiler didn't support C++20)
 - Fix errors found by the more aggressive linking mode.

With these changes, it's now possible to install snmalloc and then, in
another project, do something like this:

```cmake
find_package(snmalloc CONFIG REQUIRED)
target_link_libraries(t1 snmalloc::snmalloc)
target_link_libraries(t2 snmalloc::snmallocshim-static)
```

In this example, `t1` gets all of the compile flags necessary to include
snmalloc headers for its build configuration.  `t2` is additionally
linked to the snmalloc static shim library.
This commit is contained in:
David Chisnall
2021-09-03 11:31:05 +01:00
committed by GitHub
parent aedb666cdd
commit c70c23ad74
5 changed files with 237 additions and 149 deletions

View File

@@ -18,12 +18,13 @@ jobs:
# Build each combination of OS and release/debug variants
os: [ "ubuntu-latest", "ubuntu-18.04", "macos-11", "macos-10.15", "freebsd-12.2", "freebsd-13.0" ]
build-type: [ Release, Debug ]
extra-cmake-flags: [ " " ]
extra-cmake-flags: [ "" ]
# Modify the complete matrix
include:
# Provide the dependency installation for each platform
- os: "ubuntu-18.04"
dependencies: "sudo apt install ninja-build"
cmake-flags: "-DSNMALLOC_USE_CXX17=ON"
- os: "ubuntu-latest"
dependencies: "sudo apt install ninja-build"
- os: "macos-11"
@@ -68,7 +69,7 @@ jobs:
- name: Install build dependencies
run: ${{ matrix.dependencies }}
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.build-type}} -G Ninja ${{ matrix.extra-cmake-flags }}
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.build-type}} -G Ninja ${{ matrix.cmake-flags }} ${{ matrix.extra-cmake-flags }}
# Build with a nice ninja status line
- name: Build
working-directory: ${{github.workspace}}/build
@@ -201,7 +202,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build
run: cmake -B ${{github.workspace}}/build -DSNMALLOC_USE_CXX17=ON
- name: Install clang-tidy
run: sudo apt install clang-tidy-9
# Run the clang-format check and error if it generates a diff
@@ -213,7 +214,7 @@ jobs:
git diff --exit-code
- name: Run clang-tidy
run: |
clang-tidy-9 src/override/malloc.cc -header-filter="`pwd`/*" -warnings-as-errors='*' -export-fixes=tidy.fail -- -std=c++17 -mcx16 -DSNMALLOC_PLATFORM_HAS_GETENTROPY=0
clang-tidy-9 src/override/malloc.cc -header-filter="`pwd`/*" -warnings-as-errors='*' -export-fixes=tidy.fail -- -std=c++17 -mcx16 -DSNMALLOC_PLATFORM_HAS_GETENTROPY=0
if [ -f tidy.fail ] ; then
cat tidy.fail
exit 1

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.8)
project(snmalloc C CXX)
cmake_minimum_required(VERSION 3.14)
project(snmalloc CXX)
if (NOT CMAKE_BUILD_TYPE)
message(STATUS "No build type selected, default to: Release")
@@ -7,25 +7,70 @@ if (NOT CMAKE_BUILD_TYPE)
endif()
include(CheckCXXCompilerFlag)
include(CheckCSourceCompiles)
include(CheckCXXSourceCompiles)
include(CMakeDependentOption)
option(SNMALLOC_HEADER_ONLY_LIBRARY "Use snmalloc has a header-only library" OFF)
# Options that apply globally
option(USE_SNMALLOC_STATS "Track allocation stats" OFF)
option(SNMALLOC_CI_BUILD "Disable features not sensible for CI" OFF)
option(EXPOSE_EXTERNAL_PAGEMAP "Expose the global pagemap" OFF)
option(EXPOSE_EXTERNAL_RESERVE "Expose an interface to reserve memory using the default memory provider" OFF)
option(SNMALLOC_RUST_SUPPORT "Build static library for rust" OFF)
option(SNMALLOC_STATIC_LIBRARY "Build static libraries" ON)
option(SNMALLOC_QEMU_WORKAROUND "Disable using madvise(DONT_NEED) to zero memory on Linux" Off)
option(SNMALLOC_OPTIMISE_FOR_CURRENT_MACHINE "Compile for current machine architecture" Off)
set(SNMALLOC_STATIC_LIBRARY_PREFIX "sn_" CACHE STRING "Static library function prefix")
option(SNMALLOC_USE_CXX17 "Build as C++17 for legacy support." OFF)
option(SNMALLOC_USE_PTHREAD_DESTRUCTORS "Build using pthread destructors. Reduces the system dependencies, but may interact badly with C++ on some platforms." 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_OPTIMISE_FOR_CURRENT_MACHINE "Compile for current machine architecture" Off "NOT SNMALLOC_HEADER_ONLY_LIBRARY" 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")
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()
# 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 "$<OR:$<BOOL:${SNMALLOC_CI_BUILD}>,$<CONFIG:Debug>>")
# malloc.h will error if you include it on FreeBSD, so this test must not
# unconditionally include it.
CHECK_C_SOURCE_COMPILES("
CHECK_CXX_SOURCE_COMPILES("
#if __has_include(<malloc_np.h>)
#include <malloc_np.h>
#endif
#if __has_include(<malloc/malloc.h>)
#include <malloc/malloc.h>
#else
@@ -35,9 +80,9 @@ size_t malloc_usable_size(const void* ptr) { return 0; }
int main() { return 0; }
" CONST_QUALIFIED_MALLOC_USABLE_SIZE)
# older libcs might not have getentropy, e.g. it appeared in gliobc 2.25
# 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_C_SOURCE_COMPILES("
CHECK_CXX_SOURCE_COMPILES("
#if __has_include(<unistd.h>)
# include <unistd.h>
#endif
@@ -51,8 +96,11 @@ int main() {
}
" SNMALLOC_PLATFORM_HAS_GETENTROPY)
# Provide as macro so other projects can reuse
macro(warnings_high)
# 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]")
@@ -68,9 +116,9 @@ macro(warnings_high)
endif ()
add_compile_options(-Wall -Wextra -Werror -Wundef)
endif()
endmacro()
endfunction()
macro(clangformat_targets)
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
@@ -95,118 +143,96 @@ macro(clangformat_targets)
-i
${ALL_SOURCE_FILES})
endif()
endmacro()
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)
# Have to set this globally, as can't be set on an interface target.
if(SNMALLOC_USE_CXX17)
set(CMAKE_CXX_STANDARD 17)
target_compile_definitions(snmalloc INTERFACE -DSNMALLOC_USE_CXX17)
target_compile_features(snmalloc INTERFACE cxx_std_17)
else()
set(CMAKE_CXX_STANDARD 20)
target_compile_features(snmalloc INTERFACE cxx_std_20)
endif()
# The main target for snmalloc
add_library(snmalloc_lib INTERFACE)
target_include_directories(snmalloc_lib INTERFACE src/)
if(SNMALLOC_USE_CXX17)
target_compile_definitions(snmalloc_lib INTERFACE -DSNMALLOC_USE_CXX17)
endif()
# Add header paths.
target_include_directories(snmalloc
INTERFACE
$<INSTALL_INTERFACE:include/snmalloc>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>)
if(NOT MSVC)
find_package(Threads REQUIRED COMPONENTS snmalloc_lib)
target_link_libraries(snmalloc_lib INTERFACE ${CMAKE_THREAD_LIBS_INIT})
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
target_link_libraries(snmalloc_lib INTERFACE atomic)
endif()
find_package(Threads REQUIRED COMPONENTS snmalloc)
target_link_libraries(snmalloc INTERFACE
${CMAKE_THREAD_LIBS_INIT} $<$<CXX_COMPILER_ID:GNU>:atomic>)
endif()
if (WIN32)
set(WIN8COMPAT FALSE CACHE BOOL "Avoid Windows 10 APIs")
if (WIN8COMPAT)
target_compile_definitions(snmalloc_lib INTERFACE -DWINVER=0x0603)
message(STATUS "snmalloc: Avoiding Windows 10 APIs")
else()
message(STATUS "snmalloc: Using Windows 10 APIs")
# VirtualAlloc2 is exposed by mincore.lib, not Kernel32.lib (as the
# documentation says)
target_link_libraries(snmalloc_lib INTERFACE mincore)
endif()
target_compile_definitions(snmalloc INTERFACE $<$<BOOL:${WIN8COMPAT}>:WINVER=0x0603>)
# VirtualAlloc2 is exposed by mincore.lib, not Kernel32.lib (as the
# documentation says)
target_link_libraries(snmalloc INTERFACE $<$<NOT:$<BOOL:${WIN8COMPAT}>>: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
# 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_lib INTERFACE $<$<COMPILE_LANGUAGE:CXX>:-mcx16>)
target_compile_options(snmalloc INTERFACE $<$<COMPILE_LANGUAGE:CXX>:-mcx16>)
endif()
if(USE_SNMALLOC_STATS)
target_compile_definitions(snmalloc_lib INTERFACE -DUSE_SNMALLOC_STATS)
# 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 $<$<BOOL:${${FLAG}}>:${FLAG}>)
endfunction()
add_as_define(USE_SNMALLOC_STATS)
add_as_define(SNMALLOC_QEMU_WORKAROUND)
add_as_define(SNMALLOC_CI_BUILD)
add_as_define(SNMALLOC_PLATFORM_HAS_GETENTROPY)
target_compile_definitions(snmalloc INTERFACE $<$<BOOL:CONST_QUALIFIED_MALLOC_USABLE_SIZE>: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(SNMALLOC_QEMU_WORKAROUND)
target_compile_definitions(snmalloc_lib INTERFACE -DSNMALLOC_QEMU_WORKAROUND)
endif()
if(SNMALLOC_CI_BUILD)
target_compile_definitions(snmalloc_lib INTERFACE -DSNMALLOC_CI_BUILD)
endif()
if(SNMALLOC_PLATFORM_HAS_GETENTROPY)
target_compile_definitions(snmalloc_lib INTERFACE -DSNMALLOC_PLATFORM_HAS_GETENTROPY)
endif()
if(SNMALLOC_USE_PTHREAD_DESTRUCTORS)
target_compile_definitions(snmalloc_lib INTERFACE -DSNMALLOC_USE_PTHREAD_DESTRUCTORS)
endif()
if(CONST_QUALIFIED_MALLOC_USABLE_SIZE)
target_compile_definitions(snmalloc_lib INTERFACE -DMALLOC_USABLE_SIZE_QUALIFIER=const)
endif()
# To build with just the header library target define SNMALLOC_ONLY_HEADER_LIBRARY
# in containing Cmake file.
if(NOT DEFINED SNMALLOC_ONLY_HEADER_LIBRARY)
warnings_high()
if(MSVC)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG")
target_compile_definitions(snmalloc_lib INTERFACE -D_HAS_EXCEPTIONS=0)
add_compile_options(/std:c++latest)
else()
add_compile_options(-fno-exceptions -fno-rtti -fomit-frame-pointer -ffunction-sections)
# Static TLS model is unsupported on Haiku.
# All symbols are always dynamic on haiku and -rdynamic is redundant (and unsupported).
if (NOT CMAKE_SYSTEM_NAME MATCHES "Haiku")
add_compile_options(-ftls-model=initial-exec)
if(SNMALLOC_CI_BUILD OR (${CMAKE_BUILD_TYPE} MATCHES "Debug"))
# Get better stack traces in CI and Debug.
target_link_libraries(snmalloc_lib INTERFACE "-rdynamic")
add_compile_options(-g)
endif()
endif()
if(SNMALLOC_OPTIMISE_FOR_CURRENT_MACHINE)
check_cxx_compiler_flag(-march=native SUPPORT_MARCH_NATIVE)
if (SUPPORT_MARCH_NATIVE)
add_compile_options(-march=native)
else()
message(WARNING "Compiler does not support `-march=native` required by SNMALLOC_OPTIMISE_FOR_CURRENT_MACHINE")
endif()
endif()
find_package(Backtrace)
if(${Backtrace_FOUND})
target_compile_definitions(snmalloc_lib INTERFACE -DBACKTRACE_HEADER="${Backtrace_HEADER}")
target_link_libraries(snmalloc_lib INTERFACE ${Backtrace_LIBRARIES})
target_include_directories(snmalloc_lib INTERFACE ${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()
macro(subdirlist result curdir)
check_linker_flag(CXX "-Wl,--no-undefined" SNMALLOC_LINKER_SUPPORT_NO_ALLOW_SHLIB_UNDEF)
function(add_warning_flags name)
target_compile_options(${name} PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/Zi /W4 /WX /wd4127 /wd4324 /wd4201 $<${ci_or_debug}:/DEBUG>>
$<$<NOT:$<OR:$<CXX_COMPILER_ID:MSVC>,$<STREQUAL:${CMAKE_CXX_SIMULATE_ID},MSVC>>>:-fno-exceptions -fno-rtti -Wall -Wextra -Werror -Wundef>
$<$<CXX_COMPILER_ID:Clang>:-Wsign-conversion -Wconversion>)
target_link_options(${name} PRIVATE $<$<BOOL:${SNMALLOC_LINKER_SUPPORT_NO_ALLOW_SHLIB_UNDEF}>:-Wl,--no-undefined>)
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})
@@ -214,43 +240,63 @@ if(NOT DEFINED SNMALLOC_ONLY_HEADER_LIBRARY)
list(APPEND dirlist ${child})
endif()
endforeach()
set(${result} ${dirlist})
endmacro()
set(${result} ${dirlist} PARENT_SCOPE)
endfunction()
if(CMAKE_VERSION VERSION_LESS 3.14)
set(CMAKE_REQUIRED_LIBRARIES -fuse-ld=lld)
else()
set(CMAKE_REQUIRED_LINK_OPTIONS -fuse-ld=lld)
endif()
set(CMAKE_REQUIRED_LINK_OPTIONS -fuse-ld=lld)
check_cxx_source_compiles("int main() { return 1; }" LLD_WORKS)
if (LLD_WORKS)
message(STATUS "Using LLD to link snmalloc shims")
endif()
macro(add_shim name type)
function(add_shim name type)
add_library(${name} ${type} ${ARGN})
target_link_libraries(${name} snmalloc_lib)
target_link_libraries(${name} snmalloc)
set_target_properties(${name} PROPERTIES CXX_VISIBILITY_PRESET hidden)
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\")))")
endif()
set_target_properties(${name} PROPERTIES CXX_VISIBILITY_PRESET hidden)
# Ensure that we do not link against C++ stdlib when compiling shims.
if(NOT MSVC)
set_target_properties(${name} PROPERTIES LINKER_LANGUAGE C)
if (LLD_WORKS)
message("Using LLD.")
# Only include the dependencies that actually are touched.
# Required so C++ library is not included with direct pthread access.
target_link_libraries(${name} -Wl,--as-needed)
# Remove all the duplicate new/malloc and free/delete definitions
target_link_libraries(${name} -Wl,--icf=all -fuse-ld=lld)
target_compile_options(${name} PRIVATE
-fomit-frame-pointer -ffunction-sections)
# Static TLS model is unsupported on Haiku.
if (NOT CMAKE_SYSTEM_NAME STREQUAL "Haiku")
target_compile_options(${name} PRIVATE -ftls-model=initial-exec)
target_compile_options(${name} PRIVATE $<$<BOOL:${SNMALLOC_CI_BUILD}>:-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} -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 $<$<BOOL:${LLD_WORKS}>:-Wl,--icf=all -fuse-ld=lld>)
endif()
endmacro()
install(TARGETS ${name} EXPORT snmallocConfig)
endfunction()
if (SNMALLOC_STATIC_LIBRARY)
add_shim(snmallocshim-static STATIC src/override/malloc.cc)
add_shim(snmallocshim-static STATIC src/override/new.cc)
target_compile_definitions(snmallocshim-static PRIVATE
SNMALLOC_STATIC_LIBRARY_PREFIX=${SNMALLOC_STATIC_LIBRARY_PREFIX})
endif ()
@@ -273,7 +319,13 @@ if(NOT DEFINED SNMALLOC_ONLY_HEADER_LIBRARY)
set(TESTDIR ${CMAKE_CURRENT_SOURCE_DIR}/src/test)
subdirlist(TEST_CATEGORIES ${TESTDIR})
list(REVERSE TEST_CATEGORIES)
if (${SNMALLOC_CLEANUP} STREQUAL THREAD_CLEANUP)
set(TEST_CLEANUP PTHREAD_DESTRUCTORS)
else ()
set(TEST_CLEANUP ${SNMALLOC_CLEANUP})
endif()
foreach(TEST_CATEGORY ${TEST_CATEGORIES})
message(STATUS "Adding ${TEST_CATEGORY} tests")
subdirlist(TESTS ${TESTDIR}/${TEST_CATEGORY})
foreach(TEST ${TESTS})
if (WIN32
@@ -294,6 +346,7 @@ if(NOT DEFINED SNMALLOC_ONLY_HEADER_LIBRARY)
set(TESTNAME "${TEST_CATEGORY}-${TEST}-${FLAVOUR}")
add_executable(${TESTNAME} ${SRC})
add_warning_flags(${TESTNAME})
if (${FLAVOUR} STREQUAL "malloc")
target_compile_definitions(${TESTNAME} PRIVATE SNMALLOC_PASS_THROUGH)
@@ -301,31 +354,32 @@ if(NOT DEFINED SNMALLOC_ONLY_HEADER_LIBRARY)
if (${FLAVOUR} STREQUAL "check")
target_compile_definitions(${TESTNAME} PRIVATE SNMALLOC_CHECK_CLIENT)
endif()
target_link_libraries(${TESTNAME} snmalloc_lib)
target_link_libraries(${TESTNAME} snmalloc)
target_compile_definitions(${TESTNAME} PRIVATE "SNMALLOC_USE_${TEST_CLEANUP}")
if (${TEST} MATCHES "release-.*")
message(STATUS "Adding test: ${TESTNAME} only for release configs")
message(VERBOSE "Adding test: ${TESTNAME} only for release configs")
add_test(NAME ${TESTNAME} COMMAND ${TESTNAME} CONFIGURATIONS "Release")
else()
message(STATUS "Adding test: ${TESTNAME}")
message(VERBOSE "Adding test: ${TESTNAME}")
add_test(${TESTNAME} ${TESTNAME})
endif()
if (${TEST_CATEGORY} MATCHES "perf")
message(STATUS "Single threaded test: ${TESTNAME}")
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(STATUS "Single threaded test: ${TESTNAME}")
message(VERBOSE "Single threaded test: ${TESTNAME}")
set_tests_properties(${TESTNAME} PROPERTIES PROCESSORS 4)
endif()
if (${TEST} MATCHES "fixed_region")
message(STATUS "Single threaded test: ${TESTNAME}")
message(VERBOSE "Single threaded test: ${TESTNAME}")
set_tests_properties(${TESTNAME} PROPERTIES PROCESSORS 4)
endif()
if (${TEST} MATCHES "memory")
message(STATUS "Single threaded test: ${TESTNAME}")
message(VERBOSE "Single threaded test: ${TESTNAME}")
set_tests_properties(${TESTNAME} PROPERTIES PROCESSORS 4)
endif()
endif()
@@ -338,3 +392,23 @@ if(NOT DEFINED SNMALLOC_ONLY_HEADER_LIBRARY)
clangformat_targets()
endif()
install(TARGETS snmalloc EXPORT snmallocConfig)
install(TARGETS EXPORT snmallocConfig DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/snmalloc)
install(DIRECTORY src/aal DESTINATION include/snmalloc)
install(DIRECTORY src/ds DESTINATION include/snmalloc)
install(DIRECTORY src/override DESTINATION include/snmalloc)
install(DIRECTORY src/backend DESTINATION include/snmalloc)
install(DIRECTORY src/mem DESTINATION include/snmalloc)
install(DIRECTORY src/pal DESTINATION include/snmalloc)
install(FILES src/snmalloc.h;src/snmalloc_core.h;src/snmalloc_front.h DESTINATION include/snmalloc)
install(EXPORT snmallocConfig
FILE snmalloc-config.cmake
NAMESPACE snmalloc::
DESTINATION "share/snmalloc"
)

View File

@@ -153,8 +153,17 @@ namespace snmalloc
* Entry point that allows libc to call into the allocator for per-thread
* cleanup.
*/
void _malloc_thread_cleanup()
inline void _malloc_thread_cleanup()
{
snmalloc::ThreadAlloc::get().teardown();
}
namespace snmalloc
{
/**
* No-op version of register_clean_up. This is called unconditionally by
* globalconfig but is not necessary when using a libc hook.
*/
inline void register_clean_up() {}
}
#endif

View File

@@ -1,7 +1,11 @@
#include "malloc.cc"
#ifdef _WIN32
# define EXCEPTSPEC
# ifdef __clang__
# define EXCEPTSPEC noexcept
# else
# define EXCEPTSPEC
# endif
#else
# ifdef _GLIBCXX_USE_NOEXCEPT
# define EXCEPTSPEC _GLIBCXX_USE_NOEXCEPT

View File

@@ -4,8 +4,8 @@
# include <iostream>
#endif
#include "../ds/address.h"
#if defined(BACKTRACE_HEADER)
# include BACKTRACE_HEADER
#if defined(SNMALLOC_BACKTRACE_HEADER)
# include SNMALLOC_BACKTRACE_HEADER
#endif
#include <errno.h>
#include <stdio.h>