| # Copyright (C) 2018 The Android Open Source Project | 
 | # | 
 | # Licensed under the Apache License, Version 2.0 (the "License"); | 
 | # you may not use this file except in compliance with the License. | 
 | # You may obtain a copy of the License at | 
 | # | 
 | #      http://www.apache.org/licenses/LICENSE-2.0 | 
 | # | 
 | # Unless required by applicable law or agreed to in writing, software | 
 | # distributed under the License is distributed on an "AS IS" BASIS, | 
 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | # See the License for the specific language governing permissions and | 
 | # limitations under the License. | 
 |  | 
 | import("../../../gn/fuzzer.gni") | 
 | import("../../../gn/perfetto.gni") | 
 | import("../../../gn/test.gni") | 
 |  | 
 | assert(enable_perfetto_heapprofd) | 
 |  | 
 | # The Android heap profiling daemon. | 
 | executable("heapprofd") { | 
 |   deps = [ | 
 |     ":heapprofd_main", | 
 |     "../../../gn:default_deps", | 
 |   ] | 
 |   sources = [ "main.cc" ] | 
 | } | 
 |  | 
 | source_set("heapprofd_main") { | 
 |   deps = [ | 
 |     "../../../gn:default_deps", | 
 |     "../../../protos/perfetto/trace:zero", | 
 |     "../../../src/base", | 
 |     "../../../src/base:unix_socket", | 
 |     "../../../src/profiling/memory:daemon", | 
 |     "../../../src/profiling/memory:wire_protocol", | 
 |     "../../../src/tracing/ipc/producer", | 
 |   ] | 
 |   sources = [ | 
 |     "heapprofd.cc", | 
 |     "heapprofd.h", | 
 |   ] | 
 | } | 
 |  | 
 | # This library gets loaded into (and executes in) arbitrary android processes. | 
 | # Logging must be non-allocating. This is achieved by defining | 
 | # PERFETTO_ANDROID_ASYNC_SAFE_LOG, which needs to be set for all perfetto code | 
 | # being compiled for this library. When generating Android.bp, the |cflags| | 
 | # entry on this target is sufficient (as all sources are flattened into a | 
 | # single bp target). However this is not correctly reflected in the gn | 
 | # structure (which is a tree of targets) as the dependencies would not pick | 
 | # up the flag (and thus use the wrong logging macro). | 
 | # | 
 | # This builds only in the Android tree, when using the generated Android.bp. | 
 | if (perfetto_build_with_android) { | 
 |   shared_library("heapprofd_client") { | 
 |     configs -= [ "//gn/standalone:android_liblog" ] | 
 |     cflags = [ "-DPERFETTO_ANDROID_ASYNC_SAFE_LOG" ] | 
 |     deps = [ | 
 |       ":heapprofd_client_api", | 
 |       ":malloc_interceptor_bionic_hooks", | 
 |     ] | 
 |   } | 
 |  | 
 |   # This will export publicly visible symbols for the | 
 |   # malloc_interceptor_bionic_hooks. | 
 |   source_set("malloc_interceptor_bionic_hooks") { | 
 |     deps = [ | 
 |       ":bionic_libc_platform_headers_on_android", | 
 |       ":wrap_allocators", | 
 |       "../../../gn:default_deps", | 
 |       "../../base", | 
 |     ] | 
 |     cflags = [ | 
 |       "-isystem", | 
 |       rebase_path("../../../buildtools/bionic/libc", root_build_dir), | 
 |     ] | 
 |     sources = [ "malloc_interceptor_bionic_hooks.cc" ] | 
 |   } | 
 | }  # if (perfetto_build_with_android) | 
 |  | 
 | executable("heapprofd_standalone_client_example") { | 
 |   deps = [ | 
 |     ":heapprofd_standalone_client", | 
 |     "../../../gn:default_deps", | 
 |   ] | 
 |   sources = [ "heapprofd_standalone_client_example.cc" ] | 
 | } | 
 |  | 
 | source_set("client_api_standalone") { | 
 |   deps = [ | 
 |     ":client", | 
 |     ":client_api", | 
 |     ":daemon", | 
 |     "../../../gn:default_deps", | 
 |     "../../../include/perfetto/ext/tracing/ipc", | 
 |     "../../base", | 
 |     "../common:proc_utils", | 
 |   ] | 
 |   sources = [ "client_api_factory_standalone.cc" ] | 
 | } | 
 |  | 
 | # This can be used to instrument custom allocators to report their allocations | 
 | # to Perfetto. This bundles a copy of heapprofd in the library, in contrast to | 
 | # heapprofd_client_api (see below), which expects one to be present in the | 
 | # Android platform. | 
 | shared_library("heapprofd_standalone_client") { | 
 |   deps = [ | 
 |     ":client_api_standalone", | 
 |     "../../../gn:default_deps", | 
 |   ] | 
 |   ldflags = [ | 
 |     "-Wl,--version-script", | 
 |     rebase_path("heapprofd_client_api.map.txt", root_build_dir), | 
 |   ] | 
 | } | 
 |  | 
 | shared_library("heapprofd_api_noop") { | 
 |   deps = [ "../../../gn:default_deps" ] | 
 |   ldflags = [ | 
 |     "-Wl,--version-script", | 
 |     rebase_path("heapprofd_client_api.map.txt", root_build_dir), | 
 |   ] | 
 |  | 
 |   # This target does absolutely nothing, so we do not want to depend on | 
 |   # liblog. | 
 |   configs -= [ "//gn/standalone:android_liblog" ] | 
 |   sources = [ "client_api_noop.cc" ] | 
 | } | 
 |  | 
 | shared_library("heapprofd_client_api") { | 
 |   configs -= [ "//gn/standalone:android_liblog" ] | 
 |   if (perfetto_build_with_android) { | 
 |     cflags = [ "-DPERFETTO_ANDROID_ASYNC_SAFE_LOG" ] | 
 |   } else { | 
 |     # We don't have async safe logging for non-Android, so disable all | 
 |     # logging in the client. | 
 |     # TODO(fmayer): Add async-safe logging for non-Android. | 
 |     cflags = [ "-DPERFETTO_DISABLE_LOG" ] | 
 |   } | 
 |   deps = [ ":client_api" ] | 
 |   if (perfetto_build_with_android) { | 
 |     sources = [ "client_api_factory_android.cc" ] | 
 |   } | 
 | } | 
 |  | 
 | # On GLibc Linux, this can be used to override the allocators using | 
 | # LD_PRELOAD. On non-GLibc, this will probably fail to link. | 
 | shared_library("heapprofd_glibc_preload") { | 
 |   deps = [ | 
 |     ":client_api_standalone", | 
 |     ":wrap_allocators", | 
 |     "../../../gn:default_deps", | 
 |     "../../base", | 
 |   ] | 
 |   ldflags = [ | 
 |     "-Wl,--version-script", | 
 |     rebase_path("heapprofd_preload.map.txt", root_build_dir), | 
 |   ] | 
 |   sources = [ "malloc_interceptor_glibc_preload.cc" ] | 
 | } | 
 |  | 
 | # On Android builds, this is converted to | 
 | # header_libs: ["bionic_libc_platform_headers"]. | 
 | source_set("bionic_libc_platform_headers_on_android") { | 
 | } | 
 |  | 
 | source_set("client_api") { | 
 |   if (perfetto_build_with_android) { | 
 |     cflags = [ "-DPERFETTO_ANDROID_ASYNC_SAFE_LOG" ] | 
 |   } else { | 
 |     # We don't have async safe logging for non-Android, so disable all | 
 |     # logging in the client. | 
 |     # TODO(fmayer): Add async-safe logging for non-Android. | 
 |     cflags = [ "-DPERFETTO_DISABLE_LOG" ] | 
 |   } | 
 |   deps = [ | 
 |     ":client", | 
 |     ":scoped_spinlock", | 
 |     ":wire_protocol", | 
 |     "../../../gn:default_deps", | 
 |     "../../base", | 
 |   ] | 
 |   sources = [ "client_api.cc" ] | 
 | } | 
 |  | 
 | source_set("wrap_allocators") { | 
 |   deps = [ | 
 |     "../../../gn:default_deps", | 
 |     "../../base", | 
 |   ] | 
 |   sources = [ "wrap_allocators.cc" ] | 
 | } | 
 |  | 
 | source_set("wire_protocol") { | 
 |   public_deps = [ "../../../gn:libunwindstack" ] | 
 |   deps = [ | 
 |     ":bionic_libc_platform_headers_on_android", | 
 |     ":ring_buffer", | 
 |     "../../../gn:default_deps", | 
 |     "../../base", | 
 |     "../../base:unix_socket", | 
 |   ] | 
 |   sources = [ | 
 |     "wire_protocol.cc", | 
 |     "wire_protocol.h", | 
 |   ] | 
 | } | 
 |  | 
 | source_set("scoped_spinlock") { | 
 |   deps = [ | 
 |     "../../../gn:default_deps", | 
 |     "../../base", | 
 |   ] | 
 |   sources = [ | 
 |     "scoped_spinlock.cc", | 
 |     "scoped_spinlock.h", | 
 |   ] | 
 | } | 
 |  | 
 | source_set("ring_buffer") { | 
 |   deps = [ | 
 |     ":scoped_spinlock", | 
 |     "../../../gn:default_deps", | 
 |     "../../base", | 
 |   ] | 
 |   sources = [ | 
 |     "shared_ring_buffer.cc", | 
 |     "shared_ring_buffer.h", | 
 |   ] | 
 | } | 
 |  | 
 | source_set("ring_buffer_unittests") { | 
 |   testonly = true | 
 |   deps = [ | 
 |     ":ring_buffer", | 
 |     "../../../gn:default_deps", | 
 |     "../../../gn:gtest_and_gmock", | 
 |     "../../base", | 
 |   ] | 
 |   sources = [ "shared_ring_buffer_unittest.cc" ] | 
 | } | 
 |  | 
 | source_set("daemon") { | 
 |   deps = [ | 
 |     ":ring_buffer", | 
 |     ":scoped_spinlock", | 
 |     ":wire_protocol", | 
 |     "../../../gn:default_deps", | 
 |     "../../../protos/perfetto/config/profiling:cpp", | 
 |     "../../base", | 
 |     "../../base:unix_socket", | 
 |     "../../tracing/core", | 
 |     "../../tracing/ipc/producer", | 
 |     "../common:callstack_trie", | 
 |     "../common:interner", | 
 |     "../common:interning_output", | 
 |     "../common:proc_utils", | 
 |     "../common:producer_support", | 
 |     "../common:profiler_guardrails", | 
 |     "../common:unwind_support", | 
 |   ] | 
 |   public_deps = [ | 
 |     "../../../gn:libunwindstack", | 
 |     "../../../protos/perfetto/config/profiling:cpp", | 
 |     "../../../protos/perfetto/trace:zero", | 
 |     "../../../protos/perfetto/trace/interned_data:zero", | 
 |     "../../../protos/perfetto/trace/profiling:zero", | 
 |   ] | 
 |   sources = [ | 
 |     "bookkeeping.cc", | 
 |     "bookkeeping.h", | 
 |     "bookkeeping_dump.cc", | 
 |     "bookkeeping_dump.h", | 
 |     "heapprofd_producer.cc", | 
 |     "heapprofd_producer.h", | 
 |     "java_hprof_producer.cc", | 
 |     "java_hprof_producer.h", | 
 |     "log_histogram.cc", | 
 |     "log_histogram.h", | 
 |     "system_property.cc", | 
 |     "system_property.h", | 
 |     "unwinding.cc", | 
 |     "unwinding.h", | 
 |     "unwound_messages.h", | 
 |   ] | 
 | } | 
 |  | 
 | source_set("client") { | 
 |   deps = [ | 
 |     ":ring_buffer", | 
 |     ":scoped_spinlock", | 
 |     ":wire_protocol", | 
 |     "../../../gn:default_deps", | 
 |     "../../base", | 
 |     "../../base:unix_socket", | 
 |   ] | 
 |   public_deps = [ "../../../gn:libunwindstack" ] | 
 |   sources = [ | 
 |     "client.cc", | 
 |     "client.h", | 
 |     "sampler.cc", | 
 |     "sampler.h", | 
 |   ] | 
 | } | 
 |  | 
 | perfetto_unittest_source_set("unittests") { | 
 |   testonly = true | 
 |   deps = [ | 
 |     ":client", | 
 |     ":daemon", | 
 |     ":ring_buffer", | 
 |     ":wire_protocol", | 
 |     "../../../gn:default_deps", | 
 |     "../../../gn:gtest_and_gmock", | 
 |     "../../../gn:libunwindstack", | 
 |     "../../base", | 
 |     "../../base:test_support", | 
 |     "../../tracing/core", | 
 |     "../common:proc_utils", | 
 |     "../common:unwind_support", | 
 |   ] | 
 |   sources = [ | 
 |     "bookkeeping_unittest.cc", | 
 |     "client_unittest.cc", | 
 |     "heapprofd_producer_unittest.cc", | 
 |     "parse_smaps_unittest.cc", | 
 |     "sampler_unittest.cc", | 
 |     "system_property_unittest.cc", | 
 |     "unwinding_unittest.cc", | 
 |     "wire_protocol_unittest.cc", | 
 |   ] | 
 |  | 
 |   # Do not build with Android to avoid applying PERFETTO_ANDROID_ASYNC_SAFE_LOG | 
 |   # to the whole perfetto_unittests target. | 
 |   if (!perfetto_build_with_android) { | 
 |     sources += [ "client_api_unittest.cc" ] | 
 |     deps += [ ":client_api" ] | 
 |   } | 
 | } | 
 |  | 
 | source_set("end_to_end_tests") { | 
 |   testonly = true | 
 |   deps = [ | 
 |     ":client", | 
 |     ":daemon", | 
 |     ":wire_protocol", | 
 |     "../../../gn:default_deps", | 
 |     "../../../gn:gtest_and_gmock", | 
 |     "../../../gn:libunwindstack", | 
 |     "../../../protos/perfetto/config/profiling:cpp", | 
 |     "../../../protos/perfetto/trace/interned_data:cpp", | 
 |     "../../../protos/perfetto/trace/profiling:cpp", | 
 |     "../../../test:test_helper", | 
 |     "../../base", | 
 |     "../../base:test_support", | 
 |     "../../trace_processor:lib", | 
 |   ] | 
 |   sources = [ "heapprofd_end_to_end_test.cc" ] | 
 |   if (perfetto_build_with_android) { | 
 |     deps += [ ":heapprofd_client_api" ] | 
 |   } else { | 
 |     deps += [ ":heapprofd_standalone_client" ] | 
 |   } | 
 | } | 
 |  | 
 | perfetto_fuzzer_test("unwinding_fuzzer") { | 
 |   testonly = true | 
 |   sources = [ "unwinding_fuzzer.cc" ] | 
 |   deps = [ | 
 |     ":daemon", | 
 |     ":ring_buffer", | 
 |     ":wire_protocol", | 
 |     "../../../gn:default_deps", | 
 |     "../../base", | 
 |     "../../tracing/core", | 
 |     "../common:unwind_support", | 
 |   ] | 
 | } | 
 |  | 
 | perfetto_fuzzer_test("shared_ring_buffer_fuzzer") { | 
 |   testonly = true | 
 |   sources = [ "shared_ring_buffer_fuzzer.cc" ] | 
 |   deps = [ | 
 |     ":ring_buffer", | 
 |     "../../../gn:default_deps", | 
 |     "../../base", | 
 |   ] | 
 | } | 
 |  | 
 | perfetto_fuzzer_test("shared_ring_buffer_write_fuzzer") { | 
 |   testonly = true | 
 |   sources = [ "shared_ring_buffer_write_fuzzer.cc" ] | 
 |   deps = [ | 
 |     ":ring_buffer", | 
 |     "../../../gn:default_deps", | 
 |     "../../base", | 
 |   ] | 
 | } | 
 |  | 
 | if (enable_perfetto_benchmarks) { | 
 |   source_set("benchmarks") { | 
 |     testonly = true | 
 |     deps = [ | 
 |       ":client", | 
 |       ":client_api", | 
 |       "../../../gn:benchmark", | 
 |       "../../../gn:default_deps", | 
 |       "../../base", | 
 |       "../../base:test_support", | 
 |     ] | 
 |     sources = [ "client_api_benchmark.cc" ] | 
 |   } | 
 | } |