-
-
Notifications
You must be signed in to change notification settings - Fork 139
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
251 lines (213 loc) · 8.53 KB
/
Copy pathCMakeLists.txt
File metadata and controls
251 lines (213 loc) · 8.53 KB
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
cmake_minimum_required(VERSION 3.15)
project(hoard
VERSION 3.2
LANGUAGES CXX
DESCRIPTION "High-performance scalable memory allocator"
)
#
# ─── OPTIONS ──────────────────────────────────────────────────────────
#
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED OFF)
# Add cmake modules path
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
if(APPLE)
set(CMAKE_OSX_ARCHITECTURES arm64 arm64e x86_64)
endif()
# Generate position-independent code; required for shared libraries on many platforms
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# Note: alloc8 handles version scripts, visibility flags, and compiler options
#
# ─── INCLUDE DIRECTORIES ──────────────────────────────────────────────
#
include_directories(
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/src/include
${PROJECT_SOURCE_DIR}/src/include/hoard
${PROJECT_SOURCE_DIR}/src/include/superblocks
${PROJECT_SOURCE_DIR}/src/include/util
)
include(FetchContent)
FetchContent_Declare(
Heap-Layers
GIT_REPOSITORY https://github.com/emeryberger/Heap-Layers.git
GIT_TAG master
)
FetchContent_MakeAvailable(Heap-Layers)
include_directories(${heap-layers_SOURCE_DIR})
# Allocation-free printf (compiled directly into Hoard, not as a library)
FetchContent_Declare(
printf
GIT_REPOSITORY https://github.com/emeryberger/printf.git
GIT_TAG master
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(printf)
include_directories(${printf_SOURCE_DIR})
# alloc8 - generic allocator interposition library for all platforms
FetchContent_Declare(
alloc8
GIT_REPOSITORY https://github.com/emeryberger/alloc8.git
GIT_TAG main
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(alloc8)
include_directories(${alloc8_SOURCE_DIR}/include)
set(UNIX_SOURCES
src/source/unixtls.cpp
src/source/libhoard.cpp
${printf_SOURCE_DIR}/printf.cpp
${ALLOC8_INTERPOSE_SOURCES}
)
set(MACOS_SOURCES
src/source/mactls.cpp
src/source/libhoard.cpp
${printf_SOURCE_DIR}/printf.cpp
${ALLOC8_INTERPOSE_SOURCES}
)
set(WINDOWS_SOURCES
src/source/wintls.cpp
src/source/libhoard.cpp
${printf_SOURCE_DIR}/printf.cpp
${ALLOC8_INTERPOSE_SOURCES}
)
# Hoard never reads alloc8's caller-return-address hint (alloc8_caller_ra), and
# it is a thread_local store on EVERY malloc and free -- ~15% of the allocation
# fast path. Opt out of it. (Harmlessly ignored by alloc8 versions that predate
# the flag; the symbol is still defined either way.)
add_definitions(-DALLOC8_NO_CALLER_RA)
if(WIN32)
#
# ─── WINDOWS BUILD ───────────────────────────────────────────────────
# alloc8 handles Detours fetching/building internally
# ALLOC8_NO_DLLMAIN: Hoard provides its own DllMain in wintls.cpp
#
set(HOARD_SOURCES ${WINDOWS_SOURCES})
add_definitions(-D_CRT_SECURE_NO_WARNINGS -DWIN32_LEAN_AND_MEAN -DALLOC8_NO_DLLMAIN)
# Compile-time inline ownership hook for alloc8's Windows wrapper:
# replaces SEH-probe foreign-pointer detection (which dereferences
# masked addresses and, after init, skipped checking entirely) with
# Hoard's O(1) ownership map. See hoardownsinline.h.
add_definitions(-DALLOC8_XXOWNS_INLINE_HEADER=\"hoardownsinline.h\")
elseif(APPLE)
set(HOARD_SOURCES ${MACOS_SOURCES})
add_compile_options(-ftls-model=initial-exec -ftemplate-depth=1024)
# Compile-time inline ownership hook for alloc8: the predicate in
# hoardownsinline.h (backed by Hoard's superblock ownership map) inlines
# directly into alloc8's replace_free/replace_realloc/malloc_size hot
# paths. Harmlessly ignored by alloc8 versions without the hook (the
# runtime xxowns() hook in libhoard.cpp then applies instead).
add_definitions(-DALLOC8_XXOWNS_INLINE_HEADER=\"hoardownsinline.h\")
else()
set(HOARD_SOURCES ${UNIX_SOURCES})
endif()
# NDEBUG is deliberately NOT forced here. The Release and RelWithDebInfo
# configs already define it (CMAKE_CXX_FLAGS_<CONFIG>), so adding it
# unconditionally changed nothing for them while making it impossible to
# ever get an assertion-checked build: the asserts throughout the heap
# layers (isValid(), alignment, size-class invariants) were compiled out
# in every configuration, including Debug. Leave it to the config.
# Force Release build type for optimal performance (memory allocators need aggressive inlining)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
endif()
# NOTE: Link-Time Optimization (LTO) DISABLED on Windows ARM64 - causes 6x slowdown!
# MSVC's ARM64 LTO codegen produces significantly slower code for memory allocators.
if(NOT WIN32)
include(CheckIPOSupported)
# Hoard is C++ only (project LANGUAGES CXX); scope the check to CXX so that
# a C compiler pulled in by a dependency (which CMake's IPO table may not
# recognize) doesn't disable LTO for our C++ targets.
check_ipo_supported(RESULT ipo_supported OUTPUT ipo_error LANGUAGES CXX)
if(ipo_supported)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
message(STATUS "LTO enabled")
else()
message(STATUS "LTO not supported: ${ipo_error}")
endif()
else()
message(STATUS "LTO disabled on Windows (causes ARM64 slowdown)")
endif()
# Enable maximum optimization for MSVC
if(MSVC)
# /O2 = maximize speed, /Ob2 = inline any suitable function, /Oi = enable intrinsics
# /Ot = favor fast code
# NOTE: /GL (whole program optimization) DISABLED - causes 6x slowdown on ARM64!
# The MSVC ARM64 LTO codegen appears to produce significantly slower code.
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ob2 /Oi /Ot")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Ob2 /Oi /Ot")
# NOTE: /LTCG disabled since /GL is disabled
endif()
add_library(hoard SHARED ${HOARD_SOURCES})
# Link with alloc8 interposition library (handles platform-specific linking)
target_link_libraries(hoard PRIVATE alloc8::interpose)
# Platform-specific additional settings
if(WIN32)
# Export DetourFinishHelperProcess at ordinal #1 (required for withdll.exe)
target_link_options(hoard PRIVATE "/export:DetourFinishHelperProcess,@1,NONAME")
# Disable some MSVC warnings
target_compile_options(hoard PRIVATE /W3 /WX-)
# Set Windows-specific properties
set_target_properties(hoard PROPERTIES
OUTPUT_NAME "hoard"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
)
else()
set_target_properties(hoard PROPERTIES OUTPUT_NAME "hoard")
endif()
target_compile_definitions(hoard
PRIVATE
_REENTRANT=1
)
#
# ─── EXPORT AND INSTALL ────────────────────────────────────────────────
#
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
# Set up the export name
set(HOARD_EXPORT_NAME HoardTargets)
# Install the library with export
install(TARGETS hoard
EXPORT ${HOARD_EXPORT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
# Export target with namespace
install(EXPORT ${HOARD_EXPORT_NAME}
FILE HoardTargets.cmake
NAMESPACE Hoard::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Hoard
)
# Create an alias for use from build tree
add_library(Hoard::Hoard ALIAS hoard)
# Set export name to maintain consistent Hoard::Hoard naming after installation
set_target_properties(hoard PROPERTIES EXPORT_NAME Hoard)
# Configure the package config file
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/HoardConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/HoardConfig.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Hoard
)
# Generate version file
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/HoardConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)
# Install the config files
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/HoardConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/HoardConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Hoard
)
#
# ─── EXTERNAL ALLOCATORS (for benchmarking) ────────────────────────────
#
# Build external allocators for comparison benchmarking.
# Enable with: -DBUILD_JEMALLOC=ON -DBUILD_MIMALLOC=ON -DBUILD_TCMALLOC=ON
# Or all at once: -DBUILD_ALL_ALLOCATORS=ON
#
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/allocators/CMakeLists.txt")
add_subdirectory(allocators)
endif()