blob: 05e37ee733cbede4e4410cdd2065b2604373c178 [file] [log] [blame]
Brian Silverman20350ac2021-11-17 18:19:55 -08001cmake_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
8project(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!
13set(TCMALLOC_SO_VERSION 9.9.5)
14set(PROFILER_SO_VERSION 5.4.5)
15set(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.
22set(DEFAULT_BUILD_CPU_PROFILER ON)
23set(DEFAULT_BUILD_HEAP_PROFILER ON)
24set(DEFAULT_BUILD_HEAP_CHECKER ON)
25set(DEFAULT_BUILD_DEBUGALLOC ON)
26set(DEFAULT_BUILD_MINIMAL OFF)
27
28set(DEFAULT_TCMALLOC_ALIGNMENT 16)
29set(NEED_NANOSLEEP ON) # Used later, to decide if to run ACX_NANOSLEEP
30
31set(HOST string(TOLOWER "${CMAKE_SYSTEM_NAME}"))
32
33if(MINGW OR MSVC)
34 set(DEFAULT_BUILD_MINIMAL ON)
35 set(DEFAULT_BUILD_DEBUGALLOC OFF)
36 set(NEED_NANOSLEEP OFF)
37elseif(CYGWIN)
38 set(DEFAULT_BUILD_HEAP_CHECKER OFF)
39 set(DEFAULT_BUILD_CPU_PROFILER OFF)
40elseif(HOST MATCHES "freebsd")
41 set(DEFAULT_BUILD_HEAP_CHECKER OFF)
42elseif(APPLE)
43 set(DEFAULT_BUILD_HEAP_CHECKER OFF)
44endif()
45
46include(CheckCCompilerFlag)
47include(CheckCSourceCompiles)
48include(CheckCXXSourceCompiles)
49include(CheckFunctionExists)
50include(CheckIncludeFile)
51include(CheckLibraryExists)
52include(CheckSymbolExists)
53include(CheckTypeSize)
54include(CheckVariableExists)
55include(CMakeDependentOption)
56include(CTest)
57include(CPack)
58include(GNUInstallDirs)
59
60list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
61include(DefineTargetVariables)
62include(FindObjcopyWithWeaken)
63include(PCFromUContext)
64
65define_target_variables()
66
67# Currently only backtrace works on s390.
68if(s390 OR OSX)
69 set(default_enable_libunwind OFF)
70 set(default_enable_backtrace ON)
71else()
72 set(default_enable_libunwind ON)
73 set(default_enable_backtrace OFF)
74endif()
75
76# Disable libunwind linking on ppc64 by default.
77if(PPC64)
78 set(default_enable_libunwind OFF)
79 set(default_tcmalloc_pagesize 64)
80else()
81 set(default_enable_libunwind ON)
82 set(default_tcmalloc_pagesize 8)
83endif()
84
85cmake_dependent_option(
86 GPERFTOOLS_BUILD_CPU_PROFILER "Build cpu-profiler" ${DEFAULT_BUILD_CPU_PROFILER}
87 "NOT gperftools_build_minimal" OFF)
88cmake_dependent_option(
89 GPERFTOOLS_BUILD_HEAP_PROFILER "Build heap-profiler" ${DEFAULT_BUILD_HEAP_PROFILER}
90 "NOT gperftools_build_minimal" OFF)
91cmake_dependent_option(
92 GPERFTOOLS_BUILD_HEAP_CHECKER "Build heap-checker" ${DEFAULT_BUILD_HEAP_CHECKER}
93 "NOT gperftools_build_minimal" OFF)
94cmake_dependent_option(
95 GPERFTOOLS_BUILD_DEBUGALLOC "Build debugalloc" ${DEFAULT_BUILD_DEBUGALLOC}
96 "NOT gperftools_build_minimal" OFF)
97option(
98 gperftools_build_minimal
99 "Build only tcmalloc-minimal (and maybe tcmalloc-minimal-debug)"
100 ${DEFAULT_BUILD_MINIMAL})
101if(gperftools_build_minimal)
102 set(GPERFTOOLS_BUILD_CPU_PROFILER OFF)
103 set(GPERFTOOLS_BUILD_HEAP_PROFILER OFF)
104 set(GPERFTOOLS_BUILD_HEAP_CHECKER OFF)
105endif()
106
107cmake_dependent_option(
108 gperftools_build_benchmark "Build benchmark" ON "NOT MINGW AND NOT MSVC" OFF)
109
110option(gperftools_enable_stacktrace_via_backtrace
111 "Enable use of backtrace() for stacktrace capturing (may deadlock)"
112 ${default_enable_backtrace})
113option(gperftools_enable_libunwind
114 "Enable libunwind linking"
115 ${default_enable_libunwind})
116
117set(enable_backtrace ${gperftools_enable_stacktrace_via_backtrace})
118set(enable_libunwind ${gperftools_enable_libunwind})
119
120set(gperftools_tcmalloc_pagesize ${default_tcmalloc_pagesize}
121 CACHE STRING "Set the tcmalloc internal page size")
122set_property(CACHE gperftools_tcmalloc_pagesize PROPERTY STRINGS "8" "32" "64")
123if(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})
130endif()
131if (gperftools_tcmalloc_pagesize STREQUAL "32" OR
132 gperftools_tcmalloc_pagesize STREQUAL "64")
133 set(TCMALLOC_${gperftools_tcmalloc_pagesize}K_PAGES ON)
134endif()
135
136set(gperftools_tcmalloc_alignment ${DEFAULT_TCMALLOC_ALIGNMENT}
137 CACHE STRING "Set the tcmalloc allocation alignment")
138set_property(CACHE gperftools_tcmalloc_alignment PROPERTY STRINGS "8" "16")
139if(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})
145endif()
146if(gperftools_tcmalloc_alignment STREQUAL "8")
147 set(TCMALLOC_ALIGN_8BYTES ON)
148endif()
149
150# AX_CXX_COMPILE_STDCXX(11, ext, mandatory)
151if(cxx_std_17 IN_LIST CMAKE_CXX_COMPILE_FEATURES)
152 set(CMAKE_CXX_STANDARD 17) # std::align_val_t
153else()
154 set(CMAKE_CXX_STANDARD 11)
155endif()
156set(CMAKE_CXX_STANDARD_REQUIRED ON)
157set(CMAKE_CXX_EXTENSIONS ON)
158
159# Check if we have an objcopy installed that supports -W
160find_objcopy_with_weaken()
161
162# AX_C___ATTRIBUTE__
163check_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
169set(CMAKE_EXTRA_INCLUDE_FILES "malloc.h")
170check_type_size("struct mallinfo" STRUCT_MALLINFO LANGUAGE CXX)
171set(CMAKE_EXTRA_INCLUDE_FILES "elf.h")
172check_type_size("Elf32_Versym" ELF32_VERSYM LANGUAGE CXX) # for vdso_support.h
173set(CMAKE_EXTRA_INCLUDE_FILES)
174check_function_exists("sbrk" HAVE_SBRK) # for tcmalloc to get memory
175check_function_exists("__sbrk" HAVE_SBRK) # for tcmalloc to get memory
176check_function_exists("geteuid" HAVE_GETEUID) # for turning off services when run as root
177check_function_exists("fork" HAVE_FORK) # for the pthread_atfork setup
178check_include_file("features.h" HAVE_FEATURES_H) # for vdso_support.h, Where __GLIBC__ is defined
179check_include_file("malloc.h" HAVE_MALLOC_H) # some systems define stuff there, others not
180check_include_file("glob.h" HAVE_GLOB_H) # for heap-profile-table (cleaning up profiles)
181check_include_file("execinfo.h" HAVE_EXECINFO_H) # for stacktrace? and heapchecker_unittest
182check_include_file("unwind.h" HAVE_UNWIND_H) # for stacktrace
183check_include_file("sched.h" HAVE_SCHED_H) # for being nice in our spinlock code
184check_include_file("sys/prctl.h" HAVE_SYS_PRCTL_H) # for thread_lister (needed by leak-checker)
185check_include_file("linux/ptrace.h" HAVE_LINUX_PTRACE_H) # also needed by leak-checker
186check_include_file("sys/syscall.h" HAVE_SYS_SYSCALL_H)
187check_include_file("sys/socket.h" HAVE_SYS_SOCKET_H) # optional; for forking out to symbolizer
188check_include_file("sys/wait.h" HAVE_SYS_WAIT_H) # optional; for forking out to symbolizer
189check_include_file("poll.h" HAVE_POLL_H) # optional; for forking out to symbolizer
190check_include_file("fcntl.h" HAVE_FCNTL_H) # for tcmalloc_unittest
191check_include_file("grp.h" HAVE_GRP_H) # for heapchecker_unittest
192check_include_file("pwd.h" HAVE_PWD_H) # for heapchecker_unittest
193check_include_file("sys/resource.h" HAVE_SYS_RESOURCE_H) # for memalign_unittest.cc
194check_include_file("sys/cdefs.h" HAVE_SYS_CDEFS_H) # Where glibc defines __THROW
195
196check_include_file("unistd.h" HAVE_UNISTD_H)
197check_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.
203set(CMAKE_REQUIRED_DEFINITIONS -D_XOPEN_SOURCE=600)
204check_symbol_exists("cfree" "stdlib.h;malloc.h" HAVE_DECL_CFREE)
205check_symbol_exists("posix_memalign" "stdlib.h;malloc.h" HAVE_DECL_POSIX_MEMALIGN)
206check_symbol_exists("memalign" "stdlib.h;malloc.h" HAVE_DECL_MEMALIGN)
207check_symbol_exists("valloc" "stdlib.h;malloc.h" HAVE_DECL_VALLOC)
208check_symbol_exists("pvalloc" "stdlib.h;malloc.h" HAVE_DECL_PVALLOC)
209set(CMAKE_REQUIRED_DEFINITIONS)
210
211if(HAVE_STRUCT_MALLINFO)
212 set(HAVE_STRUCT_MALLINFO 1)
213else()
214 set(HAVE_STRUCT_MALLINFO 0)
215endif()
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.
221if(NOT WIN32)
222 set(HAVE_MMAP 1)
223endif()
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.
227check_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
243if (GPERFTOOLS_BUILD_CPU_PROFILER)
244 pc_from_ucontext(PC_FROM_UCONTEXT_DEF)
245endif ()
246
247# Some tests test the behavior of .so files, and only make sense for dynamic.
248option(GPERFTOOLS_BUILD_STATIC "Enable Static" ON)
249
250if(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()
263endif()
264
265# On x86_64, we know that default is to omit frame pointer.
266if(x86_64)
267 set(omit_fp_by_default ON)
268endif()
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.
274check_c_compiler_flag("-Wno-unused-result" have_w_no_unused_result)
275
276option(gperftools_dynamic_sized_delete_support
277 "Try to build run-time switch for sized delete operator"
278 OFF)
279if(gperftools_dynamic_sized_delete_support)
280 set(ENABLE_DYNAMIC_SIZED_DELETE 1)
281endif()
282
283option(gperftools_sized_delete "Build sized delete operator" OFF)
284if(gperftools_sized_delete)
285 set(ENABLE_SIZED_DELETE 1)
286endif()
287
288if(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)
295endif()
296
297check_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)
301if(HAVE_STD_ALIGN_VAL_T)
302 set(HAVE_STD_ALIGN_VAL_T 1)
303else()
304 set(HAVE_STD_ALIGN_VAL_T 0)
305endif()
306
307check_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
319if(enable_backtrace)
320 set(default_emergency_malloc ON)
321else()
322 set(default_emergency_malloc OFF)
323endif()
324
325if(will_use_libunwind AND ARM)
326 set(default_emergency_malloc ON)
327endif()
328
329option(gperftools_emergency_malloc
330 "Build emergency malloc"
331 ${default_emergency_malloc})
332
333check_c_source_compiles(
334 "int main() { return __builtin_expect(main != 0, 1); }"
335 HAVE_BUILTIN_EXPECT)
336
337check_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
357if(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")
360elseif(APPLE)
361 message(WARNING "OSX __thread support is known to call malloc which makes "
362 "it unsafe to use from malloc replacement")
363elseif(MINGW)
364 message(WARNING "mingw doesn't really support tls")
365else()
366 check_c_source_compiles("static __thread int p = 0; int main() {}" HAVE_TLS)
367endif()
368
369if(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()
389endif()
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.
394if(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()
405endif()
406
407find_package(Threads REQUIRED)
408set(HAVE_PTHREAD ${CMAKE_USE_PTHREADS_INIT})
409foreach(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()
418endforeach()
419
420if(FreeBSD)
421 set(PTHREADS_CRASHES_IF_RUN_TOO_EARLY ON)
422endif()
423
424set(libstdcxx_la_linker_flag)
425if(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()
430endif()
431
432check_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
438check_variable_exists("program_invocation_name" HAVE_PROGRAM_INVOCATION_NAME)
439
440if(MINGW)
441 check_symbol_exists("sleep" "unistd.h" HAVE_DECL_SLEEP)
442 check_symbol_exists("nanosleep" "time.h" HAVE_DECL_NANOSLEEP)
443endif()
444
445if(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)
451endif()
452
453configure_file(cmake/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h @ONLY)
454configure_file(cmake/tcmalloc.h.in
455 ${CMAKE_CURRENT_BINARY_DIR}/gperftools/tcmalloc.h
456 @ONLY)
457
458if(GPERFTOOLS_BUILD_CPU_PROFILER OR
459 GPERFTOOLS_BUILD_HEAP_PROFILER OR
460 GPERFTOOLS_BUILD_HEAP_CHECKER)
461 set(WITH_STACK_TRACE ON)
462endif()
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).
468if (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()
482endif()
483
484# Based on Makefile.am
485
486set(CMAKE_POSITION_INDEPENDENT_CODE ON)
487set(CMAKE_INCLUDE_CURRENT_DIR ON)
488# This is so we can #include <gperftools/foo>
489include_directories($<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>)
490
491if(NOT WITH_STACK_TRACE)
492 add_compile_definitions(NO_TCMALLOC_SAMPLES)
493endif()
494
495# These are good warnings to turn on by default.
496if(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()
507endif()
508
509if(have_w_no_unused_result)
510 add_compile_options(-Wno-unused-result)
511endif()
512
513if(have_sized_deallocation)
514 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsized-deallocation")
515endif()
516
517if(have_f_aligned_new)
518 add_compile_options(-faligned-new)
519endif()
520
521# LIBSTDCXX_LA_LINKER_FLAG is used to fix a Solaris bug.
522add_link_options(${libstdcxx_la_linker_flag})
523
524option(
525 gperftools_enable_frame_pointers
526 "Compile with -fno-omit-frame-pointer (see INSTALL)"
527 OFF)
528
529if(gperftools_enable_frame_pointers)
530 add_compile_options(-fno-omit-frame-pointer)
531endif()
532
533if(omit_fp_by_default AND NOT gperftools_enable_frame_pointers)
534 add_compile_definitions(NO_FRAME_POINTER)
535endif()
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.
542set(TCMALLOC_FLAGS)
543if(MINGW)
544 list(APPEND TCMALLOC_FLAGS "-Wl,-u__tcmalloc")
545endif()
546
547set(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 )
558install(FILES ${googleinclude_HEADERS}
559 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/google
560 )
561
562# This is a 'convenience library' -- it's not actually installed or anything
563set(LOGGING_INCLUDES
564 src/base/logging.h
565 src/base/commandlineflags.h
566 src/base/basictypes.h
567 src/base/dynamic_annotations.h)
568set(liblogging_la_SOURCES src/base/logging.cc
569 src/base/dynamic_annotations.c
570 ${LOGGING_INCLUDES})
571add_library(logging STATIC ${liblogging_la_SOURCES})
572
573set(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)
580set(libsysinfo_la_SOURCES src/base/sysinfo.cc
581 ${SYSINFO_INCLUDES})
582set(libsysinfo_la_LIBADD ${NANOSLEEP_LIBS})
583add_library(sysinfo STATIC ${libsysinfo_la_SOURCES})
584target_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.
593if(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()
642else()
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)
662endif()
663
664if(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)
702endif()
703
704### ------- stack trace
705
706if(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
751endif()
752
753### ------- pprof
754
755# If we are not compiling with stacktrace support, pprof is worthless
756if(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()
768endif()
769
770### ------- tcmalloc_minimal (thread-caching malloc)
771
772### The header files we use. We divide into categories based on directory
773set(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)
801set(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)
806set(TCMALLOC_MINIMAL_INCLUDES ${S_TCMALLOC_MINIMAL_INCLUDES} ${SG_TCMALLOC_MINIMAL_INCLUDES} ${SG_STACKTRACE_INCLUDES})
807list(APPEND perftoolsinclude_HEADERS ${SG_TCMALLOC_MINIMAL_INCLUDES})
808
809### Making the library
810
811set(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})
826add_library(tcmalloc_minimal_internal_object OBJECT ${libtcmalloc_minimal_internal_la_SOURCES})
827# We #define NO_TCMALLOC_SAMPLES, since sampling is turned off for _minimal.
828target_compile_definitions(tcmalloc_minimal_internal_object PRIVATE NO_TCMALLOC_SAMPLES NO_HEAP_CHECK NDEBUG)
829add_library(tcmalloc_minimal_internal INTERFACE)
830target_link_libraries(tcmalloc_minimal_internal INTERFACE ${LIBSPINLOCK} ${maybe_threads_lib})
831target_sources(tcmalloc_minimal_internal INTERFACE $<TARGET_OBJECTS:tcmalloc_minimal_internal_object>)
832
833set(libtcmalloc_minimal_la_SOURCES ${TCMALLOC_CC} ${TCMALLOC_MINIMAL_INCLUDES})
834set(libtcmalloc_minimal_la_DEFINES NO_TCMALLOC_SAMPLES NDEBUG)
835add_library(tcmalloc_minimal SHARED ${libtcmalloc_minimal_la_SOURCES})
836target_compile_definitions(tcmalloc_minimal PRIVATE ${libtcmalloc_minimal_la_DEFINES})
837set(libtcmalloc_minimal_la_LIBADD tcmalloc_minimal_internal)
838target_link_libraries(tcmalloc_minimal PRIVATE tcmalloc_minimal_internal Threads::Threads)
839if(MINGW)
840 target_link_libraries(tcmalloc_minimal PRIVATE stacktrace)
841endif()
842set_target_properties(tcmalloc_minimal PROPERTIES
843 VERSION ${TCMALLOC_SO_VERSION}
844 SOVERSION ${TCMALLOC_SO_VERSION})
845weaken_object(tcmalloc_minimal)
846install(TARGETS tcmalloc_minimal)
847if(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)
860endif()
861
862if(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)
1009endif()
1010
1011### ------- tcmalloc_minimal_debug (thread-caching malloc with debugallocation)
1012
1013if(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()
1069endif()
1070
1071if(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()
1100endif()
1101
1102### ------- tcmalloc (thread-caching malloc + heap profiler + heap checker)
1103
1104if(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")
1293endif()
1294 endif()
1295
1296endif()
1297
1298### ------- tcmalloc with debugallocation
1299if(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()
1350endif()
1351
1352### ------- CPU profiler
1353if(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()
1431endif()
1432
1433install(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
1446if(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()
1477endif()
1478
1479if(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()
1487endif()
1488
1489if(MSVC)
1490 add_subdirectory(src/windows)
1491endif()
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.
1500set(PTHREAD_FLAGS)
1501foreach(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()
1506endforeach()
1507set(NAME tcmalloc)
1508configure_file(cmake/pkgconfig.pc libtcmalloc.pc @ONLY)
1509set(NAME tcmalloc_debug)
1510configure_file(cmake/pkgconfig.pc libtcmalloc_debug.pc @ONLY)
1511set(NAME tcmalloc_minimal)
1512configure_file(cmake/pkgconfig.pc libtcmalloc_minimal.pc @ONLY)
1513set(NAME tcmalloc_minimal_debug)
1514configure_file(cmake/pkgconfig.pc libtcmalloc_minimal_debug.pc @ONLY)
1515set(NAME profiler)
1516configure_file(cmake/pkgconfig.pc libprofiler.pc @ONLY)
1517install(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