Brian Silverman | 20350ac | 2021-11-17 18:19:55 -0800 | [diff] [blame] | 1 | cmake_minimum_required(VERSION 3.12) |
| 2 | |
| 3 | # Please note that cmake support is very preliminary. Autotools-based |
| 4 | # build is the only fully supported build for now. |
| 5 | |
| 6 | # Based on configure.ac |
| 7 | |
| 8 | project(gperftools VERSION 2.9.0 LANGUAGES C CXX |
| 9 | DESCRIPTION "Performance tools for C++" |
| 10 | HOMEPAGE_URL http://code.google.com/p/gperftools/) |
| 11 | |
| 12 | # Update this value for every release! |
| 13 | set(TCMALLOC_SO_VERSION 9.9.5) |
| 14 | set(PROFILER_SO_VERSION 5.4.5) |
| 15 | set(TCMALLOC_AND_PROFILER_SO_VERSION 10.4.6) |
| 16 | |
| 17 | # The user can choose not to compile in the heap-profiler, the |
| 18 | # heap-checker, or the cpu-profiler. There's also the possibility |
| 19 | # for a 'fully minimal' compile, which leaves out the stacktrace |
| 20 | # code as well. By default, we include all of these that the |
| 21 | # target system supports. |
| 22 | set(DEFAULT_BUILD_CPU_PROFILER ON) |
| 23 | set(DEFAULT_BUILD_HEAP_PROFILER ON) |
| 24 | set(DEFAULT_BUILD_HEAP_CHECKER ON) |
| 25 | set(DEFAULT_BUILD_DEBUGALLOC ON) |
| 26 | set(DEFAULT_BUILD_MINIMAL OFF) |
| 27 | |
| 28 | set(DEFAULT_TCMALLOC_ALIGNMENT 16) |
| 29 | set(NEED_NANOSLEEP ON) # Used later, to decide if to run ACX_NANOSLEEP |
| 30 | |
| 31 | set(HOST string(TOLOWER "${CMAKE_SYSTEM_NAME}")) |
| 32 | |
| 33 | if(MINGW OR MSVC) |
| 34 | set(DEFAULT_BUILD_MINIMAL ON) |
| 35 | set(DEFAULT_BUILD_DEBUGALLOC OFF) |
| 36 | set(NEED_NANOSLEEP OFF) |
| 37 | elseif(CYGWIN) |
| 38 | set(DEFAULT_BUILD_HEAP_CHECKER OFF) |
| 39 | set(DEFAULT_BUILD_CPU_PROFILER OFF) |
| 40 | elseif(HOST MATCHES "freebsd") |
| 41 | set(DEFAULT_BUILD_HEAP_CHECKER OFF) |
| 42 | elseif(APPLE) |
| 43 | set(DEFAULT_BUILD_HEAP_CHECKER OFF) |
| 44 | endif() |
| 45 | |
| 46 | include(CheckCCompilerFlag) |
| 47 | include(CheckCSourceCompiles) |
| 48 | include(CheckCXXSourceCompiles) |
| 49 | include(CheckFunctionExists) |
| 50 | include(CheckIncludeFile) |
| 51 | include(CheckLibraryExists) |
| 52 | include(CheckSymbolExists) |
| 53 | include(CheckTypeSize) |
| 54 | include(CheckVariableExists) |
| 55 | include(CMakeDependentOption) |
| 56 | include(CTest) |
| 57 | include(CPack) |
| 58 | include(GNUInstallDirs) |
| 59 | |
| 60 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) |
| 61 | include(DefineTargetVariables) |
| 62 | include(FindObjcopyWithWeaken) |
| 63 | include(PCFromUContext) |
| 64 | |
| 65 | define_target_variables() |
| 66 | |
| 67 | # Currently only backtrace works on s390. |
| 68 | if(s390 OR OSX) |
| 69 | set(default_enable_libunwind OFF) |
| 70 | set(default_enable_backtrace ON) |
| 71 | else() |
| 72 | set(default_enable_libunwind ON) |
| 73 | set(default_enable_backtrace OFF) |
| 74 | endif() |
| 75 | |
| 76 | # Disable libunwind linking on ppc64 by default. |
| 77 | if(PPC64) |
| 78 | set(default_enable_libunwind OFF) |
| 79 | set(default_tcmalloc_pagesize 64) |
| 80 | else() |
| 81 | set(default_enable_libunwind ON) |
| 82 | set(default_tcmalloc_pagesize 8) |
| 83 | endif() |
| 84 | |
| 85 | cmake_dependent_option( |
| 86 | GPERFTOOLS_BUILD_CPU_PROFILER "Build cpu-profiler" ${DEFAULT_BUILD_CPU_PROFILER} |
| 87 | "NOT gperftools_build_minimal" OFF) |
| 88 | cmake_dependent_option( |
| 89 | GPERFTOOLS_BUILD_HEAP_PROFILER "Build heap-profiler" ${DEFAULT_BUILD_HEAP_PROFILER} |
| 90 | "NOT gperftools_build_minimal" OFF) |
| 91 | cmake_dependent_option( |
| 92 | GPERFTOOLS_BUILD_HEAP_CHECKER "Build heap-checker" ${DEFAULT_BUILD_HEAP_CHECKER} |
| 93 | "NOT gperftools_build_minimal" OFF) |
| 94 | cmake_dependent_option( |
| 95 | GPERFTOOLS_BUILD_DEBUGALLOC "Build debugalloc" ${DEFAULT_BUILD_DEBUGALLOC} |
| 96 | "NOT gperftools_build_minimal" OFF) |
| 97 | option( |
| 98 | gperftools_build_minimal |
| 99 | "Build only tcmalloc-minimal (and maybe tcmalloc-minimal-debug)" |
| 100 | ${DEFAULT_BUILD_MINIMAL}) |
| 101 | if(gperftools_build_minimal) |
| 102 | set(GPERFTOOLS_BUILD_CPU_PROFILER OFF) |
| 103 | set(GPERFTOOLS_BUILD_HEAP_PROFILER OFF) |
| 104 | set(GPERFTOOLS_BUILD_HEAP_CHECKER OFF) |
| 105 | endif() |
| 106 | |
| 107 | cmake_dependent_option( |
| 108 | gperftools_build_benchmark "Build benchmark" ON "NOT MINGW AND NOT MSVC" OFF) |
| 109 | |
| 110 | option(gperftools_enable_stacktrace_via_backtrace |
| 111 | "Enable use of backtrace() for stacktrace capturing (may deadlock)" |
| 112 | ${default_enable_backtrace}) |
| 113 | option(gperftools_enable_libunwind |
| 114 | "Enable libunwind linking" |
| 115 | ${default_enable_libunwind}) |
| 116 | |
| 117 | set(enable_backtrace ${gperftools_enable_stacktrace_via_backtrace}) |
| 118 | set(enable_libunwind ${gperftools_enable_libunwind}) |
| 119 | |
| 120 | set(gperftools_tcmalloc_pagesize ${default_tcmalloc_pagesize} |
| 121 | CACHE STRING "Set the tcmalloc internal page size") |
| 122 | set_property(CACHE gperftools_tcmalloc_pagesize PROPERTY STRINGS "8" "32" "64") |
| 123 | if(NOT gperftools_tcmalloc_pagesize STREQUAL "8" AND |
| 124 | NOT gperftools_tcmalloc_pagesize STREQUAL "32" AND |
| 125 | NOT gperftools_tcmalloc_pagesize STREQUAL "64") |
| 126 | message(WARNING |
| 127 | "Invalid gperftools_tcmalloc_pagesize (${gperftools_tcmalloc_pagesize}), " |
| 128 | "setting to default value (${default_tcmalloc_pagesize})") |
| 129 | set(gperftools_tcmalloc_pagesize ${default_tcmalloc_pagesize}) |
| 130 | endif() |
| 131 | if (gperftools_tcmalloc_pagesize STREQUAL "32" OR |
| 132 | gperftools_tcmalloc_pagesize STREQUAL "64") |
| 133 | set(TCMALLOC_${gperftools_tcmalloc_pagesize}K_PAGES ON) |
| 134 | endif() |
| 135 | |
| 136 | set(gperftools_tcmalloc_alignment ${DEFAULT_TCMALLOC_ALIGNMENT} |
| 137 | CACHE STRING "Set the tcmalloc allocation alignment") |
| 138 | set_property(CACHE gperftools_tcmalloc_alignment PROPERTY STRINGS "8" "16") |
| 139 | if(NOT gperftools_tcmalloc_alignment STREQUAL "8" AND |
| 140 | NOT gperftools_tcmalloc_alignment STREQUAL "16") |
| 141 | message(WARNING |
| 142 | "Invalid gperftools_tcmalloc_alignment (${gperftools_tcmalloc_alignment}), " |
| 143 | "setting to default value (${DEFAULT_TCMALLOC_ALIGNMENT})") |
| 144 | set(gperftools_tcmalloc_alignment ${DEFAULT_TCMALLOC_ALIGNMENT}) |
| 145 | endif() |
| 146 | if(gperftools_tcmalloc_alignment STREQUAL "8") |
| 147 | set(TCMALLOC_ALIGN_8BYTES ON) |
| 148 | endif() |
| 149 | |
| 150 | # AX_CXX_COMPILE_STDCXX(11, ext, mandatory) |
| 151 | if(cxx_std_17 IN_LIST CMAKE_CXX_COMPILE_FEATURES) |
| 152 | set(CMAKE_CXX_STANDARD 17) # std::align_val_t |
| 153 | else() |
| 154 | set(CMAKE_CXX_STANDARD 11) |
| 155 | endif() |
| 156 | set(CMAKE_CXX_STANDARD_REQUIRED ON) |
| 157 | set(CMAKE_CXX_EXTENSIONS ON) |
| 158 | |
| 159 | # Check if we have an objcopy installed that supports -W |
| 160 | find_objcopy_with_weaken() |
| 161 | |
| 162 | # AX_C___ATTRIBUTE__ |
| 163 | check_c_source_compiles("#include <stdlib.h> |
| 164 | static void foo(void) __attribute__ ((unused)); |
| 165 | void foo(void) { exit(1); } |
| 166 | int main() { return 0; }" |
| 167 | HAVE___ATTRIBUTE__) |
| 168 | |
| 169 | set(CMAKE_EXTRA_INCLUDE_FILES "malloc.h") |
| 170 | check_type_size("struct mallinfo" STRUCT_MALLINFO LANGUAGE CXX) |
| 171 | set(CMAKE_EXTRA_INCLUDE_FILES "elf.h") |
| 172 | check_type_size("Elf32_Versym" ELF32_VERSYM LANGUAGE CXX) # for vdso_support.h |
| 173 | set(CMAKE_EXTRA_INCLUDE_FILES) |
| 174 | check_function_exists("sbrk" HAVE_SBRK) # for tcmalloc to get memory |
| 175 | check_function_exists("__sbrk" HAVE_SBRK) # for tcmalloc to get memory |
| 176 | check_function_exists("geteuid" HAVE_GETEUID) # for turning off services when run as root |
| 177 | check_function_exists("fork" HAVE_FORK) # for the pthread_atfork setup |
| 178 | check_include_file("features.h" HAVE_FEATURES_H) # for vdso_support.h, Where __GLIBC__ is defined |
| 179 | check_include_file("malloc.h" HAVE_MALLOC_H) # some systems define stuff there, others not |
| 180 | check_include_file("glob.h" HAVE_GLOB_H) # for heap-profile-table (cleaning up profiles) |
| 181 | check_include_file("execinfo.h" HAVE_EXECINFO_H) # for stacktrace? and heapchecker_unittest |
| 182 | check_include_file("unwind.h" HAVE_UNWIND_H) # for stacktrace |
| 183 | check_include_file("sched.h" HAVE_SCHED_H) # for being nice in our spinlock code |
| 184 | check_include_file("sys/prctl.h" HAVE_SYS_PRCTL_H) # for thread_lister (needed by leak-checker) |
| 185 | check_include_file("linux/ptrace.h" HAVE_LINUX_PTRACE_H) # also needed by leak-checker |
| 186 | check_include_file("sys/syscall.h" HAVE_SYS_SYSCALL_H) |
| 187 | check_include_file("sys/socket.h" HAVE_SYS_SOCKET_H) # optional; for forking out to symbolizer |
| 188 | check_include_file("sys/wait.h" HAVE_SYS_WAIT_H) # optional; for forking out to symbolizer |
| 189 | check_include_file("poll.h" HAVE_POLL_H) # optional; for forking out to symbolizer |
| 190 | check_include_file("fcntl.h" HAVE_FCNTL_H) # for tcmalloc_unittest |
| 191 | check_include_file("grp.h" HAVE_GRP_H) # for heapchecker_unittest |
| 192 | check_include_file("pwd.h" HAVE_PWD_H) # for heapchecker_unittest |
| 193 | check_include_file("sys/resource.h" HAVE_SYS_RESOURCE_H) # for memalign_unittest.cc |
| 194 | check_include_file("sys/cdefs.h" HAVE_SYS_CDEFS_H) # Where glibc defines __THROW |
| 195 | |
| 196 | check_include_file("unistd.h" HAVE_UNISTD_H) |
| 197 | check_include_file("inttypes.h" HAVE_INTTYPES_H) |
| 198 | # We also need <ucontext.h>/<sys/ucontext.h>, but we get those from |
| 199 | # AC_PC_FROM_UCONTEXT, below. |
| 200 | |
| 201 | # We override a lot of memory allocation routines, not all of which are |
| 202 | # standard. For those the system doesn't declare, we'll declare ourselves. |
| 203 | set(CMAKE_REQUIRED_DEFINITIONS -D_XOPEN_SOURCE=600) |
| 204 | check_symbol_exists("cfree" "stdlib.h;malloc.h" HAVE_DECL_CFREE) |
| 205 | check_symbol_exists("posix_memalign" "stdlib.h;malloc.h" HAVE_DECL_POSIX_MEMALIGN) |
| 206 | check_symbol_exists("memalign" "stdlib.h;malloc.h" HAVE_DECL_MEMALIGN) |
| 207 | check_symbol_exists("valloc" "stdlib.h;malloc.h" HAVE_DECL_VALLOC) |
| 208 | check_symbol_exists("pvalloc" "stdlib.h;malloc.h" HAVE_DECL_PVALLOC) |
| 209 | set(CMAKE_REQUIRED_DEFINITIONS) |
| 210 | |
| 211 | if(HAVE_STRUCT_MALLINFO) |
| 212 | set(HAVE_STRUCT_MALLINFO 1) |
| 213 | else() |
| 214 | set(HAVE_STRUCT_MALLINFO 0) |
| 215 | endif() |
| 216 | |
| 217 | # We hardcode HAVE_MMAP to 1. There are no interesting systems anymore |
| 218 | # without functional mmap. And our windows (except mingw) builds |
| 219 | # aren't using autoconf. So we keep HAVE_MMAP define, but only to |
| 220 | # distingush windows and rest. |
| 221 | if(NOT WIN32) |
| 222 | set(HAVE_MMAP 1) |
| 223 | endif() |
| 224 | |
| 225 | # If AtomicWord != Atomic32, we need to define two versions of all the |
| 226 | # atomicops functions. If they're the same, we want to define only one. |
| 227 | check_c_source_compiles(" |
| 228 | #include <stdint.h> |
| 229 | int main() |
| 230 | { |
| 231 | int32_t v1 = 0; |
| 232 | intptr_t v2 = 0; |
| 233 | return (&v1 - &v2); |
| 234 | }" |
| 235 | INT32_EQUALS_INTPTR) |
| 236 | |
| 237 | # We want to access the "PC" (Program Counter) register from a struct |
| 238 | # ucontext. Every system has its own way of doing that. We try all the |
| 239 | # possibilities we know about. Note REG_PC should come first (REG_RIP |
| 240 | # is also defined on solaris, but does the wrong thing). But don't |
| 241 | # bother if we're not doing cpu-profiling. |
| 242 | # [*] means that we've not actually tested one of these systems |
| 243 | if (GPERFTOOLS_BUILD_CPU_PROFILER) |
| 244 | pc_from_ucontext(PC_FROM_UCONTEXT_DEF) |
| 245 | endif () |
| 246 | |
| 247 | # Some tests test the behavior of .so files, and only make sense for dynamic. |
| 248 | option(GPERFTOOLS_BUILD_STATIC "Enable Static" ON) |
| 249 | |
| 250 | if(gperftools_enable_libunwind) |
| 251 | check_include_file("libunwind.h" HAVE_LIBUNWIND_H) |
| 252 | if(HAVE_LIBUNWIND_H) |
| 253 | find_library(libunwind_location NAMES unwind) |
| 254 | if(libunwind_location) |
| 255 | check_library_exists( |
| 256 | unwind backtrace ${libunwind_location} have_libunwind) |
| 257 | endif() |
| 258 | if(have_libunwind) |
| 259 | set(unwind_libs ${libunwind_location}) |
| 260 | set(will_use_libunwind ON) |
| 261 | endif() |
| 262 | endif() |
| 263 | endif() |
| 264 | |
| 265 | # On x86_64, we know that default is to omit frame pointer. |
| 266 | if(x86_64) |
| 267 | set(omit_fp_by_default ON) |
| 268 | endif() |
| 269 | |
| 270 | # See if the compiler supports -Wno-unused-result. |
| 271 | # Newer ubuntu's turn on -D_FORTIFY_SOURCE=2, enabling |
| 272 | # __attribute__((warn_unused_result)) for things like write(), |
| 273 | # which we don't care about. |
| 274 | check_c_compiler_flag("-Wno-unused-result" have_w_no_unused_result) |
| 275 | |
| 276 | option(gperftools_dynamic_sized_delete_support |
| 277 | "Try to build run-time switch for sized delete operator" |
| 278 | OFF) |
| 279 | if(gperftools_dynamic_sized_delete_support) |
| 280 | set(ENABLE_DYNAMIC_SIZED_DELETE 1) |
| 281 | endif() |
| 282 | |
| 283 | option(gperftools_sized_delete "Build sized delete operator" OFF) |
| 284 | if(gperftools_sized_delete) |
| 285 | set(ENABLE_SIZED_DELETE 1) |
| 286 | endif() |
| 287 | |
| 288 | if(NOT MSVC) |
| 289 | set(CMAKE_REQUIRED_FLAGS -fsized-deallocation) |
| 290 | check_cxx_source_compiles(" |
| 291 | #include <new> |
| 292 | int main() { (::operator delete)(0, 256); return 0; }" |
| 293 | have_sized_deallocation) |
| 294 | set(CMAKE_REQUIRED_FLAGS) |
| 295 | endif() |
| 296 | |
| 297 | check_cxx_source_compiles(" |
| 298 | #include <new> |
| 299 | int main() { (::operator delete)((::operator new)(256, std::align_val_t(16)), std::align_val_t(16)); return 0; }" |
| 300 | HAVE_STD_ALIGN_VAL_T) |
| 301 | if(HAVE_STD_ALIGN_VAL_T) |
| 302 | set(HAVE_STD_ALIGN_VAL_T 1) |
| 303 | else() |
| 304 | set(HAVE_STD_ALIGN_VAL_T 0) |
| 305 | endif() |
| 306 | |
| 307 | check_c_source_compiles(" |
| 308 | #include <unwind.h> |
| 309 | int main() |
| 310 | { |
| 311 | #if __APPLE__ |
| 312 | #error OSX _Unwind_Backtrace recurses back to malloc |
| 313 | #endif |
| 314 | &_Unwind_Backtrace; |
| 315 | return 0; |
| 316 | }" |
| 317 | HAVE_UNWIND_BACKTRACE) |
| 318 | |
| 319 | if(enable_backtrace) |
| 320 | set(default_emergency_malloc ON) |
| 321 | else() |
| 322 | set(default_emergency_malloc OFF) |
| 323 | endif() |
| 324 | |
| 325 | if(will_use_libunwind AND ARM) |
| 326 | set(default_emergency_malloc ON) |
| 327 | endif() |
| 328 | |
| 329 | option(gperftools_emergency_malloc |
| 330 | "Build emergency malloc" |
| 331 | ${default_emergency_malloc}) |
| 332 | |
| 333 | check_c_source_compiles( |
| 334 | "int main() { return __builtin_expect(main != 0, 1); }" |
| 335 | HAVE_BUILTIN_EXPECT) |
| 336 | |
| 337 | check_c_source_compiles(" |
| 338 | #include <unistd.h> |
| 339 | int main() |
| 340 | { |
| 341 | char** env = __environ; |
| 342 | return 0; |
| 343 | }" |
| 344 | HAVE___ENVIRON) |
| 345 | |
| 346 | # If we support __thread, that can speed up tcmalloc a bit. |
| 347 | # Note, however, that our code tickles a bug in gcc < 4.1.2 |
| 348 | # involving TLS and -fPIC (which our libraries will use) on x86: |
| 349 | # http://gcc.gnu.org/ml/gcc-bugs/2006-09/msg02275.html |
| 350 | # |
| 351 | # And mingw also does compile __thread but resultant code actually |
| 352 | # fails to work correctly at least in some not so ancient version: |
| 353 | # http://mingw-users.1079350.n2.nabble.com/gcc-4-4-multi-threaded-exception-handling-amp-thread-specifier-not-working-td3440749.html |
| 354 | # |
| 355 | # Also it was reported that earlier gcc versions for mips compile |
| 356 | # __thread but it doesn't really work |
| 357 | if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND |
| 358 | CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.1.2") |
| 359 | message(WARNING "gcc has this bug: http://gcc.gnu.org/ml/gcc-bugs/2006-09/msg02275.html") |
| 360 | elseif(APPLE) |
| 361 | message(WARNING "OSX __thread support is known to call malloc which makes " |
| 362 | "it unsafe to use from malloc replacement") |
| 363 | elseif(MINGW) |
| 364 | message(WARNING "mingw doesn't really support tls") |
| 365 | else() |
| 366 | check_c_source_compiles("static __thread int p = 0; int main() {}" HAVE_TLS) |
| 367 | endif() |
| 368 | |
| 369 | if(NEED_NANOSLEEP) |
| 370 | check_c_source_compiles( |
| 371 | "#include <time.h> |
| 372 | int main() |
| 373 | { static struct timespec ts; nanosleep(&ts, NULL); return 0; }" |
| 374 | nanosleep_ok) |
| 375 | if(NOT nanosleep_ok) |
| 376 | set(CMAKE_REQUIRED_LIBRARIES rt) |
| 377 | check_c_source_compiles( |
| 378 | "#include <time.h> |
| 379 | int main() |
| 380 | { static struct timespec ts; nanosleep(&ts, NULL); return 0; }" |
| 381 | nanosleep_ok) |
| 382 | if(nanosleep_ok) |
| 383 | set(nanosleep_libs rt) |
| 384 | else() |
| 385 | message(FATAL_ERROR "cannot find the nanosleep function") |
| 386 | endif() |
| 387 | set(CMAKE_REQUIRED_LIBRARIES) |
| 388 | endif() |
| 389 | endif() |
| 390 | |
| 391 | # Nanosleep requires extra libraries on some architectures (solaris). |
| 392 | # This sets NANOSLEEP_LIBS. nanosleep doesn't exist on mingw, which |
| 393 | # is fine for us because we don't compile libspinlock, which uses it. |
| 394 | if(enable_backtrace) |
| 395 | check_symbol_exists("backtrace" "execinfo.h" HAVE_DECL_BACKTRACE) |
| 396 | check_function_exists("backtrace" backtrace_exists) |
| 397 | if(NOT backtrace_exists) |
| 398 | set(CMAKE_REQUIRED_LIBRARIES execinfo) |
| 399 | check_function_exists("backtrace" backtrace_exists) |
| 400 | set(CMAKE_REQUIRED_LIBRARIES) |
| 401 | if(backtrace_exists) |
| 402 | list(INSERT unwind_libs 0 execinfo) |
| 403 | endif() |
| 404 | endif() |
| 405 | endif() |
| 406 | |
| 407 | find_package(Threads REQUIRED) |
| 408 | set(HAVE_PTHREAD ${CMAKE_USE_PTHREADS_INIT}) |
| 409 | foreach(attr "PTHREAD_CREATE_JOINABLE" "PTHREAD_CREATE_UNDETACHED") |
| 410 | check_c_source_compiles(" |
| 411 | #include <pthread.h> |
| 412 | int main() { int attr = ${attr}; return attr; }" |
| 413 | ${attr}_ATTR) |
| 414 | if(${attr}_ATTR) |
| 415 | set(PTHREAD_CREATE_JOINABLE ${attr}) |
| 416 | break() |
| 417 | endif() |
| 418 | endforeach() |
| 419 | |
| 420 | if(FreeBSD) |
| 421 | set(PTHREADS_CRASHES_IF_RUN_TOO_EARLY ON) |
| 422 | endif() |
| 423 | |
| 424 | set(libstdcxx_la_linker_flag) |
| 425 | if(EXISTS /usr/sfw/lib/libstdc++.la) |
| 426 | file(READ /usr/sfw/lib/libstdc++.la _ch LIMIT 1) |
| 427 | if(string(LENGTH _ch) EQUAL 0) |
| 428 | set(libstdcxx_la_linker_flag "-L${CMAKE_CURRENT_SOURCE_DIR}/src/solaris") |
| 429 | endif() |
| 430 | endif() |
| 431 | |
| 432 | check_cxx_source_compiles( |
| 433 | "#include <string> |
| 434 | #include <vector> |
| 435 | int main() { pthread_t th; pthread_join(th, 0); return 0; }" |
| 436 | have_pthread_despite_asking_for) |
| 437 | |
| 438 | check_variable_exists("program_invocation_name" HAVE_PROGRAM_INVOCATION_NAME) |
| 439 | |
| 440 | if(MINGW) |
| 441 | check_symbol_exists("sleep" "unistd.h" HAVE_DECL_SLEEP) |
| 442 | check_symbol_exists("nanosleep" "time.h" HAVE_DECL_NANOSLEEP) |
| 443 | endif() |
| 444 | |
| 445 | if(LINUX) |
| 446 | check_c_source_compiles(" |
| 447 | #include <signal.h> |
| 448 | #include <time.h> |
| 449 | int main() { return SIGEV_THREAD_ID || CLOCK_THREAD_CPUTIME_ID; }" |
| 450 | HAVE_LINUX_SIGEV_THREAD_ID) |
| 451 | endif() |
| 452 | |
| 453 | configure_file(cmake/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h @ONLY) |
| 454 | configure_file(cmake/tcmalloc.h.in |
| 455 | ${CMAKE_CURRENT_BINARY_DIR}/gperftools/tcmalloc.h |
| 456 | @ONLY) |
| 457 | |
| 458 | if(GPERFTOOLS_BUILD_CPU_PROFILER OR |
| 459 | GPERFTOOLS_BUILD_HEAP_PROFILER OR |
| 460 | GPERFTOOLS_BUILD_HEAP_CHECKER) |
| 461 | set(WITH_STACK_TRACE ON) |
| 462 | endif() |
| 463 | |
| 464 | # The following matters only if we're not using libunwind and if we |
| 465 | # care about backtrace capturing, and frame pointers are not available |
| 466 | # to capture backtraces. The idea is to warn user about less stable or |
| 467 | # known bad configurations (e.g. encourage to install libunwind). |
| 468 | if (NOT unwind_libs AND NOT gperftools_build_minimal AND |
| 469 | omit_fp_by_default AND NOT gperftools_enable_frame_pointers) |
| 470 | if(HAVE_UNWIND_BACKTRACE) |
| 471 | message(WARNING "No frame pointers and no libunwind. " |
| 472 | "Using experimental backtrace capturing via libgcc. " |
| 473 | "Expect crashy cpu profiler.") |
| 474 | elseif(gperftools_enable_stacktrace_via_backtrace) |
| 475 | message(WARNING "No frame pointers and no libunwind. " |
| 476 | "Using experimental backtrace(). " |
| 477 | "Expect crashy cpu profiler.") |
| 478 | else() |
| 479 | message(FATAL_ERROR "No frame pointers and no libunwind. " |
| 480 | "The compilation will fail.") |
| 481 | endif() |
| 482 | endif() |
| 483 | |
| 484 | # Based on Makefile.am |
| 485 | |
| 486 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) |
| 487 | set(CMAKE_INCLUDE_CURRENT_DIR ON) |
| 488 | # This is so we can #include <gperftools/foo> |
| 489 | include_directories($<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>) |
| 490 | |
| 491 | if(NOT WITH_STACK_TRACE) |
| 492 | add_compile_definitions(NO_TCMALLOC_SAMPLES) |
| 493 | endif() |
| 494 | |
| 495 | # These are good warnings to turn on by default. |
| 496 | if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") |
| 497 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare") |
| 498 | |
| 499 | # On i386, -mmmx is needed for the mmx-based instructions in |
| 500 | # atomicops-internal-x86.h. Also as of gcc 4.6, -fomit-frame-pointer |
| 501 | # is the default. Since we must always have frame pointers for I386 |
| 502 | # in order to generate backtraces we now specify -fno-omit-frame-pointer |
| 503 | # by default. |
| 504 | if(i386) |
| 505 | add_compile_options(-mmmx -fno-omit-frame-pointer) |
| 506 | endif() |
| 507 | endif() |
| 508 | |
| 509 | if(have_w_no_unused_result) |
| 510 | add_compile_options(-Wno-unused-result) |
| 511 | endif() |
| 512 | |
| 513 | if(have_sized_deallocation) |
| 514 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsized-deallocation") |
| 515 | endif() |
| 516 | |
| 517 | if(have_f_aligned_new) |
| 518 | add_compile_options(-faligned-new) |
| 519 | endif() |
| 520 | |
| 521 | # LIBSTDCXX_LA_LINKER_FLAG is used to fix a Solaris bug. |
| 522 | add_link_options(${libstdcxx_la_linker_flag}) |
| 523 | |
| 524 | option( |
| 525 | gperftools_enable_frame_pointers |
| 526 | "Compile with -fno-omit-frame-pointer (see INSTALL)" |
| 527 | OFF) |
| 528 | |
| 529 | if(gperftools_enable_frame_pointers) |
| 530 | add_compile_options(-fno-omit-frame-pointer) |
| 531 | endif() |
| 532 | |
| 533 | if(omit_fp_by_default AND NOT gperftools_enable_frame_pointers) |
| 534 | add_compile_definitions(NO_FRAME_POINTER) |
| 535 | endif() |
| 536 | |
| 537 | # For windows systems (at least, mingw), we need to tell all our |
| 538 | # tests to link in libtcmalloc using -u. This is because libtcmalloc |
| 539 | # accomplishes its tasks via patching, leaving no work for the linker |
| 540 | # to identify, so the linker will ignore libtcmalloc by default unless |
| 541 | # we explicitly create a dependency via -u. |
| 542 | set(TCMALLOC_FLAGS) |
| 543 | if(MINGW) |
| 544 | list(APPEND TCMALLOC_FLAGS "-Wl,-u__tcmalloc") |
| 545 | endif() |
| 546 | |
| 547 | set(googleinclude_HEADERS |
| 548 | src/google/heap-checker.h |
| 549 | src/google/heap-profiler.h |
| 550 | src/google/malloc_extension.h |
| 551 | src/google/malloc_extension_c.h |
| 552 | src/google/malloc_hook.h |
| 553 | src/google/malloc_hook_c.h |
| 554 | src/google/profiler.h |
| 555 | src/google/stacktrace.h |
| 556 | src/google/tcmalloc.h |
| 557 | ) |
| 558 | install(FILES ${googleinclude_HEADERS} |
| 559 | DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/google |
| 560 | ) |
| 561 | |
| 562 | # This is a 'convenience library' -- it's not actually installed or anything |
| 563 | set(LOGGING_INCLUDES |
| 564 | src/base/logging.h |
| 565 | src/base/commandlineflags.h |
| 566 | src/base/basictypes.h |
| 567 | src/base/dynamic_annotations.h) |
| 568 | set(liblogging_la_SOURCES src/base/logging.cc |
| 569 | src/base/dynamic_annotations.c |
| 570 | ${LOGGING_INCLUDES}) |
| 571 | add_library(logging STATIC ${liblogging_la_SOURCES}) |
| 572 | |
| 573 | set(SYSINFO_INCLUDES |
| 574 | src/base/sysinfo.h |
| 575 | src/getenv_safe.h |
| 576 | src/base/logging.h |
| 577 | src/base/commandlineflags.h |
| 578 | src/base/arm_instruction_set_select.h |
| 579 | src/base/basictypes.h) |
| 580 | set(libsysinfo_la_SOURCES src/base/sysinfo.cc |
| 581 | ${SYSINFO_INCLUDES}) |
| 582 | set(libsysinfo_la_LIBADD ${NANOSLEEP_LIBS}) |
| 583 | add_library(sysinfo STATIC ${libsysinfo_la_SOURCES}) |
| 584 | target_link_libraries(sysinfo ${libsysinfo_la_LIBADD}) |
| 585 | |
| 586 | # For MinGW, we use also have to use libwindows Luckily, we need the |
| 587 | # windows.a library in exactly the same place we need spinlock.a |
| 588 | # (pretty much everywhere), so we can use the same variable name for |
| 589 | # each. We can also optimize the MinGW rule a bit by leaving out |
| 590 | # files we know aren't used on windows, such as |
| 591 | # atomicops-internals-x86.cc. libwindows also obsoletes the need for |
| 592 | # other files like system_alloc.cc. |
| 593 | if(MINGW OR MSVC) |
| 594 | set(WINDOWS_INCLUDES |
| 595 | src/windows/port.h |
| 596 | src/windows/mingw.h |
| 597 | src/windows/mini_disassembler.h |
| 598 | src/windows/mini_disassembler_types.h |
| 599 | src/windows/preamble_patcher.h) |
| 600 | set(libwindows_la_SOURCES ${WINDOWS_INCLUDES} |
| 601 | src/windows/port.cc |
| 602 | src/windows/system-alloc.cc |
| 603 | src/windows/ia32_modrm_map.cc |
| 604 | src/windows/ia32_opcode_map.cc |
| 605 | src/windows/mini_disassembler.cc |
| 606 | src/windows/patch_functions.cc |
| 607 | src/windows/preamble_patcher.cc |
| 608 | src/windows/preamble_patcher_with_stub.cc) |
| 609 | add_library(windows_object OBJECT ${libwindows_la_SOURCES}) |
| 610 | add_library(windows INTERFACE) |
| 611 | target_sources(windows INTERFACE $<TARGET_OBJECTS:windows_object>) |
| 612 | # patch_functions.cc uses Psapi.lib. MSVC has a #pragma for that, but not us. |
| 613 | target_link_libraries(windows INTERFACE psapi) |
| 614 | |
| 615 | set(SPINLOCK_INCLUDES src/base/spinlock.h |
| 616 | src/base/spinlock_internal.h |
| 617 | src/base/spinlock_win32-inl.h |
| 618 | src/base/spinlock_linux-inl.h |
| 619 | src/base/spinlock_posix-inl.h |
| 620 | src/base/atomicops-internals-macosx.h |
| 621 | src/base/atomicops-internals-linuxppc.h |
| 622 | src/base/atomicops-internals-arm-generic.h |
| 623 | src/base/atomicops-internals-arm-v6plus.h |
| 624 | src/base/atomicops-internals-mips.h |
| 625 | src/base/atomicops-internals-windows.h |
| 626 | src/base/atomicops-internals-gcc.h |
| 627 | src/base/atomicops-internals-x86.h) |
| 628 | set(libspinlock_la_SOURCES src/base/spinlock.cc |
| 629 | src/base/spinlock_internal.cc |
| 630 | src/base/atomicops-internals-x86.cc |
| 631 | ${SPINLOCK_INCLUDES}) |
| 632 | add_library(spinlock STATIC ${libspinlock_la_SOURCES}) |
| 633 | set(LIBSPINLOCK windows spinlock sysinfo logging) |
| 634 | # We also need to tell mingw that sysinfo.cc needs shlwapi.lib. |
| 635 | # (We do this via a #pragma for msvc, but need to do it here for mingw). |
| 636 | target_link_libraries(sysinfo shlwapi) |
| 637 | |
| 638 | if(have_pthread_despite_asking_for) |
| 639 | add_library(maybe_threads STATIC src/maybe_threads.cc) |
| 640 | set(maybe_threads_lib maybe_threads) |
| 641 | endif() |
| 642 | else() |
| 643 | set(SPINLOCK_INCLUDES src/base/spinlock.h |
| 644 | src/base/spinlock_internal.h |
| 645 | src/base/atomicops.h |
| 646 | src/base/atomicops-internals-macosx.h |
| 647 | src/base/atomicops-internals-linuxppc.h |
| 648 | src/base/atomicops-internals-windows.h |
| 649 | src/base/atomicops-internals-x86.h) |
| 650 | set(libspinlock_la_SOURCES src/base/spinlock.cc |
| 651 | src/base/spinlock_internal.cc |
| 652 | src/base/atomicops-internals-x86.cc |
| 653 | ${SPINLOCK_INCLUDES}) |
| 654 | add_library(spinlock STATIC ${libspinlock_la_SOURCES}) |
| 655 | target_link_libraries(spinlock ${nanosleep_libs}) |
| 656 | set(LIBSPINLOCK spinlock sysinfo logging) |
| 657 | set(TCMALLOC_CC "src/tcmalloc.cc") |
| 658 | set(SYSTEM_ALLOC_CC "src/system-alloc.cc") |
| 659 | |
| 660 | add_library(maybe_threads STATIC src/maybe_threads.cc) |
| 661 | set(maybe_threads_lib maybe_threads) |
| 662 | endif() |
| 663 | |
| 664 | if(BUILD_TESTING) |
| 665 | set(LOW_LEVEL_ALLOC_UNITTEST_INCLUDES |
| 666 | src/base/low_level_alloc.h |
| 667 | src/base/basictypes.h |
| 668 | src/gperftools/malloc_hook.h |
| 669 | src/gperftools/malloc_hook_c.h |
| 670 | src/malloc_hook-inl.h |
| 671 | src/malloc_hook_mmap_linux.h |
| 672 | src/malloc_hook_mmap_freebsd.h |
| 673 | ${SPINLOCK_INCLUDES} |
| 674 | ${LOGGING_INCLUDES}) |
| 675 | set(low_level_alloc_unittest_SOURCES src/base/low_level_alloc.cc |
| 676 | src/malloc_hook.cc |
| 677 | src/tests/low_level_alloc_unittest.cc |
| 678 | ${LOW_LEVEL_ALLOC_UNITTEST_INCLUDES}) |
| 679 | if(MSVC OR MINGW) |
| 680 | list(APPEND low_level_alloc_unittest_SOURCES src/windows/port.cc) |
| 681 | endif() |
| 682 | add_executable(low_level_alloc_unittest ${low_level_alloc_unittest_SOURCES}) |
| 683 | # By default, MallocHook takes stack traces for use by the heap-checker. |
| 684 | # We don't need that functionality here, so we turn it off to reduce deps. |
| 685 | target_compile_definitions(low_level_alloc_unittest PRIVATE NO_TCMALLOC_SAMPLES) |
| 686 | target_link_libraries(low_level_alloc_unittest spinlock sysinfo logging ${maybe_threads_lib}) |
| 687 | add_test(low_level_alloc_unittest low_level_alloc_unittest) |
| 688 | |
| 689 | set(ATOMICOPS_UNITTEST_INCLUDES src/base/atomicops.h |
| 690 | src/base/atomicops-internals-macosx.h |
| 691 | src/base/atomicops-internals-windows.h |
| 692 | src/base/atomicops-internals-x86.h |
| 693 | ${LOGGING_INCLUDES}) |
| 694 | set(atomicops_unittest_SOURCES src/tests/atomicops_unittest.cc |
| 695 | ${ATOMICOPS_UNITTEST_INCLUDES}) |
| 696 | if(MSVC OR MINGW) |
| 697 | list(APPEND atomicops_unittest_SOURCES src/windows/port.cc) |
| 698 | endif() |
| 699 | add_executable(atomicops_unittest ${atomicops_unittest_SOURCES}) |
| 700 | target_link_libraries(atomicops_unittest spinlock sysinfo logging) |
| 701 | add_test(atomicops_unittest atomicops_unittest) |
| 702 | endif() |
| 703 | |
| 704 | ### ------- stack trace |
| 705 | |
| 706 | if(WITH_STACK_TRACE) |
| 707 | |
| 708 | set(S_STACKTRACE_INCLUDES src/stacktrace_impl_setup-inl.h |
| 709 | src/stacktrace_generic-inl.h |
| 710 | src/stacktrace_libgcc-inl.h |
| 711 | src/stacktrace_libunwind-inl.h |
| 712 | src/stacktrace_arm-inl.h |
| 713 | src/stacktrace_powerpc-inl.h |
| 714 | src/stacktrace_powerpc-darwin-inl.h |
| 715 | src/stacktrace_powerpc-linux-inl.h |
| 716 | src/stacktrace_x86-inl.h |
| 717 | src/stacktrace_win32-inl.h |
| 718 | src/stacktrace_instrument-inl.h |
| 719 | src/base/elf_mem_image.h |
| 720 | src/base/vdso_support.h) |
| 721 | |
| 722 | set(SG_STACKTRACE_INCLUDES src/gperftools/stacktrace.h) |
| 723 | set(STACKTRACE_INCLUDES ${S_STACKTRACE_INCLUDES} ${SG_STACKTRACE_INCLUDES}) |
| 724 | list(APPEND perftoolsinclude_HEADERS ${SG_STACKTRACE_INCLUDES}) |
| 725 | |
| 726 | ### Making the library |
| 727 | set(libstacktrace_la_SOURCES src/stacktrace.cc |
| 728 | src/base/elf_mem_image.cc |
| 729 | src/base/vdso_support.cc |
| 730 | ${STACKTRACE_INCLUDES}) |
| 731 | add_library(stacktrace INTERFACE) |
| 732 | add_library(stacktrace_object OBJECT ${libstacktrace_la_SOURCES}) |
| 733 | target_link_libraries(stacktrace INTERFACE ${unwind_libs} ${LIBSPINLOCK}) |
| 734 | target_sources(stacktrace INTERFACE $<TARGET_OBJECTS:stacktrace_object>) |
| 735 | |
| 736 | set(libfake_stacktrace_scope_la_SOURCES src/fake_stacktrace_scope.cc) |
| 737 | add_library(fake_stacktrace_scope ${libfake_stacktrace_scope_la_SOURCES}) |
| 738 | |
| 739 | if(BUILD_TESTING) |
| 740 | set(STACKTRACE_UNITTEST_INCLUDES src/config_for_unittests.h |
| 741 | src/base/commandlineflags.h |
| 742 | ${STACKTRACE_INCLUDES} |
| 743 | ${LOGGING_INCLUDES}) |
| 744 | set(stacktrace_unittest_SOURCES src/tests/stacktrace_unittest.cc |
| 745 | ${STACKTRACE_UNITTEST_INCLUDES}) |
| 746 | add_executable(stacktrace_unittest ${stacktrace_unittest_SOURCES}) |
| 747 | target_link_libraries(stacktrace_unittest stacktrace logging fake_stacktrace_scope) |
| 748 | add_test(stacktrace_unittest stacktrace_unittest) |
| 749 | endif() |
| 750 | |
| 751 | endif() |
| 752 | |
| 753 | ### ------- pprof |
| 754 | |
| 755 | # If we are not compiling with stacktrace support, pprof is worthless |
| 756 | if(WITH_STACK_TRACE) |
| 757 | install(FILES src/pprof DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME pprof-symbolize) |
| 758 | |
| 759 | if(BUILD_TESTING) |
| 760 | add_test(NAME pprof_unittest |
| 761 | COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/src/pprof" -test |
| 762 | VERBATIM) |
| 763 | list(APPEND TESTS_ENVIRONMENT "PPROF_PATH=${CMAKE_CURRENT_SOURCE_DIR}/src/pprof") |
| 764 | endif() |
| 765 | if(INSTALL_PPROF) |
| 766 | install(FILES src/pprof DESTINATION ${CMAKE_INSTALL_BINDIR}) |
| 767 | endif() |
| 768 | endif() |
| 769 | |
| 770 | ### ------- tcmalloc_minimal (thread-caching malloc) |
| 771 | |
| 772 | ### The header files we use. We divide into categories based on directory |
| 773 | set(S_TCMALLOC_MINIMAL_INCLUDES src/common.h |
| 774 | src/internal_logging.h |
| 775 | src/system-alloc.h |
| 776 | src/packed-cache-inl.h |
| 777 | ${SPINLOCK_INCLUDES} |
| 778 | src/tcmalloc_guard.h |
| 779 | src/base/commandlineflags.h |
| 780 | src/base/basictypes.h |
| 781 | src/pagemap.h |
| 782 | src/sampler.h |
| 783 | src/central_freelist.h |
| 784 | src/linked_list.h |
| 785 | src/libc_override.h |
| 786 | src/libc_override_gcc_and_weak.h |
| 787 | src/libc_override_glibc.h |
| 788 | src/libc_override_osx.h |
| 789 | src/libc_override_redefine.h |
| 790 | src/page_heap.h |
| 791 | src/page_heap_allocator.h |
| 792 | src/span.h |
| 793 | src/static_vars.h |
| 794 | src/symbolize.h |
| 795 | src/thread_cache.h |
| 796 | src/stack_trace_table.h |
| 797 | src/base/thread_annotations.h |
| 798 | src/malloc_hook-inl.h |
| 799 | src/malloc_hook_mmap_linux.h |
| 800 | src/malloc_hook_mmap_freebsd.h) |
| 801 | set(SG_TCMALLOC_MINIMAL_INCLUDES src/gperftools/malloc_hook.h |
| 802 | src/gperftools/malloc_hook_c.h |
| 803 | src/gperftools/malloc_extension.h |
| 804 | src/gperftools/malloc_extension_c.h |
| 805 | src/gperftools/nallocx.h) |
| 806 | set(TCMALLOC_MINIMAL_INCLUDES ${S_TCMALLOC_MINIMAL_INCLUDES} ${SG_TCMALLOC_MINIMAL_INCLUDES} ${SG_STACKTRACE_INCLUDES}) |
| 807 | list(APPEND perftoolsinclude_HEADERS ${SG_TCMALLOC_MINIMAL_INCLUDES}) |
| 808 | |
| 809 | ### Making the library |
| 810 | |
| 811 | set(libtcmalloc_minimal_internal_la_SOURCES src/common.cc |
| 812 | src/internal_logging.cc |
| 813 | ${SYSTEM_ALLOC_CC} |
| 814 | src/memfs_malloc.cc |
| 815 | src/central_freelist.cc |
| 816 | src/page_heap.cc |
| 817 | src/sampler.cc |
| 818 | src/span.cc |
| 819 | src/stack_trace_table.cc |
| 820 | src/static_vars.cc |
| 821 | src/symbolize.cc |
| 822 | src/thread_cache.cc |
| 823 | src/malloc_hook.cc |
| 824 | src/malloc_extension.cc |
| 825 | ${TCMALLOC_MINIMAL_INCLUDES}) |
| 826 | add_library(tcmalloc_minimal_internal_object OBJECT ${libtcmalloc_minimal_internal_la_SOURCES}) |
| 827 | # We #define NO_TCMALLOC_SAMPLES, since sampling is turned off for _minimal. |
| 828 | target_compile_definitions(tcmalloc_minimal_internal_object PRIVATE NO_TCMALLOC_SAMPLES NO_HEAP_CHECK NDEBUG) |
| 829 | add_library(tcmalloc_minimal_internal INTERFACE) |
| 830 | target_link_libraries(tcmalloc_minimal_internal INTERFACE ${LIBSPINLOCK} ${maybe_threads_lib}) |
| 831 | target_sources(tcmalloc_minimal_internal INTERFACE $<TARGET_OBJECTS:tcmalloc_minimal_internal_object>) |
| 832 | |
| 833 | set(libtcmalloc_minimal_la_SOURCES ${TCMALLOC_CC} ${TCMALLOC_MINIMAL_INCLUDES}) |
| 834 | set(libtcmalloc_minimal_la_DEFINES NO_TCMALLOC_SAMPLES NDEBUG) |
| 835 | add_library(tcmalloc_minimal SHARED ${libtcmalloc_minimal_la_SOURCES}) |
| 836 | target_compile_definitions(tcmalloc_minimal PRIVATE ${libtcmalloc_minimal_la_DEFINES}) |
| 837 | set(libtcmalloc_minimal_la_LIBADD tcmalloc_minimal_internal) |
| 838 | target_link_libraries(tcmalloc_minimal PRIVATE tcmalloc_minimal_internal Threads::Threads) |
| 839 | if(MINGW) |
| 840 | target_link_libraries(tcmalloc_minimal PRIVATE stacktrace) |
| 841 | endif() |
| 842 | set_target_properties(tcmalloc_minimal PROPERTIES |
| 843 | VERSION ${TCMALLOC_SO_VERSION} |
| 844 | SOVERSION ${TCMALLOC_SO_VERSION}) |
| 845 | weaken_object(tcmalloc_minimal) |
| 846 | install(TARGETS tcmalloc_minimal) |
| 847 | if(GPERFTOOLS_BUILD_STATIC) |
| 848 | add_library(tcmalloc_minimal_static STATIC ${libtcmalloc_minimal_internal_la_SOURCES}) |
| 849 | target_compile_definitions(tcmalloc_minimal_static PRIVATE NO_TCMALLOC_SAMPLES NDEBUG) |
| 850 | target_link_libraries(tcmalloc_minimal_static PRIVATE tcmalloc_minimal_internal Threads::Threads) |
| 851 | if(MINGW) |
| 852 | target_link_libraries(tcmalloc_minimal_static PRIVATE stacktrace) |
| 853 | endif() |
| 854 | if(NOT MSVC) |
| 855 | set_target_properties(tcmalloc_minimal_static PROPERTIES |
| 856 | OUTPUT_NAME tcmalloc_minimal) |
| 857 | endif() |
| 858 | weaken_object(tcmalloc_minimal_static) |
| 859 | install(TARGETS tcmalloc_minimal_static) |
| 860 | endif() |
| 861 | |
| 862 | if(BUILD_TESTING) |
| 863 | set(tcmalloc_minimal_unittest_SOURCES |
| 864 | src/tests/tcmalloc_unittest.cc |
| 865 | src/tests/testutil.h src/tests/testutil.cc |
| 866 | ${TCMALLOC_UNITTEST_INCLUDES}) |
| 867 | set(tcmalloc_minimal_unittest_LDADD |
| 868 | ${TCMALLOC_FLAGS} Threads::Threads logging) |
| 869 | # We want libtcmalloc last on the link line, but due to a bug in |
| 870 | # libtool involving convenience libs, they need to come last on the |
| 871 | # link line in order to get dependency ordering right. This is ok: |
| 872 | # convenience libraries are .a's, so tcmalloc is still the last .so. |
| 873 | # We also put pthreads after tcmalloc, because some pthread |
| 874 | # implementations define their own malloc, and we need to go on the |
| 875 | # first linkline to make sure our malloc 'wins'. |
| 876 | add_executable(tcmalloc_minimal_unittest ${tcmalloc_minimal_unittest_SOURCES}) |
| 877 | target_link_libraries(tcmalloc_minimal_unittest tcmalloc_minimal ${tcmalloc_minimal_unittest_LDADD}) |
| 878 | add_test(tcmalloc_minimal_unittest tcmalloc_minimal_unittest) |
| 879 | |
| 880 | if(NOT MSVC) |
| 881 | add_executable(tcm_min_asserts_unittest |
| 882 | src/tests/tcmalloc_unittest.cc |
| 883 | src/tests/testutil.cc) |
| 884 | target_compile_definitions(tcm_min_asserts_unittest PUBLIC NO_TCMALLOC_SAMPLES NO_HEAP_CHECK) |
| 885 | target_link_libraries(tcm_min_asserts_unittest tcmalloc_minimal Threads::Threads) |
| 886 | add_test(tcm_min_asserts_unittest tcm_min_asserts_unittest) |
| 887 | endif() |
| 888 | |
| 889 | add_executable(tcmalloc_minimal_large_unittest |
| 890 | src/tests/tcmalloc_large_unittest.cc |
| 891 | src/tests/testutil.cc |
| 892 | src/tests/testutil.h) |
| 893 | target_link_libraries(tcmalloc_minimal_large_unittest tcmalloc_minimal Threads::Threads) |
| 894 | add_test(tcmalloc_minimal_large_unittest tcmalloc_minimal_large_unittest) |
| 895 | |
| 896 | add_executable(tcmalloc_minimal_large_heap_fragmentation_unittest |
| 897 | src/tests/large_heap_fragmentation_unittest.cc) |
| 898 | target_link_libraries( |
| 899 | tcmalloc_minimal_large_heap_fragmentation_unittest PUBLIC tcmalloc_minimal) |
| 900 | add_test(tcmalloc_minimal_large_heap_fragmentation_unittest tcmalloc_minimal_large_heap_fragmentation_unittest) |
| 901 | |
| 902 | if(BUILD_SHARED_LIBS AND NOT MINGW) |
| 903 | add_custom_target(maybe_threads_unittest |
| 904 | COMMAND src/tests/maybe_threads_unittest.sh |
| 905 | VERBATIM) |
| 906 | add_test(maybe_threads_unittest maybe_threads_unittest) |
| 907 | endif() |
| 908 | |
| 909 | if(MINGW OR MSVC) |
| 910 | set(port_src src/windows/port.cc) |
| 911 | endif() |
| 912 | add_executable(addressmap_unittest |
| 913 | src/tests/addressmap_unittest.cc |
| 914 | src/addressmap-inl.h |
| 915 | ${port_src}) |
| 916 | target_link_libraries(addressmap_unittest logging) |
| 917 | add_test(addressmap_unittest addressmap_unittest) |
| 918 | |
| 919 | if(NOT MINGW) |
| 920 | add_executable(system_alloc_unittest src/tests/system-alloc_unittest.cc) |
| 921 | target_link_libraries(system_alloc_unittest PUBLIC tcmalloc_minimal) |
| 922 | add_test(system_alloc_unittest system_alloc_unittest) |
| 923 | endif() |
| 924 | |
| 925 | add_executable(packed_cache_test src/tests/packed-cache_test.cc) |
| 926 | target_link_libraries(packed_cache_test PUBLIC tcmalloc_minimal) |
| 927 | add_test(packed_cache_test packed_cache_test) |
| 928 | |
| 929 | add_executable(frag_unittest src/tests/frag_unittest.cc) |
| 930 | target_link_libraries(frag_unittest PUBLIC tcmalloc_minimal) |
| 931 | add_test(frag_unittest frag_unittest) |
| 932 | |
| 933 | add_executable(markidle_unittest |
| 934 | src/tests/markidle_unittest.cc |
| 935 | src/tests/testutil.cc) |
| 936 | target_link_libraries(markidle_unittest tcmalloc_minimal Threads::Threads) |
| 937 | add_test(markidle_unittest markidle_unittest) |
| 938 | |
| 939 | add_executable(current_allocated_bytes_test |
| 940 | src/tests/current_allocated_bytes_test.cc) |
| 941 | target_link_libraries(current_allocated_bytes_test PUBLIC tcmalloc_minimal) |
| 942 | add_test(current_allocated_bytes_test current_allocated_bytes_test) |
| 943 | |
| 944 | add_executable(malloc_hook_test |
| 945 | src/tests/malloc_hook_test.cc |
| 946 | src/tests/testutil.cc) |
| 947 | target_link_libraries(malloc_hook_test tcmalloc_minimal Threads::Threads) |
| 948 | add_test(malloc_hook_test malloc_hook_test) |
| 949 | |
| 950 | set(malloc_extension_test_SOURCES src/tests/malloc_extension_test.cc |
| 951 | src/config_for_unittests.h |
| 952 | src/base/logging.h |
| 953 | src/gperftools/malloc_extension.h |
| 954 | src/gperftools/malloc_extension_c.h) |
| 955 | set(malloc_extension_test_LIBADD Threads::Threads ${TCMALLOC_FLAGS}) |
| 956 | add_executable(malloc_extension_test ${malloc_extension_test_SOURCES}) |
| 957 | target_link_libraries(malloc_extension_test tcmalloc_minimal ${malloc_extension_test_LIBADD}) |
| 958 | add_test(malloc_extension_test malloc_extension_test) |
| 959 | |
| 960 | if(NOT MSVC) |
| 961 | add_executable(malloc_extension_c_test src/tests/malloc_extension_c_test.c) |
| 962 | target_link_libraries(malloc_extension_c_test PUBLIC |
| 963 | tcmalloc_minimal stdc++ m) |
| 964 | if(CMAKE_C_COMPILER_ID STREQUAL "GNU") |
| 965 | target_compile_options(malloc_extension_c_test PUBLIC "-ansi") |
| 966 | endif() |
| 967 | add_test(malloc_extension_c_test malloc_extension_c_test) |
| 968 | endif() |
| 969 | |
| 970 | if(NOT MINGW AND NOT MSVC AND NOT APPLE) |
| 971 | set(memalign_unittest_SOURCES src/tests/memalign_unittest.cc |
| 972 | src/tcmalloc.h |
| 973 | src/config_for_unittests.h |
| 974 | src/tests/testutil.h src/tests/testutil.cc) |
| 975 | add_executable(memalign_unittest ${memalign_unittest_SOURCES}) |
| 976 | target_link_libraries(memalign_unittest tcmalloc_minimal Threads::Threads) |
| 977 | add_test(memalign_unittest memalign_unittest) |
| 978 | endif() |
| 979 | |
| 980 | add_executable(page_heap_test src/tests/page_heap_test.cc) |
| 981 | if(MSVC) |
| 982 | target_link_libraries(page_heap_test tcmalloc_minimal_static) |
| 983 | else() |
| 984 | target_link_libraries(page_heap_test tcmalloc_minimal) |
| 985 | endif() |
| 986 | add_test(page_heap_test page_heap_test) |
| 987 | |
| 988 | add_executable(pagemap_unittest src/tests/pagemap_unittest.cc) |
| 989 | target_link_libraries(pagemap_unittest PUBLIC tcmalloc_minimal) |
| 990 | add_test(pagemap_unittest pagemap_unittest) |
| 991 | |
| 992 | set(realloc_unittest_SOURCES src/tests/realloc_unittest.cc |
| 993 | src/config_for_unittests.h |
| 994 | src/base/logging.h) |
| 995 | set(realloc_unittest_LDFLAGS Threads::Threads ${TCMALLOC_FLAGS}) |
| 996 | add_executable(realloc_unittest ${realloc_unittest_SOURCES}) |
| 997 | target_link_libraries(realloc_unittest PUBLIC tcmalloc_minimal ${realloc_unittest_LDFLAGS}) |
| 998 | add_test(realloc_unittest realloc_unittest) |
| 999 | |
| 1000 | add_executable(stack_trace_table_test src/tests/stack_trace_table_test.cc) |
| 1001 | target_link_libraries(stack_trace_table_test PUBLIC tcmalloc_minimal) |
| 1002 | add_test(stack_trace_table_test stack_trace_table_test) |
| 1003 | |
| 1004 | add_executable(thread_dealloc_unittest |
| 1005 | src/tests/thread_dealloc_unittest.cc |
| 1006 | src/tests/testutil.cc) |
| 1007 | target_link_libraries(thread_dealloc_unittest tcmalloc_minimal Threads::Threads) |
| 1008 | add_test(thread_dealloc_unittest thread_dealloc_unittest) |
| 1009 | endif() |
| 1010 | |
| 1011 | ### ------- tcmalloc_minimal_debug (thread-caching malloc with debugallocation) |
| 1012 | |
| 1013 | if(GPERFTOOLS_BUILD_DEBUGALLOC) |
| 1014 | set(libtcmalloc_minimal_debug_la_SOURCES src/debugallocation.cc |
| 1015 | ${TCMALLOC_MINIMAL_INCLUDES}) |
| 1016 | add_library(tcmalloc_minimal_debug SHARED ${libtcmalloc_minimal_debug_la_SOURCES}) |
| 1017 | target_compile_definitions(tcmalloc_minimal_debug PRIVATE ${libtcmalloc_minimal_la_DEFINES} |
| 1018 | TCMALLOC_FOR_DEBUGALLOCATION) |
| 1019 | target_link_libraries(tcmalloc_minimal_debug PRIVATE ${libtcmalloc_minimal_la_LIBADD}) |
| 1020 | weaken_object(tcmalloc_minimal_debug) |
| 1021 | install(TARGETS tcmalloc_minimal_debug) |
| 1022 | set_target_properties(tcmalloc_minimal_debug PROPERTIES |
| 1023 | VERSION ${TCMALLOC_SO_VERSION} |
| 1024 | SOVERSION ${TCMALLOC_SO_VERSION}) |
| 1025 | if(GPERFTOOLS_BUILD_STATIC) |
| 1026 | add_library(tcmalloc_minimal_debug_static STATIC ${libtcmalloc_minimal_debug_la_SOURCES}) |
| 1027 | target_compile_definitions(tcmalloc_minimal_debug_static PRIVATE ${libtcmalloc_minimal_la_DEFINES} |
| 1028 | TCMALLOC_FOR_DEBUGALLOCATION) |
| 1029 | if(NOT MSVC) |
| 1030 | set_target_properties(tcmalloc_minimal_debug_static PROPERTIES |
| 1031 | OUTPUT_NAME tcmalloc_minimal_debug) |
| 1032 | endif() |
| 1033 | target_link_libraries(tcmalloc_minimal_debug_static PRIVATE ${libtcmalloc_minimal_la_LIBADD}) |
| 1034 | weaken_object(tcmalloc_minimal_debug_static) |
| 1035 | install(TARGETS tcmalloc_minimal_debug_static) |
| 1036 | endif() |
| 1037 | |
| 1038 | ### Unittests |
| 1039 | |
| 1040 | if(BUILD_TESTING) |
| 1041 | add_executable(tcmalloc_minimal_debug_unittest ${tcmalloc_minimal_unittest_SOURCES}) |
| 1042 | target_compile_definitions(tcmalloc_minimal_debug_unittest PRIVATE DEBUGALLOCATION) |
| 1043 | target_link_libraries(tcmalloc_minimal_debug_unittest tcmalloc_minimal_debug ${tcmalloc_minimal_unittest_LDADD}) |
| 1044 | add_test(tcmalloc_minimal_debug_unittest tcmalloc_minimal_debug_unittest) |
| 1045 | |
| 1046 | add_executable(malloc_extension_debug_test ${malloc_extension_test_SOURCES}) |
| 1047 | target_link_libraries(malloc_extension_debug_test tcmalloc_minimal_debug ${malloc_extension_test_LIBADD}) |
| 1048 | add_test(malloc_extension_debug_test malloc_extension_debug_test) |
| 1049 | |
| 1050 | if(NOT MINGW AND NOT APPLE) |
| 1051 | add_executable(memalign_debug_unittest ${memalign_unittest_SOURCES}) |
| 1052 | target_link_libraries(memalign_debug_unittest |
| 1053 | tcmalloc_minimal_debug Threads::Threads) |
| 1054 | add_test(memalign_debug_unittest memalign_debug_unittest) |
| 1055 | endif() |
| 1056 | |
| 1057 | add_executable(realloc_debug_unittest ${realloc_unittest_SOURCES}) |
| 1058 | target_link_libraries(realloc_debug_unittest PUBLIC tcmalloc_minimal_debug) |
| 1059 | add_test(realloc_debug_unittest realloc_debug_unittest) |
| 1060 | |
| 1061 | if(WITH_STACK_TRACE) |
| 1062 | add_executable(debugallocation_test src/tests/debugallocation_test.cc) |
| 1063 | target_link_libraries(debugallocation_test PUBLIC tcmalloc_minimal_debug Threads::Threads) |
| 1064 | |
| 1065 | add_test(NAME debugallocation_test |
| 1066 | COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/src/tests/debugallocation_test.sh) |
| 1067 | endif() |
| 1068 | endif() |
| 1069 | endif() |
| 1070 | |
| 1071 | if(NOT MINGW AND NOT MSVC) |
| 1072 | if(gperftools_build_benchmark) |
| 1073 | add_library(run_benchmark benchmark/run_benchmark.c) |
| 1074 | |
| 1075 | add_executable(malloc_bench benchmark/malloc_bench.cc) |
| 1076 | target_link_libraries(malloc_bench run_benchmark ${TCMALLOC_FLAGS}) |
| 1077 | if(GPERFTOOLS_BUILD_STATIC) |
| 1078 | target_link_libraries(malloc_bench tcmalloc_minimal_static) |
| 1079 | else() |
| 1080 | target_link_libraries(malloc_bench tcmalloc_minimal) |
| 1081 | endif() |
| 1082 | add_executable(malloc_bench_shared benchmark/malloc_bench.cc) |
| 1083 | target_link_libraries(malloc_bench_shared run_benchmark tcmalloc_minimal ${TCMALLOC_FLAGS} Threads::Threads) |
| 1084 | |
| 1085 | if(GPERFTOOLS_BUILD_HEAP_CHECKER OR GPERFTOOLS_BUILD_HEAP_PROFILER) |
| 1086 | add_executable(malloc_bench_shared_full benchmark/malloc_bench.cc) |
| 1087 | target_link_libraries(malloc_bench_shared_full run_benchmark tcmalloc ${TCMALLOC_FLAGS} Threads::Threads) |
| 1088 | endif() |
| 1089 | |
| 1090 | add_executable(binary_trees benchmark/binary_trees.cc) |
| 1091 | target_link_libraries(binary_trees Threads::Threads ${TCMALLOC_FLAGS}) |
| 1092 | if(GPERFTOOLS_BUILD_STATIC) |
| 1093 | target_link_libraries(binary_trees tcmalloc_minimal_static) |
| 1094 | else() |
| 1095 | target_link_libraries(binary_trees tcmalloc_minimal) |
| 1096 | endif() |
| 1097 | add_executable(binary_trees_shared benchmark/binary_trees.cc) |
| 1098 | target_link_libraries(binary_trees_shared tcmalloc_minimal Threads::Threads ${TCMALLOC_FLAGS}) |
| 1099 | endif() |
| 1100 | endif() |
| 1101 | |
| 1102 | ### ------- tcmalloc (thread-caching malloc + heap profiler + heap checker) |
| 1103 | |
| 1104 | if(GPERFTOOLS_BUILD_HEAP_CHECKER OR GPERFTOOLS_BUILD_HEAP_PROFILER) |
| 1105 | ### The header files we use. We divide into categories based on directory |
| 1106 | set(S_TCMALLOC_INCLUDES ${S_TCMALLOC_MINIMAL_INCLUDES} |
| 1107 | ${LOGGING_INCLUDES} |
| 1108 | src/addressmap-inl.h |
| 1109 | src/raw_printer.h |
| 1110 | src/base/elfcore.h |
| 1111 | src/base/googleinit.h |
| 1112 | src/base/linux_syscall_support.h |
| 1113 | src/base/linuxthreads.h |
| 1114 | src/base/stl_allocator.h |
| 1115 | src/base/sysinfo.h |
| 1116 | src/base/thread_lister.h |
| 1117 | src/heap-profile-table.h |
| 1118 | src/heap-profile-stats.h |
| 1119 | src/maybe_emergency_malloc.h |
| 1120 | src/emergency_malloc.h) |
| 1121 | |
| 1122 | set(SG_TCMALLOC_INCLUDES src/gperftools/heap-profiler.h |
| 1123 | src/gperftools/heap-checker.h) |
| 1124 | set(TCMALLOC_INCLUDES ${S_TCMALLOC_INCLUDES} ${SG_TCMALLOC_MINIMAL_INCLUDES} |
| 1125 | ${SG_TCMALLOC_INCLUDES} ${SG_STACKTRACE_INCLUDES}) |
| 1126 | list(APPEND perftoolsinclude_HEADERS ${SG_TCMALLOC_INCLUDES}) |
| 1127 | |
| 1128 | if(gperftools_emergency_malloc) |
| 1129 | set(EMERGENCY_MALLOC_CC |
| 1130 | src/emergency_malloc.cc |
| 1131 | src/emergency_malloc_for_stacktrace.cc) |
| 1132 | set(EMERGENCY_MALLOC_DEFINE ENABLE_EMERGENCY_MALLOC) |
| 1133 | else() |
| 1134 | set(EMERGENCY_MALLOC_CC src/fake_stacktrace_scope.cc) |
| 1135 | endif() |
| 1136 | |
| 1137 | ### Making the library |
| 1138 | |
| 1139 | set(libtcmalloc_internal_la_SOURCES ${libtcmalloc_minimal_internal_la_SOURCES} |
| 1140 | ${TCMALLOC_INCLUDES} |
| 1141 | src/base/low_level_alloc.cc |
| 1142 | src/heap-profile-table.cc |
| 1143 | src/heap-profiler.cc |
| 1144 | src/raw_printer.cc |
| 1145 | ${EMERGENCY_MALLOC_CC} |
| 1146 | src/memory_region_map.cc) |
| 1147 | set(libtcmalloc_internal_la_DEFINE NDEBUG ${EMERGENCY_MALLOC_DEFINE}) |
| 1148 | set(libtcmalloc_internal_la_LIBADD stacktrace Threads::Threads) |
| 1149 | |
| 1150 | set(libtcmalloc_la_SOURCES ${TCMALLOC_CC} ${TCMALLOC_INCLUDES}) |
| 1151 | set(libtcmalloc_la_DEFINE NDEBUG ${EMERGENCY_MALLOC_DEFINE}) |
| 1152 | set(libtcmalloc_la_LIBADD tcmalloc_internal ${maybe_threads_lib} Threads::Threads) |
| 1153 | if(GPERFTOOLS_BUILD_HEAP_CHECKER) |
| 1154 | # heap-checker-bcad is last, in hopes its global ctor will run first. |
| 1155 | # (Note this is added to libtcmalloc.la, not libtcmalloc_internal.la, |
| 1156 | # but that's ok; the internal/external distinction is only useful for |
| 1157 | # cygwin, and cygwin doesn't use HEAP_CHECKER anyway.) |
| 1158 | set(HEAP_CHECKER_SOURCES src/base/thread_lister.c |
| 1159 | src/base/linuxthreads.cc |
| 1160 | src/heap-checker.cc |
| 1161 | src/heap-checker-bcad.cc) |
| 1162 | list(APPEND libtcmalloc_la_SOURCES ${HEAP_CHECKER_SOURCES}) |
| 1163 | else() |
| 1164 | list(APPEND libtcmalloc_internal_la_DEFINE NO_HEAP_CHECK) |
| 1165 | list(APPEND libtcmalloc_la_DEFINE NO_HEAP_CHECK) |
| 1166 | endif() |
| 1167 | |
| 1168 | add_library(tcmalloc_internal_object OBJECT ${libtcmalloc_internal_la_SOURCES}) |
| 1169 | target_compile_definitions(tcmalloc_internal_object PRIVATE ${libtcmalloc_internal_la_DEFINE}) |
| 1170 | add_library(tcmalloc_internal INTERFACE) |
| 1171 | target_sources(tcmalloc_internal INTERFACE $<TARGET_OBJECTS:tcmalloc_internal_object>) |
| 1172 | target_link_libraries(tcmalloc_internal INTERFACE ${libtcmalloc_internal_la_LIBADD}) |
| 1173 | |
| 1174 | add_library(tcmalloc SHARED ${libtcmalloc_la_SOURCES}) |
| 1175 | target_compile_definitions(tcmalloc PRIVATE ${libtcmalloc_la_DEFINE}) |
| 1176 | target_link_libraries(tcmalloc ${libtcmalloc_la_LIBADD}) |
| 1177 | set_target_properties(tcmalloc PROPERTIES |
| 1178 | VERSION ${TCMALLOC_SO_VERSION} |
| 1179 | SOVERSION ${TCMALLOC_SO_VERSION}) |
| 1180 | weaken_object(tcmalloc) |
| 1181 | install(TARGETS tcmalloc) |
| 1182 | if(GPERFTOOLS_BUILD_STATIC) |
| 1183 | add_library(tcmalloc_static STATIC ${libtcmalloc_la_SOURCES}) |
| 1184 | target_compile_definitions(tcmalloc_static PRIVATE ${libtcmalloc_la_DEFINE}) |
| 1185 | if(NOT MSVC) |
| 1186 | set_target_properties(tcmalloc_static PROPERTIES OUTPUT_NAME tcmalloc) |
| 1187 | endif() |
| 1188 | target_link_libraries(tcmalloc_static PRIVATE ${libtcmalloc_la_LIBADD}) |
| 1189 | weaken_object(tcmalloc_static) |
| 1190 | install(TARGETS tcmalloc_static) |
| 1191 | endif() |
| 1192 | |
| 1193 | ### Unittests |
| 1194 | if(BUILD_TESTING) |
| 1195 | set(TCMALLOC_UNITTEST_INCLUDES src/config_for_unittests.h |
| 1196 | src/gperftools/malloc_extension.h) |
| 1197 | set(tcmalloc_unittest_SOURCES src/tests/tcmalloc_unittest.cc |
| 1198 | src/tcmalloc.h |
| 1199 | src/tests/testutil.h src/tests/testutil.cc |
| 1200 | ${TCMALLOC_UNITTEST_INCLUDES}) |
| 1201 | set(tcmalloc_unittest_LIBADD ${TCMALLOC_FLAGS} logging Threads::Threads) |
| 1202 | add_executable(tcmalloc_unittest ${tcmalloc_unittest_SOURCES}) |
| 1203 | target_link_libraries(tcmalloc_unittest tcmalloc ${tcmalloc_unittest_LIBADD}) |
| 1204 | add_test(NAME tcmalloc_unittest |
| 1205 | COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/tcmalloc_unittest.sh") |
| 1206 | |
| 1207 | # This makes sure it's safe to link in both tcmalloc and |
| 1208 | # tcmalloc_minimal. (One would never do this on purpose, but perhaps |
| 1209 | # by accident...) When we can compile libprofiler, we also link it in |
| 1210 | # to make sure that works too. NOTE: On OS X, it's *not* safe to |
| 1211 | # link both in (we end up with two copies of every global var, and |
| 1212 | # the code tends to pick one arbitrarily), so don't run the test there. |
| 1213 | set(tcmalloc_both_unittest_srcs src/tests/tcmalloc_unittest.cc |
| 1214 | src/tests/testutil.h src/tests/testutil.cc |
| 1215 | ${TCMALLOC_UNITTEST_INCLUDES}) |
| 1216 | if(GPERFTOOLS_BUILD_CPU_PROFILER) |
| 1217 | set(tcmalloc_both_unittest_ladd tcmalloc tcmalloc_minimal profiler logging Threads::Threads) |
| 1218 | else() |
| 1219 | set(tcmalloc_both_unittest_ladd tcmalloc tcmalloc_minimal logging Threads::Threads) |
| 1220 | endif() |
| 1221 | if(NOT APPLE) |
| 1222 | add_executable(tcmalloc_both_unittest ${tcmalloc_both_unittest_srcs}) |
| 1223 | target_link_libraries(tcmalloc_both_unittest ${TCMALLOC_FLAGS} ${tcmalloc_both_unittest_ladd}) |
| 1224 | add_test(tcmalloc_both_unittest tcmalloc_both_unittest) |
| 1225 | endif() |
| 1226 | |
| 1227 | add_executable(tcmalloc_large_unittest src/tests/tcmalloc_large_unittest.cc) |
| 1228 | target_link_libraries(tcmalloc_large_unittest tcmalloc Threads::Threads) |
| 1229 | add_test(tcmalloc_large_unittest tcmalloc_large_unittest) |
| 1230 | |
| 1231 | add_executable(tcmalloc_large_heap_fragmentation_unittest src/tests/large_heap_fragmentation_unittest.cc) |
| 1232 | target_link_libraries(tcmalloc_large_heap_fragmentation_unittest tcmalloc Threads::Threads) |
| 1233 | add_test(tcmalloc_large_heap_fragmentation_unittest tcmalloc_large_heap_fragmentation_unittest) |
| 1234 | |
| 1235 | add_executable(raw_printer_test src/tests/raw_printer_test.cc) |
| 1236 | target_link_libraries(raw_printer_test tcmalloc Threads::Threads) |
| 1237 | add_test(raw_printer_test raw_printer_test) |
| 1238 | |
| 1239 | # sampler_test and sampling_test both require sampling to be turned |
| 1240 | # on, which it's not by default. Use the "standard" value of 2^19. |
| 1241 | list(APPEND TESTS_ENVIRONMENT TCMALLOC_SAMPLE_PARAMETER=524288) |
| 1242 | |
| 1243 | set(sampler_test_SOURCES src/tests/sampler_test.cc |
| 1244 | src/config_for_unittests.h) |
| 1245 | set(sampler_test_LIBADD ${TCMALLOC_FLAGS} Threads::Threads m) |
| 1246 | add_executable(sampler_test ${sampler_test_SOURCES}) |
| 1247 | target_link_libraries(sampler_test tcmalloc ${sampler_test_LIBADD}) |
| 1248 | add_test(sampler_test sampler_test) |
| 1249 | |
| 1250 | # These unittests often need to run binaries. They're in the current dir |
| 1251 | list(APPEND TESTS_ENVIRONMENT BINDIR=. TMPDIR=/tmp/perftools) |
| 1252 | set(SAMPLING_TEST_INCLUDES src/config_for_unittests.h |
| 1253 | src/base/logging.h |
| 1254 | src/gperftools/malloc_extension.h) |
| 1255 | set(sampling_test_SOURCES src/tests/sampling_test.cc |
| 1256 | ${SAMPLING_TEST_INCLUDES}) |
| 1257 | add_executable(sampling_test ${sampling_test_SOURCES}) |
| 1258 | target_link_libraries(sampling_test ${TCMALLOC_FLAGS} tcmalloc Threads::Threads) |
| 1259 | add_test(NAME sampling_test.sh |
| 1260 | COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/sampling_test.sh" sampling_test) |
| 1261 | if(GPERFTOOLS_BUILD_HEAP_PROFILER) |
| 1262 | set(HEAP_PROFILER_UNITTEST_INCLUDES src/config_for_unittests.h |
| 1263 | src/gperftools/heap-profiler.h) |
| 1264 | set(heap_profiler_unittest_SOURCES src/tests/heap-profiler_unittest.cc |
| 1265 | ${HEAP_PROFILER_UNITTEST_INCLUDES}) |
| 1266 | add_executable(heap_profiler_unittest ${heap_profiler_unittest_SOURCES}) |
| 1267 | target_link_libraries(heap_profiler_unittest ${TCMALLOC_FLAGS} tcmalloc Threads::Threads) |
| 1268 | add_test(NAME heap-profiler_unittest.sh |
| 1269 | COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/heap-profiler_unittest.sh" heap-profiler_unittest) |
| 1270 | |
| 1271 | # Tests the compatibility include-headers in google/. Requires a function |
| 1272 | # defined in the heap-profiler, which is why the test lives here. |
| 1273 | add_executable(simple_compat_test src/tests/simple_compat_test.cc |
| 1274 | ${googleinclude_HEADERS}) |
| 1275 | target_link_libraries(simple_compat_test ${TCMALLOC_FLAGS} tcmalloc) |
| 1276 | add_test(simple_compat_test simple_compat_test) |
| 1277 | endif() |
| 1278 | if(GPERFTOOLS_BUILD_HEAP_CHECKER) |
| 1279 | set(HEAP_CHECKER_UNITTEST_INCLUDES src/config_for_unittests.h |
| 1280 | src/memory_region_map.h |
| 1281 | src/base/commandlineflags.h |
| 1282 | src/base/googleinit.h |
| 1283 | src/gperftools/heap-checker.h |
| 1284 | ${LOGGING_INCLUDES}) |
| 1285 | set(heap_checker_unittest_SOURCES src/tests/heap-checker_unittest.cc |
| 1286 | ${HEAP_CHECKER_UNITTEST_INCLUDES}) |
| 1287 | add_executable(heap_checker_unittest ${heap_checker_unittest_SOURCES}) |
| 1288 | target_link_libraries(heap_checker_unittest ${TCMALLOC_FLAGS} tcmalloc logging Threads::Threads) |
| 1289 | add_test(NAME heap-checker_unittest.sh |
| 1290 | COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/heap-checker_unittest.sh" heap_checker_unittest) |
| 1291 | add_test(NAME heap-checker-death_unittest.sh |
| 1292 | COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/heap-checker-death_unittest.sh") |
| 1293 | endif() |
| 1294 | endif() |
| 1295 | |
| 1296 | endif() |
| 1297 | |
| 1298 | ### ------- tcmalloc with debugallocation |
| 1299 | if(GPERFTOOLS_BUILD_DEBUGALLOC) |
| 1300 | if(GPERFTOOLS_BUILD_HEAP_CHECKER OR GPERFTOOLS_BUILD_HEAP_PROFILER) |
| 1301 | add_library(tcmalloc_debug SHARED src/debugallocation.cc ${HEAP_CHECKER_SOURCES} ${TCMALLOC_INCLUDES}) |
| 1302 | target_compile_definitions(tcmalloc_debug PRIVATE ${libtcmalloc_la_DEFINE} |
| 1303 | TCMALLOC_FOR_DEBUGALLOCATION) |
| 1304 | target_link_libraries(tcmalloc_debug PRIVATE ${libtcmalloc_la_LIBADD}) |
| 1305 | set_target_properties(tcmalloc_debug PROPERTIES |
| 1306 | VERSION ${TCMALLOC_SO_VERSION} |
| 1307 | SOVERSION ${TCMALLOC_SO_VERSION}) |
| 1308 | weaken_object(tcmalloc_debug) |
| 1309 | install(TARGETS tcmalloc_debug) |
| 1310 | if(GPERFTOOLS_BUILD_STATIC) |
| 1311 | add_library(tcmalloc_debug_static STATIC src/debugallocation.cc ${HEAP_CHECKER_SOURCES} ${TCMALLOC_INCLUDES}) |
| 1312 | target_compile_definitions(tcmalloc_debug_static PRIVATE ${libtcmalloc_la_DEFINE} |
| 1313 | TCMALLOC_FOR_DEBUGALLOCATION) |
| 1314 | target_link_libraries(tcmalloc_debug_static PRIVATE ${libtcmalloc_la_LIBADD}) |
| 1315 | if(NOT MSVC) |
| 1316 | set_target_properties(tcmalloc_debug_static PROPERTIES |
| 1317 | OUTPUT_NAME tcmalloc_debug) |
| 1318 | endif() |
| 1319 | weaken_object(tcmalloc_debug_static) |
| 1320 | install(TARGETS tcmalloc_debug_static) |
| 1321 | endif() |
| 1322 | |
| 1323 | ### Unittests |
| 1324 | if(BUILD_TESTING) |
| 1325 | add_executable(tcmalloc_debug_unittest ${tcmalloc_unittest_SOURCES}) |
| 1326 | target_compile_definitions(tcmalloc_debug_unittest PRIVATE DEBUGALLOCATION ${tcmalloc_unittest}) |
| 1327 | target_link_libraries(tcmalloc_debug_unittest tcmalloc_debug ${tcmalloc_unittest_LIBADD}) |
| 1328 | add_test(tcmalloc_debug_unittest tcmalloc_debug_unittest) |
| 1329 | |
| 1330 | add_executable(sampler_debug_test ${sampler_test_SOURCES}) |
| 1331 | target_link_libraries(sampler_debug_test tcmalloc_debug ${tcmalloc_unittest_LIBADD}) |
| 1332 | add_test(sampler_debug_test sampler_debug_test) |
| 1333 | |
| 1334 | add_executable(sampling_debug_test ${sampling_test_SOURCES}) |
| 1335 | target_link_libraries(sampling_debug_test ${TCMALLOC_FLAGS} tcmalloc_debug Threads::Threads) |
| 1336 | add_test(sampling_debug_test.sh "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/sampling_test.sh" sampling_debug_test) |
| 1337 | |
| 1338 | if(GPERFTOOLS_BUILD_HEAP_PROFILER) |
| 1339 | add_executable(heap_profiler_debug_unittest ${heap_profiler_unittest_SOURCES}) |
| 1340 | target_link_libraries(heap_profiler_debug_unittest ${TCMALLOC_FLAGS} tcmalloc_debug Threads::Threads) |
| 1341 | add_test(heap-profiler_debug_unittest.sh "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/heap-profiler_unittest.sh" heap-profiler_debug_unittest) |
| 1342 | endif() |
| 1343 | if(GPERFTOOLS_BUILD_HEAP_CHECKER) |
| 1344 | add_executable(heap_checker_debug_unittest ${heap_checker_unittest_SOURCES}) |
| 1345 | target_link_libraries(heap_checker_debug_unittest ${TCMALLOC_FLAGS} tcmalloc_debug logging Threads::Threads) |
| 1346 | add_test(heap-checker_debug_unittest.sh "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/heap-checker_unittest.sh" heap-checker_debug_unittest) |
| 1347 | endif() |
| 1348 | endif() |
| 1349 | endif() |
| 1350 | endif() |
| 1351 | |
| 1352 | ### ------- CPU profiler |
| 1353 | if(GPERFTOOLS_BUILD_CPU_PROFILER) |
| 1354 | ### The header files we use. We divide into categories based on directory |
| 1355 | set(S_CPU_PROFILER_INCLUDES src/profiledata.h |
| 1356 | src/profile-handler.h |
| 1357 | src/getpc.h |
| 1358 | src/base/basictypes.h |
| 1359 | src/base/commandlineflags.h |
| 1360 | src/base/googleinit.h |
| 1361 | src/base/logging.h |
| 1362 | src/base/simple_mutex.h |
| 1363 | src/base/sysinfo.h |
| 1364 | ${SPINLOCK_INCLUDES} |
| 1365 | ${LOGGING_INCLUDES}) |
| 1366 | set(SG_CPU_PROFILER_INCLUDES src/gperftools/profiler.h) |
| 1367 | set(CPU_PROFILER_INCLUDES ${S_CPU_PROFILER_INCLUDES} ${SG_CPU_PROFILER_INCLUDES} |
| 1368 | ${SG_STACKTRACE_INCLUDES}) |
| 1369 | list(APPEND perftoolsinclude_HEADERS ${SG_CPU_PROFILER_INCLUDES}) |
| 1370 | |
| 1371 | ### Making the library |
| 1372 | set(libprofiler_la_SOURCES src/profiler.cc |
| 1373 | src/profile-handler.cc |
| 1374 | src/profiledata.cc |
| 1375 | ${CPU_PROFILER_INCLUDES}) |
| 1376 | set(libprofiler_la_LIBADD stacktrace ${maybe_threads_lib} fake_stacktrace_scope) |
| 1377 | add_library(profiler SHARED ${libprofiler_la_SOURCES}) |
| 1378 | target_link_libraries(profiler PRIVATE ${libprofiler_la_LIBADD}) |
| 1379 | set_target_properties(profiler PROPERTIES |
| 1380 | VERSION ${PROFILER_SO_VERSION} |
| 1381 | SOVERSION ${PROFILER_SO_VERSION}) |
| 1382 | install(TARGETS profiler) |
| 1383 | if(GPERFTOOLS_BUILD_STATIC) |
| 1384 | add_library(profiler_static STATIC ${libprofiler_la_SOURCES}) |
| 1385 | target_link_libraries(profiler_static PRIVATE ${libprofiler_la_LIBADD}) |
| 1386 | if(NOT MSVC) |
| 1387 | set_target_properties(profiler_static PROPERTIES OUTPUT_NAME profiler) |
| 1388 | endif() |
| 1389 | install(TARGETS profiler_static) |
| 1390 | endif() |
| 1391 | |
| 1392 | # See discussion above (under LIBTCMALLOC_MINIMAL) for why we do this. |
| 1393 | # Basically it's to work around systems where --rpath doesn't work right. |
| 1394 | set(LIBPROFILER stacktrace profiler) |
| 1395 | |
| 1396 | if(BUILD_TESTING) |
| 1397 | add_executable(getpc_test src/tests/getpc_test.cc src/getpc.h) |
| 1398 | add_test(getpc_test getpc_test) |
| 1399 | |
| 1400 | add_executable(profiledata_unittest src/tests/profiledata_unittest.cc |
| 1401 | src/profiledata.h |
| 1402 | src/base/commandlineflags.h |
| 1403 | src/base/logging.h |
| 1404 | src/base/basictypes.h) |
| 1405 | target_link_libraries(profiledata_unittest ${LIBPROFILER}) |
| 1406 | add_test(profiledata_unittest profiledata_unittest) |
| 1407 | |
| 1408 | add_executable(profile_handler_unittest src/tests/profile-handler_unittest.cc |
| 1409 | src/profile-handler.h) |
| 1410 | target_link_libraries(profile_handler_unittest ${LIBPROFILER} Threads::Threads) |
| 1411 | add_test(profile_handler_unittest profile_handler_unittest) |
| 1412 | |
| 1413 | add_test(NAME profiler_unittest.sh |
| 1414 | COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/profiler_unittest.sh") |
| 1415 | set(PROFILER_UNITTEST_INCLUDES src/config_for_unittests.h |
| 1416 | src/gperftools/profiler.h) |
| 1417 | set(PROFILER_UNITTEST_SRCS src/tests/profiler_unittest.cc |
| 1418 | src/tests/testutil.h src/tests/testutil.cc |
| 1419 | ${PROFILER_UNITTEST_INCLUDES}) |
| 1420 | add_executable(profiler1_unittest ${PROFILER_UNITTEST_SRCS}) |
| 1421 | target_compile_definitions(profiler1_unittest PRIVATE NO_THREADS) |
| 1422 | target_link_libraries(profiler1_unittest ${LIBPROFILER}) |
| 1423 | add_executable(profiler2_unittest ${PROFILER_UNITTEST_SRCS}) |
| 1424 | target_compile_definitions(profiler2_unittest PRIVATE NO_THREADS) |
| 1425 | target_link_libraries(profiler2_unittest stacktrace profiler) |
| 1426 | add_executable(profiler3_unittest ${PROFILER_UNITTEST_SRCS}) |
| 1427 | target_link_libraries(profiler3_unittest ${LIBPROFILER} Threads::Threads) |
| 1428 | add_executable(profiler4_unittest ${PROFILER_UNITTEST_SRCS}) |
| 1429 | target_link_libraries(profiler4_unittest stacktrace profiler Threads::Threads) |
| 1430 | endif() |
| 1431 | endif() |
| 1432 | |
| 1433 | install(FILES |
| 1434 | ${CMAKE_CURRENT_BINARY_DIR}/gperftools/tcmalloc.h |
| 1435 | ${perftoolsinclude_HEADERS} |
| 1436 | DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gperftools) |
| 1437 | |
| 1438 | ### ------- CPU profiler and heap checker, in one! |
| 1439 | |
| 1440 | # Ideally, folks who wanted to use both tcmalloc and libprofiler, |
| 1441 | # could just link them both into their application. But while this |
| 1442 | # works fine for .so files, it does not for .a files. The easiest way |
| 1443 | # around this -- and I've tried a bunch of the hard ways -- is to just |
| 1444 | # to create another set of libraries that has both functionality in it. |
| 1445 | |
| 1446 | if(GPERFTOOLS_BUILD_HEAP_PROFILER OR GPERFTOOLS_BUILD_HEAP_CHECKER) |
| 1447 | if(GPERFTOOLS_BUILD_CPU_PROFILER) |
| 1448 | add_library(tcmalloc_and_profiler SHARED ${libtcmalloc_la_SOURCES} ${libprofiler_la_SOURCES}) |
| 1449 | target_compile_definitions(tcmalloc_and_profiler PRIVATE ${libtcmalloc_la_DEFINE}) |
| 1450 | set_target_properties(tcmalloc_and_profiler PROPERTIES |
| 1451 | VERSION ${TCMALLOC_AND_PROFILER_SO_VERSION} |
| 1452 | SOVERSION ${TCMALLOC_AND_PROFILER_SO_VERSION}) |
| 1453 | # We don't include libprofiler_la_LIBADD here because all it adds is |
| 1454 | # libstacktrace.la, which we already get via libtcmalloc. Trying to |
| 1455 | # specify it twice causes link-time duplicate-definition errors. :-( |
| 1456 | target_link_libraries(tcmalloc_and_profiler PRIVATE ${libtcmalloc_la_LIBADD}) |
| 1457 | weaken_object(tcmalloc_and_profiler) |
| 1458 | install(TARGETS tcmalloc_and_profiler) |
| 1459 | if(GPERFTOOLS_BUILD_STATIC) |
| 1460 | add_library(tcmalloc_and_profiler_static STATIC ${libtcmalloc_la_SOURCES} ${libprofiler_la_SOURCES}) |
| 1461 | target_compile_definitions(tcmalloc_and_profiler_static PRIVATE ${libtcmalloc_la_DEFINE}) |
| 1462 | target_link_libraries(tcmalloc_and_profiler_static PRIVATE ${libtcmalloc_la_LIBADD}) |
| 1463 | if(NOT MSVC) |
| 1464 | set_target_properties(tcmalloc_and_profiler_static PROPERTIES |
| 1465 | OUTPUT_NAME tcmalloc_and_profiler) |
| 1466 | endif() |
| 1467 | weaken_object(tcmalloc_and_profiler_static) |
| 1468 | install(TARGETS tcmalloc_and_profiler_static) |
| 1469 | endif() |
| 1470 | |
| 1471 | if(BUILD_TESTING) |
| 1472 | add_executable(tcmalloc_and_profiler_unittest ${tcmalloc_both_unittest_srcs}) |
| 1473 | target_link_libraries(tcmalloc_and_profiler_unittest tcmalloc_and_profiler Threads::Threads) |
| 1474 | add_test(tcmalloc_and_profiler_unittest tcmalloc_and_profiler_unittest) |
| 1475 | endif() |
| 1476 | endif() |
| 1477 | endif() |
| 1478 | |
| 1479 | if(BUILD_TESTING) |
| 1480 | get_directory_property(tests TESTS) |
| 1481 | message("TESTS_ENVIRONMENT:${TESTS_ENVIRONMENT}") |
| 1482 | if(TESTS_ENVIRONMENT) |
| 1483 | foreach(test IN LISTS tests) |
| 1484 | set_tests_properties(${test} PROPERTIES ENVIRONMENT "${TESTS_ENVIRONMENT}") |
| 1485 | endforeach() |
| 1486 | endif() |
| 1487 | endif() |
| 1488 | |
| 1489 | if(MSVC) |
| 1490 | add_subdirectory(src/windows) |
| 1491 | endif() |
| 1492 | |
| 1493 | ## ^^^^ END OF RULES TO MAKE YOUR LIBRARIES, BINARIES, AND UNITTESTS |
| 1494 | #TODO rpm deb |
| 1495 | |
| 1496 | # http://linux.die.net/man/1/pkg-config, http://pkg-config.freedesktop.org/wiki |
| 1497 | # I get the description and URL lines from the rpm spec. I use sed to |
| 1498 | # try to rewrite exec_prefix, libdir, and includedir in terms of |
| 1499 | # prefix, if possible. |
| 1500 | set(PTHREAD_FLAGS) |
| 1501 | foreach(flag IN ITEMS INTERFACE_LINK_LIBRARIES INTERFACE_LINK_OPTIONS INTERFACE_INCLUDE_DIRECTORIES INTERFACE_COMPILE_OPTIONS INTERFACE_COMPILE_DEFINITIONS INTERFACE_SOURCES) |
| 1502 | get_target_property(T Threads::Threads ${flag}) |
| 1503 | if(T) |
| 1504 | set(PTHREAD_FLAGS "${PTHREAD_FLAGS} ${T}") |
| 1505 | endif() |
| 1506 | endforeach() |
| 1507 | set(NAME tcmalloc) |
| 1508 | configure_file(cmake/pkgconfig.pc libtcmalloc.pc @ONLY) |
| 1509 | set(NAME tcmalloc_debug) |
| 1510 | configure_file(cmake/pkgconfig.pc libtcmalloc_debug.pc @ONLY) |
| 1511 | set(NAME tcmalloc_minimal) |
| 1512 | configure_file(cmake/pkgconfig.pc libtcmalloc_minimal.pc @ONLY) |
| 1513 | set(NAME tcmalloc_minimal_debug) |
| 1514 | configure_file(cmake/pkgconfig.pc libtcmalloc_minimal_debug.pc @ONLY) |
| 1515 | set(NAME profiler) |
| 1516 | configure_file(cmake/pkgconfig.pc libprofiler.pc @ONLY) |
| 1517 | install(FILES |
| 1518 | ${CMAKE_CURRENT_BINARY_DIR}/libtcmalloc.pc |
| 1519 | ${CMAKE_CURRENT_BINARY_DIR}/libtcmalloc_minimal.pc |
| 1520 | ${CMAKE_CURRENT_BINARY_DIR}/libtcmalloc_debug.pc |
| 1521 | ${CMAKE_CURRENT_BINARY_DIR}/libtcmalloc_minimal_debug.pc |
| 1522 | ${CMAKE_CURRENT_BINARY_DIR}/libprofiler.pc |
| 1523 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") |
| 1524 | |
| 1525 | #TODO @GENERATE_CHANGELOG_RULES@ |
| 1526 | #TODO dist |