# -*- mode: python -*- Import("env") Import("has_option") Import("use_libunwind") Import("debugBuild") Import("selected_experimental_optimizations") env = env.Clone( # Building with hidden visibility interferes with intercepting the # libc allocation functions. DISALLOW_VISHIDDEN=True, NINJA_GENSOURCE_INDEPENDENT=True, ) # If we don't have a frame pointer, we need to tell tcmalloc so that # it doesn't try to select a frame pointer based unwinder like # generic_fp. For debugBuilds, we also don't want the generic_fp or # libunwind based unwinders because they are currently too slow. We # will still fall back to libunwind if it is present and no better # option is available. Note that defining # TCMALLOC_DONT_PREFER_LIBUNWIND has real effects even if libunwind # isn't in play. Specifically, it enables the architecture specific # implementations for x86 and ppc. # # Please see the following gperftools issues for ongoing discussion: # # https://github.com/gperftools/gperftools/issues/1276 # https://github.com/gperftools/gperftools/issues/1277 # https://github.com/gperftools/gperftools/issues/1278 # fp = 'nofp' not in selected_experimental_optimizations if not fp or debugBuild: env.Append( CPPDEFINES=[ 'NO_FRAME_POINTER', 'TCMALLOC_DONT_PREFER_LIBUNWIND' if debugBuild else None, ], ) if use_libunwind: env.Append(CPPDEFINES=[ ("HAVE_LIBUNWIND_H", "1"), 'HAVE_UCONTEXT_H', ], ) env.InjectThirdParty(libraries=['unwind']) files = [ 'src/base/dynamic_annotations.c', 'src/base/elf_mem_image.cc', 'src/base/logging.cc', 'src/base/spinlock.cc', 'src/base/spinlock_internal.cc', 'src/base/sysinfo.cc', 'src/base/vdso_support.cc', 'src/central_freelist.cc', 'src/common.cc', 'src/internal_logging.cc', 'src/malloc_extension.cc', 'src/malloc_hook.cc', 'src/memfs_malloc.cc', 'src/page_heap.cc', 'src/sampler.cc', 'src/span.cc', 'src/stack_trace_table.cc', 'src/stacktrace.cc', 'src/static_vars.cc', 'src/symbolize.cc', 'src/thread_cache.cc', ] if env.TargetOSIs('windows'): files += [ 'src/tcmalloc.cc', 'src/windows/port.cc', 'src/windows/system-alloc.cc', 'src/fake_stacktrace_scope.cc', ] # warning C4141: 'inline': used more than once # warning C4305: 'argument': truncation from 'ssize_t' to 'double' # warning C4003: not enough arguments for function-like macro invocation env.Append(CXXFLAGS=["/wd4141", "/wd4305", '/wd4003']) else: files += [ 'src/emergency_malloc_for_stacktrace.cc', 'src/maybe_threads.cc', 'src/system-alloc.cc', ] if not debugBuild: files += ['src/tcmalloc.cc'] else: files += ['src/debugallocation.cc'] # gperftools has some sloppy write calls that emit warnings env.Append(CXXFLAGS=["-Wno-unused-result"]) env.Append(CPPDEFINES=["NO_HEAP_CHECK"], ) # The build system doesn't define NDEBUG globally for historical reasons, however, TCMalloc # expects that NDEBUG is used to select between preferring the mmap or the sbrk allocator. For # non-debug builds, we want to prefer the sbrk allocator since this is TCMallocs preferred # production deployment configuration. See the use of NDEBUG and kDebugMode in # src/system-alloc.cc for more details. if not debugBuild: env.Append(CPPDEFINES=["NDEBUG"]) # For debug builds we want to capture stacks during (de)allocations, # but we don't want to pay that cost for release builds. For non-debug # builds we use NO_TCMALLOC_SAMPLES to disable the stack trace # collection. For debug builds we enable stack capture, but only on # intel targets, since tcmalloc's unwinder is very slow on other # platforms (see SERVER-28502). if (not debugBuild) or (not env['TARGET_ARCH'] in ['x86_64', 'i386']): env.Append(CPPDEFINES=["NO_TCMALLOC_SAMPLES"]) gperftools_root = env.Dir("#/src/third_party/gperftools") gperftools_platform = gperftools_root.Dir("platform/${TARGET_OS}_${TARGET_ARCH}") env.Append(CPPPATH=[ gperftools_platform.Dir("internal/src"), gperftools_root.Dir("dist/src"), ]) # propagates to consumers that Inject (depend on) gperftools. env.RegisterConsumerModifications(CPPPATH=[gperftools_platform.Dir("include")]) def removeIfPresent(lst, item): try: lst.remove(item) except ValueError: pass env['CCFLAGS_WERROR'] = [] env['CXXFLAGS_WERROR'] = [] for to_remove in ["-Wsign-compare", "-Wall"]: removeIfPresent(env['CCFLAGS'], to_remove) if not env.TargetOSIs('windows'): env.Append(CXXFLAGS=['-Wno-unused-result']) if env.ToolchainIs('GCC'): env.Append(CXXFLAGS=['-Wno-attribute-alias']) # GCC on PowerPC under C++11 mode does not define __linux which gperftools depends on if env['TARGET_ARCH'] == 'ppc64le': env.Append(CPPDEFINES=["__linux"]) env.Library( target='tcmalloc_minimal', source=[env.Dir('dist').File(f) for f in files], LIBDEPS_PRIVATE=[ '$BUILD_DIR/third_party/shim_unwind' if use_libunwind else [], ], )