Major clean up build files, use flags-per-feature.

These days we support an incredible number of build configurations:
- standalone (GN)
- in chromium (GN)
- in v8 (GN)
- in Fuchsia (GN)
- in Android (soong)
- in Google3
- amalgamated SDK


For each config we want to pick only some components of the
codebase. So far we've been carefully using intersections of
platform flags (e.g. build_standalone && !build_with_android)
but that has become unmaintainable.
This CL mainly introduces one flag per feature. Benefit:
1. All feature flags live in one place (perfetto.gni) and are
   easy to reason about.
2. All the GN conditions depend on these feature flags.

Test: manually rolled in chromium and v8 and looked
      at diff of .ninja files.
Bug: 132678367
Bug: 140126865
Change-Id: I36c4653f25751654c04ab257bdb7a0756269a813
diff --git a/Android.bp b/Android.bp
index 5d550cf..d9972ad 100644
--- a/Android.bp
+++ b/Android.bp
@@ -48,7 +48,7 @@
   ],
 }
 
-// GN target: //:heapprofd
+// GN target: //src/profiling/memory:heapprofd
 cc_binary {
   name: "heapprofd",
   srcs: [
@@ -220,7 +220,7 @@
   ],
 }
 
-// GN target: //:heapprofd_client
+// GN target: //src/profiling/memory:heapprofd_client
 cc_library_shared {
   name: "heapprofd_client",
   srcs: [
@@ -464,7 +464,7 @@
   ],
 }
 
-// GN target: //:libperfetto_android_internal
+// GN target: //src/android_internal:libperfetto_android_internal
 cc_library_shared {
   name: "libperfetto_android_internal",
   srcs: [
@@ -708,7 +708,7 @@
   ],
 }
 
-// GN target: //:perfetto
+// GN target: //src/perfetto_cmd:perfetto
 cc_binary {
   name: "perfetto",
   srcs: [
@@ -4131,7 +4131,7 @@
   ],
 }
 
-// GN target: //:perfetto_trace_protos
+// GN target: //protos/perfetto/trace:perfetto_trace_protos
 cc_library_static {
   name: "perfetto_trace_protos",
   srcs: [
@@ -4254,6 +4254,8 @@
     ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
     ":perfetto_protos_perfetto_config_zero_gen",
     ":perfetto_protos_perfetto_ipc_ipc_gen",
+    ":perfetto_protos_perfetto_metrics_android_zero_gen",
+    ":perfetto_protos_perfetto_metrics_zero_gen",
     ":perfetto_protos_perfetto_trace_android_lite_gen",
     ":perfetto_protos_perfetto_trace_android_zero_gen",
     ":perfetto_protos_perfetto_trace_chrome_lite_gen",
@@ -4274,6 +4276,7 @@
     ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
     ":perfetto_protos_perfetto_trace_power_lite_gen",
     ":perfetto_protos_perfetto_trace_power_zero_gen",
+    ":perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen",
     ":perfetto_protos_perfetto_trace_profiling_lite_gen",
     ":perfetto_protos_perfetto_trace_profiling_zero_gen",
     ":perfetto_protos_perfetto_trace_ps_lite_gen",
@@ -4392,6 +4395,97 @@
     "src/protozero/scattered_stream_writer_unittest.cc",
     "src/protozero/test/fake_scattered_buffer.cc",
     "src/protozero/test/protozero_conformance_unittest.cc",
+    "src/trace_processor/android_logs_table.cc",
+    "src/trace_processor/args_table.cc",
+    "src/trace_processor/args_table_unittest.cc",
+    "src/trace_processor/args_tracker.cc",
+    "src/trace_processor/clock_tracker.cc",
+    "src/trace_processor/clock_tracker_unittest.cc",
+    "src/trace_processor/counter_definitions_table.cc",
+    "src/trace_processor/counter_values_table.cc",
+    "src/trace_processor/db/bit_vector.cc",
+    "src/trace_processor/db/bit_vector_unittest.cc",
+    "src/trace_processor/db/column.cc",
+    "src/trace_processor/db/row_map.cc",
+    "src/trace_processor/db/row_map_unittest.cc",
+    "src/trace_processor/db/sparse_vector_unittest.cc",
+    "src/trace_processor/db/table.cc",
+    "src/trace_processor/event_tracker.cc",
+    "src/trace_processor/event_tracker_unittest.cc",
+    "src/trace_processor/filtered_row_index.cc",
+    "src/trace_processor/filtered_row_index_unittest.cc",
+    "src/trace_processor/forwarding_trace_parser.cc",
+    "src/trace_processor/forwarding_trace_parser_unittest.cc",
+    "src/trace_processor/ftrace_descriptors.cc",
+    "src/trace_processor/ftrace_utils.cc",
+    "src/trace_processor/ftrace_utils_unittest.cc",
+    "src/trace_processor/fuchsia_provider_view.cc",
+    "src/trace_processor/fuchsia_trace_parser.cc",
+    "src/trace_processor/fuchsia_trace_tokenizer.cc",
+    "src/trace_processor/fuchsia_trace_utils.cc",
+    "src/trace_processor/fuchsia_trace_utils_unittest.cc",
+    "src/trace_processor/graphics_frame_event_parser.cc",
+    "src/trace_processor/gzip_trace_parser.cc",
+    "src/trace_processor/heap_profile_allocation_table.cc",
+    "src/trace_processor/heap_profile_tracker.cc",
+    "src/trace_processor/heap_profile_tracker_unittest.cc",
+    "src/trace_processor/instants_table.cc",
+    "src/trace_processor/metadata_table.cc",
+    "src/trace_processor/metadata_table_unittest.cc",
+    "src/trace_processor/metrics/descriptors.cc",
+    "src/trace_processor/metrics/metrics.cc",
+    "src/trace_processor/metrics/metrics_unittest.cc",
+    "src/trace_processor/null_term_string_view_unittest.cc",
+    "src/trace_processor/process_table.cc",
+    "src/trace_processor/process_table_unittest.cc",
+    "src/trace_processor/process_tracker.cc",
+    "src/trace_processor/process_tracker_unittest.cc",
+    "src/trace_processor/proto_trace_parser.cc",
+    "src/trace_processor/proto_trace_parser_unittest.cc",
+    "src/trace_processor/proto_trace_tokenizer.cc",
+    "src/trace_processor/raw_table.cc",
+    "src/trace_processor/row_iterators.cc",
+    "src/trace_processor/sched_slice_table.cc",
+    "src/trace_processor/sched_slice_table_unittest.cc",
+    "src/trace_processor/slice_table.cc",
+    "src/trace_processor/slice_tracker.cc",
+    "src/trace_processor/slice_tracker_unittest.cc",
+    "src/trace_processor/span_join_operator_table.cc",
+    "src/trace_processor/span_join_operator_table_unittest.cc",
+    "src/trace_processor/sql_stats_table.cc",
+    "src/trace_processor/sqlite/query_constraints.cc",
+    "src/trace_processor/sqlite/query_constraints_unittest.cc",
+    "src/trace_processor/sqlite/sqlite3_str_split.cc",
+    "src/trace_processor/sqlite/sqlite3_str_split_unittest.cc",
+    "src/trace_processor/sqlite/sqlite_table.cc",
+    "src/trace_processor/stack_profile_callsite_table.cc",
+    "src/trace_processor/stack_profile_frame_table.cc",
+    "src/trace_processor/stack_profile_mapping_table.cc",
+    "src/trace_processor/stack_profile_tracker.cc",
+    "src/trace_processor/stats_table.cc",
+    "src/trace_processor/storage_columns.cc",
+    "src/trace_processor/storage_schema.cc",
+    "src/trace_processor/storage_table.cc",
+    "src/trace_processor/string_pool.cc",
+    "src/trace_processor/string_pool_unittest.cc",
+    "src/trace_processor/syscall_tracker.cc",
+    "src/trace_processor/syscall_tracker_unittest.cc",
+    "src/trace_processor/systrace_parser.cc",
+    "src/trace_processor/systrace_parser_unittest.cc",
+    "src/trace_processor/systrace_trace_parser.cc",
+    "src/trace_processor/tables/macros_unittest.cc",
+    "src/trace_processor/thread_table.cc",
+    "src/trace_processor/thread_table_unittest.cc",
+    "src/trace_processor/trace_processor.cc",
+    "src/trace_processor/trace_processor_context.cc",
+    "src/trace_processor/trace_processor_impl.cc",
+    "src/trace_processor/trace_sorter.cc",
+    "src/trace_processor/trace_sorter_unittest.cc",
+    "src/trace_processor/trace_storage.cc",
+    "src/trace_processor/track_table.cc",
+    "src/trace_processor/virtual_destructors.cc",
+    "src/trace_processor/virtual_track_tracker.cc",
+    "src/trace_processor/window_operator_table.cc",
     "src/traced/probes/android_log/android_log_data_source.cc",
     "src/traced/probes/android_log/android_log_data_source_unittest.cc",
     "src/traced/probes/filesystem/file_scanner.cc",
@@ -4509,6 +4603,7 @@
     "perfetto_src_tracing_ipc",
   ],
   generated_headers: [
+    "gen_merged_sql_metrics",
     "perfetto_protos_perfetto_common_lite_gen_headers",
     "perfetto_protos_perfetto_common_zero_gen_headers",
     "perfetto_protos_perfetto_config_android_lite_gen_headers",
@@ -4530,6 +4625,8 @@
     "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
     "perfetto_protos_perfetto_config_zero_gen_headers",
     "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+    "perfetto_protos_perfetto_metrics_android_zero_gen_headers",
+    "perfetto_protos_perfetto_metrics_zero_gen_headers",
     "perfetto_protos_perfetto_trace_android_lite_gen_headers",
     "perfetto_protos_perfetto_trace_android_zero_gen_headers",
     "perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
@@ -4550,6 +4647,7 @@
     "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
     "perfetto_protos_perfetto_trace_power_lite_gen_headers",
     "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen_headers",
     "perfetto_protos_perfetto_trace_profiling_lite_gen_headers",
     "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
     "perfetto_protos_perfetto_trace_ps_lite_gen_headers",
@@ -4575,9 +4673,24 @@
     "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
     "-DHAVE_HIDDEN",
   ],
+  target: {
+    android: {
+      shared_libs: [
+        "libandroidicu",
+        "liblog",
+        "libsqlite",
+        "libutils",
+      ],
+    },
+    host: {
+      static_libs: [
+        "libsqlite",
+      ],
+    },
+  },
 }
 
-// GN target: //:trace_processor_shell
+// GN target: //src/trace_processor:trace_processor_shell
 cc_binary {
   name: "trace_processor_shell",
   srcs: [
@@ -4756,7 +4869,7 @@
   },
 }
 
-// GN target: //:trace_to_text
+// GN target: //tools/trace_to_text:trace_to_text
 cc_binary_host {
   name: "trace_to_text",
   srcs: [
@@ -4985,7 +5098,7 @@
   ],
 }
 
-// GN target: //:traced
+// GN target: //src/traced/service:traced
 cc_binary {
   name: "traced",
   srcs: [
@@ -5003,7 +5116,7 @@
   ],
 }
 
-// GN target: //:traced_probes
+// GN target: //src/traced/probes:traced_probes
 cc_binary {
   name: "traced_probes",
   srcs: [
@@ -5022,7 +5135,7 @@
   ],
 }
 
-// GN target: //:trigger_perfetto
+// GN target: //src/perfetto_cmd:trigger_perfetto
 cc_binary {
   name: "trigger_perfetto",
   srcs: [
diff --git a/BUILD b/BUILD
index 8417987..ebc1851 100644
--- a/BUILD
+++ b/BUILD
@@ -55,85 +55,9 @@
     ],
 )
 
-# GN target: //src/protozero:libprotozero
-cc_library(
-    name = "libprotozero",
-    srcs = [
-        "src/protozero/message.cc",
-        "src/protozero/message_handle.cc",
-        "src/protozero/proto_decoder.cc",
-        "src/protozero/scattered_heap_buffer.cc",
-        "src/protozero/scattered_stream_null_delegate.cc",
-        "src/protozero/scattered_stream_writer.cc",
-    ],
-    hdrs = [
-        "include/perfetto/base/build_config.h",
-        "include/perfetto/base/compiler.h",
-        "include/perfetto/base/copyable_ptr.h",
-        "include/perfetto/base/export.h",
-        "include/perfetto/base/logging.h",
-        "include/perfetto/base/task_runner.h",
-        "include/perfetto/base/time.h",
-        "include/perfetto/ext/base/circular_queue.h",
-        "include/perfetto/ext/base/container_annotations.h",
-        "include/perfetto/ext/base/event_fd.h",
-        "include/perfetto/ext/base/file_utils.h",
-        "include/perfetto/ext/base/hash.h",
-        "include/perfetto/ext/base/lookup_set.h",
-        "include/perfetto/ext/base/metatrace.h",
-        "include/perfetto/ext/base/metatrace_events.h",
-        "include/perfetto/ext/base/no_destructor.h",
-        "include/perfetto/ext/base/optional.h",
-        "include/perfetto/ext/base/paged_memory.h",
-        "include/perfetto/ext/base/pipe.h",
-        "include/perfetto/ext/base/proc_utils.h",
-        "include/perfetto/ext/base/scoped_file.h",
-        "include/perfetto/ext/base/small_set.h",
-        "include/perfetto/ext/base/string_splitter.h",
-        "include/perfetto/ext/base/string_utils.h",
-        "include/perfetto/ext/base/string_view.h",
-        "include/perfetto/ext/base/string_writer.h",
-        "include/perfetto/ext/base/temp_file.h",
-        "include/perfetto/ext/base/thread_annotations.h",
-        "include/perfetto/ext/base/thread_checker.h",
-        "include/perfetto/ext/base/thread_task_runner.h",
-        "include/perfetto/ext/base/thread_utils.h",
-        "include/perfetto/ext/base/unix_socket.h",
-        "include/perfetto/ext/base/unix_task_runner.h",
-        "include/perfetto/ext/base/utils.h",
-        "include/perfetto/ext/base/uuid.h",
-        "include/perfetto/ext/base/waitable_event.h",
-        "include/perfetto/ext/base/watchdog.h",
-        "include/perfetto/ext/base/watchdog_noop.h",
-        "include/perfetto/ext/base/watchdog_posix.h",
-        "include/perfetto/ext/base/weak_ptr.h",
-        "include/perfetto/protozero/contiguous_memory_range.h",
-        "include/perfetto/protozero/field.h",
-        "include/perfetto/protozero/message.h",
-        "include/perfetto/protozero/message_handle.h",
-        "include/perfetto/protozero/proto_decoder.h",
-        "include/perfetto/protozero/proto_utils.h",
-        "include/perfetto/protozero/scattered_heap_buffer.h",
-        "include/perfetto/protozero/scattered_stream_null_delegate.h",
-        "include/perfetto/protozero/scattered_stream_writer.h",
-    ],
-)
-
-# GN target: //src/protozero/protoc_plugin:protozero_plugin
-cc_binary(
-    name = "src_protozero_protoc_plugin_protozero_plugin",
-    srcs = [
-        "src/protozero/protoc_plugin/protozero_plugin.cc",
-    ],
-    deps = [
-        "//third_party/protobuf:libprotoc_legacy",
-        "//third_party/protobuf:protobuf_legacy",
-    ],
-)
-
 # GN target: //tools/trace_to_text:libpprofbuilder
 cc_library(
-    name = "tools_trace_to_text_libpprofbuilder",
+    name = "libpprofbuilder",
     srcs = [
         "src/base/event_fd.cc",
         "src/base/file_utils.cc",
@@ -274,6 +198,82 @@
     ],
 )
 
+# GN target: //src/protozero:libprotozero
+cc_library(
+    name = "libprotozero",
+    srcs = [
+        "src/protozero/message.cc",
+        "src/protozero/message_handle.cc",
+        "src/protozero/proto_decoder.cc",
+        "src/protozero/scattered_heap_buffer.cc",
+        "src/protozero/scattered_stream_null_delegate.cc",
+        "src/protozero/scattered_stream_writer.cc",
+    ],
+    hdrs = [
+        "include/perfetto/base/build_config.h",
+        "include/perfetto/base/compiler.h",
+        "include/perfetto/base/copyable_ptr.h",
+        "include/perfetto/base/export.h",
+        "include/perfetto/base/logging.h",
+        "include/perfetto/base/task_runner.h",
+        "include/perfetto/base/time.h",
+        "include/perfetto/ext/base/circular_queue.h",
+        "include/perfetto/ext/base/container_annotations.h",
+        "include/perfetto/ext/base/event_fd.h",
+        "include/perfetto/ext/base/file_utils.h",
+        "include/perfetto/ext/base/hash.h",
+        "include/perfetto/ext/base/lookup_set.h",
+        "include/perfetto/ext/base/metatrace.h",
+        "include/perfetto/ext/base/metatrace_events.h",
+        "include/perfetto/ext/base/no_destructor.h",
+        "include/perfetto/ext/base/optional.h",
+        "include/perfetto/ext/base/paged_memory.h",
+        "include/perfetto/ext/base/pipe.h",
+        "include/perfetto/ext/base/proc_utils.h",
+        "include/perfetto/ext/base/scoped_file.h",
+        "include/perfetto/ext/base/small_set.h",
+        "include/perfetto/ext/base/string_splitter.h",
+        "include/perfetto/ext/base/string_utils.h",
+        "include/perfetto/ext/base/string_view.h",
+        "include/perfetto/ext/base/string_writer.h",
+        "include/perfetto/ext/base/temp_file.h",
+        "include/perfetto/ext/base/thread_annotations.h",
+        "include/perfetto/ext/base/thread_checker.h",
+        "include/perfetto/ext/base/thread_task_runner.h",
+        "include/perfetto/ext/base/thread_utils.h",
+        "include/perfetto/ext/base/unix_socket.h",
+        "include/perfetto/ext/base/unix_task_runner.h",
+        "include/perfetto/ext/base/utils.h",
+        "include/perfetto/ext/base/uuid.h",
+        "include/perfetto/ext/base/waitable_event.h",
+        "include/perfetto/ext/base/watchdog.h",
+        "include/perfetto/ext/base/watchdog_noop.h",
+        "include/perfetto/ext/base/watchdog_posix.h",
+        "include/perfetto/ext/base/weak_ptr.h",
+        "include/perfetto/protozero/contiguous_memory_range.h",
+        "include/perfetto/protozero/field.h",
+        "include/perfetto/protozero/message.h",
+        "include/perfetto/protozero/message_handle.h",
+        "include/perfetto/protozero/proto_decoder.h",
+        "include/perfetto/protozero/proto_utils.h",
+        "include/perfetto/protozero/scattered_heap_buffer.h",
+        "include/perfetto/protozero/scattered_stream_null_delegate.h",
+        "include/perfetto/protozero/scattered_stream_writer.h",
+    ],
+)
+
+# GN target: //src/protozero/protoc_plugin:protozero_plugin
+cc_binary(
+    name = "src_protozero_protoc_plugin_protozero_plugin",
+    srcs = [
+        "src/protozero/protoc_plugin/protozero_plugin.cc",
+    ],
+    deps = [
+        "//third_party/protobuf:libprotoc_legacy",
+        "//third_party/protobuf:protobuf_legacy",
+    ],
+)
+
 # GN target: //src/trace_processor:trace_processor
 cc_library(
     name = "trace_processor",
@@ -395,7 +395,6 @@
         "src/trace_processor/sqlite/query_constraints.cc",
         "src/trace_processor/sqlite/query_constraints.h",
         "src/trace_processor/sqlite/scoped_db.h",
-        "src/trace_processor/sqlite/sqlite.h",
         "src/trace_processor/sqlite/sqlite3_str_split.cc",
         "src/trace_processor/sqlite/sqlite3_str_split.h",
         "src/trace_processor/sqlite/sqlite_table.cc",
@@ -545,7 +544,7 @@
     ],
 )
 
-# GN target: //:trace_processor_shell
+# GN target: //src/trace_processor:trace_processor_shell
 cc_binary(
     name = "trace_processor_shell",
     srcs = [
@@ -719,7 +718,6 @@
         "src/trace_processor/sqlite/query_constraints.cc",
         "src/trace_processor/sqlite/query_constraints.h",
         "src/trace_processor/sqlite/scoped_db.h",
-        "src/trace_processor/sqlite/sqlite.h",
         "src/trace_processor/sqlite/sqlite3_str_split.cc",
         "src/trace_processor/sqlite/sqlite3_str_split.h",
         "src/trace_processor/sqlite/sqlite_table.cc",
@@ -783,7 +781,6 @@
         "//third_party/perfetto:gen_merged_sql_metrics",
         "//third_party/perfetto/google:jsoncpp",
         "//third_party/perfetto/google:linenoise",
-        "//third_party/perfetto/google:perfetto_version",
         "//third_party/perfetto/protos:common_zero_cc_proto",
         "//third_party/perfetto/protos:config_android_zero_cc_proto",
         "//third_party/perfetto/protos:config_ftrace_zero_cc_proto",
@@ -819,7 +816,7 @@
     ],
 )
 
-# GN target: //tools/trace_to_text:trace_to_text_host
+# GN target: //tools/trace_to_text:trace_to_text
 cc_binary(
     name = "trace_to_text",
     srcs = [
@@ -993,7 +990,6 @@
         "src/trace_processor/sqlite/query_constraints.cc",
         "src/trace_processor/sqlite/query_constraints.h",
         "src/trace_processor/sqlite/scoped_db.h",
-        "src/trace_processor/sqlite/sqlite.h",
         "src/trace_processor/sqlite/sqlite3_str_split.cc",
         "src/trace_processor/sqlite/sqlite3_str_split.h",
         "src/trace_processor/sqlite/sqlite_table.cc",
@@ -1078,7 +1074,6 @@
     deps = [
         "//third_party/perfetto:gen_merged_sql_metrics",
         "//third_party/perfetto/google:jsoncpp",
-        "//third_party/perfetto/google:perfetto_version",
         "//third_party/perfetto/protos:common_cc_proto",
         "//third_party/perfetto/protos:common_zero_cc_proto",
         "//third_party/perfetto/protos:config_android_cc_proto",
diff --git a/BUILD.gn b/BUILD.gn
index df6da5c..61d6d9d 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -15,106 +15,130 @@
 import("gn/perfetto.gni")
 import("gn/test.gni")
 
-if (perfetto_root_path == "//") {
-  import("//gn/standalone/android.gni")
-  import("//gn/standalone/sanitizers/vars.gni")
-} else {
-  import("//build/config/android/config.gni")
-  import("//build/config/sanitizers/sanitizers.gni")
+# +----------------------------------------------------------------------------+
+# | "all" targets definition: defines targets reachable by the various configs |
+# +----------------------------------------------------------------------------+
+# There is a subtletly here related with chromium and other GN embedders.
+# When adding a dependency some_dir/:target_name, some_dir/BUILD.gn is
+# "discovered". As a side effect any *other* target defined in some_dir/BUILD.gn
+# (and its transitive dependencies) becomes implicitly part of the "default"
+# target, the one invoked running ninja -C out/xxx without further args.
+# Because of this, care must be taken to wrap dependencies to targets in other
+# build files with if (enable_xxx) flags. Accidentally including a harmless
+# target that happens to be defined in the same BUILD.gn that contains targets
+# incompatible with the chromium build will cause build/roll failures.
+
+all_targets = [ "protos/perfetto/trace:perfetto_trace_protos" ]
+
+if (enable_perfetto_platform_services) {
+  all_targets += [
+    "src/perfetto_cmd:perfetto",
+    "src/perfetto_cmd:trigger_perfetto",
+    "src/traced/service:traced",
+    "src/traced/probes:traced_probes",
+  ]
 }
 
-declare_args() {
-  # Only for local development. When true the binaries (perfetto, traced, ...)
-  # are monolithic and don't use a common shared library. This is mainly to
-  # avoid LD_LIBRARY_PATH dances when testing locally.
-  monolithic_binaries = false
-
-  # libunwindstack requires API level 26 or newer.
-  should_build_heapprofd =
-      (perfetto_build_standalone || perfetto_build_with_android) && is_clang &&
-      (is_linux || is_android) &&
-      (!is_android || android_api_level >= 26 || perfetto_build_with_android)
+if (enable_perfetto_trace_processor) {
+  all_targets += [ "src/trace_processor:trace_processor_shell" ]
 }
-assert(!monolithic_binaries || !perfetto_build_with_android)
+
+if (enable_perfetto_heapprofd) {
+  all_targets += [ "src/profiling/memory:heapprofd" ]
+  if (perfetto_build_with_android) {
+    all_targets += [ "src/profiling/memory:heapprofd_client" ]
+  }
+}
+
+if (perfetto_build_with_android) {
+  all_targets += [ "src/android_internal/:libperfetto_android_internal" ]
+}
+
+if (enable_perfetto_tools) {
+  all_targets += [ "tools" ]
+}
+
+if (enable_perfetto_unittests) {
+  import("gn/perfetto_unittests.gni")
+  test("perfetto_unittests") {
+    deps = perfetto_unittests_targets
+  }
+  all_targets += [ ":perfetto_unittests" ]
+}
+
+if (enable_perfetto_integration_tests) {
+  import("gn/perfetto_integrationtests.gni")
+  test("perfetto_integrationtests") {
+    deps = perfetto_integrationtests_targets
+  }
+  all_targets += [
+    ":perfetto_integrationtests",
+    "test:client_api_example",
+  ]
+}
+
+if (enable_perfetto_benchmarks) {
+  import("gn/perfetto_benchmarks.gni")
+  executable("perfetto_benchmarks") {
+    testonly = true
+    deps = perfetto_benchmarks_targets
+  }
+  all_targets += [ ":perfetto_benchmarks" ]
+}
+
+if (enable_perfetto_fuzzers) {
+  import("gn/perfetto_fuzzers.gni")
+  group("fuzzers") {
+    testonly = true
+    deps = perfetto_fuzzers_targets
+  }
+  all_targets += [ ":fuzzers" ]
+}
+
+# Less interesting stuff that makes sense only in the standalone build, mainly
+# compile-time checks for the CI.
+if (perfetto_build_standalone) {
+  all_targets += [
+    "src/tracing:consumer_api_test",
+    "test/configs",
+
+    # For syntax-checking the proto.
+    "protos/perfetto/config:merged_config",
+    "protos/perfetto/trace:merged_trace",  # For syntax-checking the proto.
+
+    # The diff testing framework depends on these descriptors.
+    "protos/perfetto/metrics:descriptor",
+    "protos/perfetto/trace:descriptor",
+
+    # Used in the when updating the ftrace protos
+    "protos/perfetto/trace/ftrace:descriptor",
+  ]
+}
 
 group("all") {
   testonly = true  # allow to build also test targets
-  deps = [
-    ":perfetto_unittests",
-    "src/protozero/protoc_plugin:protozero_plugin($host_toolchain)",
-  ]
-  if (enable_perfetto_trace_processor) {
-    deps += [ ":trace_processor_shell" ]
-  }
-  if (perfetto_build_standalone || perfetto_build_with_android) {
-    deps += [
-      ":perfetto",
-      ":perfetto_integrationtests",
-      ":traced",
-      ":traced_probes",
-      ":trigger_perfetto",
-      "protos/perfetto/config:merged_config",  # For syntax-checking the proto.
-      "protos/perfetto/trace:merged_trace",  # For syntax-checking the proto.
-      "src/ipc/protoc_plugin:ipc_plugin($host_toolchain)",
-      "src/tracing:client_api",
-      "test:client_api_example",
-      "tools:protoc_helper",
-    ]
-    if (perfetto_build_standalone) {
-      deps += [
-        ":perfetto_benchmarks",
-        "src/profiling/memory:ring_buffer",
-        "src/tracing:consumer_api_test",
-        "test/configs",
-        "tools/ftrace_proto_gen:ftrace_proto_gen",
-        "tools/proto_to_cpp",
-        "tools/protoprofile",
-        "tools/trace_to_text",
-        "tools/trace_to_text:trace_to_text_lite_host($host_toolchain)",
-
-        # The diff testing framework depends on these descriptors.
-        "protos/perfetto/metrics:descriptor",
-        "protos/perfetto/trace:descriptor",
-
-        # Used in the when updating the ftrace protos
-        "protos/perfetto/trace/ftrace:descriptor",
-      ]
-      if (is_linux || is_android) {
-        deps += [ "tools/busy_threads" ]
-        deps += [ "tools/cpu_utilization" ]
-        deps += [ "tools/dump_ftrace_stats" ]
-        deps += [ "tools/skippy" ]
-      }
-      if (is_fuzzer) {
-        deps += [ ":fuzzers" ]
-      }
-    }
-  }
+  deps = all_targets
 }
 
-# TODO(primiano): temporary workaround to:
-# 1) Prevent that the UI gets build automatically when doing ninja -C out/xx .
-# 2) Avoid breaking the chrome build, that right now depends on "all".
+# This target is used when running ninja without any argument (by default would
+# build all reachable targets). This is mainly used to prevent the UI being
+# built when running ninja -C out/xxx.
+# This has effect only in standalone builds, no effect on chromium builds.
+# Chromium's "all" target depends on our "all" target above. However chromium's
+# "default" target depends on any target that we cause to be discovered by
+# depending on other GN files.
 group("default") {
-  testonly = true  # allow to build also test targets
+  testonly = true
   deps = [
     ":all",
   ]
 }
 
-# The trace processor shell executable. An interactive shell that allows to
-# make queries on the trace using the terminal.
-if (enable_perfetto_trace_processor) {
-  executable("trace_processor_shell") {
-    deps = [
-      "gn:default_deps",
-      "src/trace_processor:trace_processor_shell",
-    ]
-    testonly = true  # We need this for proto full.
-  }
-}
+# +----------------------------------------------------------------------------+
+# | Other definitions: root targets that don't belong to any other subdirectory|
+# +----------------------------------------------------------------------------+
 
-if (perfetto_build_standalone) {
+if (enable_perfetto_ui) {
   group("ui") {
     deps = [
       "ui",
@@ -122,60 +146,18 @@
   }
 }
 
-test("perfetto_unittests") {
-  deps = [
-    "gn:default_deps",
-    "gn:gtest_main",
-    "src/base:unittests",
-    "src/protozero:unittests",
-    "src/tracing:unittests",
-  ]
-
-  if (perfetto_build_standalone || perfetto_build_with_android) {
-    deps += [
-      "src/ipc:unittests",
-      "src/perfetto_cmd:unittests",
-      "src/profiling/memory:ring_buffer_unittests",
-      "src/traced/probes:unittests",
-      "src/traced/probes/filesystem:unittests",
-      "src/traced/probes/ftrace:unittests",
-      "src/traced/service:unittests",
-      "tools/ftrace_proto_gen:unittests",
-      "tools/sanitizers_unittests",
-    ]
-  }
-  if (should_build_heapprofd) {
-    # Restrict to clang, as libunwindstack and its dependencies is never
-    # built using GCC in the Android tree.
-    deps += [ "src/profiling/memory:unittests" ]
-  }
-  if (perfetto_build_standalone && !is_android) {
-    deps += [
-      "src/trace_processor:unittests",
-      "src/trace_processor/metrics:unittests",
-    ]
-  }
-}
-
-if (perfetto_build_standalone || perfetto_build_with_android) {
-  test("perfetto_integrationtests") {
-    deps = [
-      "gn:default_deps",
-      "gn:gtest_main",
-      "src/traced/probes/ftrace:integrationtests",
-      "src/tracing:client_api_integrationtests",
-      "test:end_to_end_integrationtests",
-    ]
-    if (perfetto_build_standalone && !is_android) {
-      deps += [ "src/trace_processor:integrationtests" ]
-    }
-
-    # TODO(fmayer): Fix in process daemons.
-    if (should_build_heapprofd) {
-      deps += [ "src/profiling/memory:end_to_end_tests" ]
-    }
-  }
-
+# In Android builds, we build the code of traced and traced_probes in one shared
+# library that exposes one xxx_main() for each. The executables themselves are
+# tiny shells that just invoke their own entry point into the library.
+# This is done merely for saving binary size, because the three binaries happen
+# to share a lot of code.
+# When setting monolithic_binaries=true (only supported in standalone builds)
+# it builds more conventional executables, where each binary has the full
+# implementation and no shared library dependency. This is to make dev cycles
+# on Android faster, avoiding all the LD_LIBRARY_PATH boilerplate.
+# libperfetto.so is also used for stuff that is exposed to the rest of the
+# Android tree.
+if (enable_perfetto_platform_services) {
   if (monolithic_binaries) {
     libperfetto_target_type = "source_set"
   } else {
@@ -190,88 +172,7 @@
       "src/tracing:consumer_api_deprecated",
     ]
   }
-
-  # The unprivileged trace daemon that listens for Producer and Consumer
-  # connections, handles the coordination of the tracing sessions and owns the
-  # log buffers.
-  executable("traced") {
-    deps = [
-      ":libperfetto",
-      "gn:default_deps",
-      "include/perfetto/ext/traced",
-    ]
-    sources = [
-      "src/traced/service/main.cc",
-    ]
-  }
-
-  # The unprivileged daemon that is allowed to access tracefs (for ftrace).
-  # Registers as a Producer on the traced daemon.
-  executable("traced_probes") {
-    deps = [
-      ":libperfetto",
-      "gn:default_deps",
-      "include/perfetto/ext/traced",
-    ]
-    sources = [
-      "src/traced/probes/main.cc",
-    ]
-  }
-
-  # The command line client for Perfetto. Allows to configure / start / stop
-  # tracing, acting as a Consumer.
-  executable("perfetto") {
-    deps = [
-      "gn:default_deps",
-      "src/perfetto_cmd",
-    ]
-    sources = [
-      "src/perfetto_cmd/main.cc",
-    ]
-  }
-
-  # Tool to finalize long running traces.
-  # This connects to traced as a producer and sends the triggers passed on the
-  # commandline. This is a subset of what the perfetto binary can do but we
-  # need a separate binary for programs that cannot (for good reason) use the
-  # additional functionality (for example starting traces via consumer socket)
-  # due to selinux rules.
-  executable("trigger_perfetto") {
-    deps = [
-      "gn:default_deps",
-      "src/perfetto_cmd:trigger_perfetto_cmd",
-    ]
-    sources = [
-      "src/perfetto_cmd/trigger_perfetto_main.cc",
-    ]
-  }
-
-  if (perfetto_build_with_android) {
-    executable("trace_to_text") {
-      testonly = true
-      deps = [
-        "gn:default_deps",
-        "tools/trace_to_text:full",
-      ]
-    }
-
-    # This target exports perfetto trace protos in the Android build system,
-    # allowing both host and device targets to implement custom parsers based on
-    # our protos.
-    static_library("perfetto_trace_protos") {
-      deps = [
-        "protos/perfetto/trace:lite",
-      ]
-    }
-
-    shared_library("libperfetto_android_internal") {
-      deps = [
-        "gn:default_deps",
-        "src/android_internal",
-      ]
-    }
-  }  # if (perfetto_build_with_android)
-}  # if (perfetto_build_standalone || perfetto_build_with_android)
+}
 
 if (!build_with_chromium) {
   # Client library target.
@@ -292,9 +193,10 @@
   }
 }
 
-# TODO(primiano): there seem to be two "libperfetto" targets defined within this
-# BUILD.gn file. Rationalize them with eseckler@. For now seems this one is only
-# used from chromium and the other one only from the Android tree.
+# TODO(primiano): there seem to be two "libperfetto" and one
+# "libperfetto_client_experimental" targets defined within this BUILD.gn file.
+# Rationalize them with eseckler@. For now seems this one is only used from
+# chromium and the other one only from the Android tree.
 if (build_with_chromium) {
   component("libperfetto") {
     public_configs = [ "gn:public_config" ]
@@ -324,79 +226,3 @@
     ]
   }
 }
-
-if (perfetto_build_standalone) {
-  executable("perfetto_benchmarks") {
-    testonly = true
-    deps = [
-      "gn:default_deps",
-      "src/traced/probes/ftrace:benchmarks",
-      "test:benchmark_main",
-      "test:end_to_end_benchmarks",
-    ]
-  }
-
-  group("fuzzers") {
-    testonly = true
-    deps = [
-      "src/ipc:buffered_frame_deserializer_fuzzer",
-      "src/profiling/memory:shared_ring_buffer_fuzzer",
-      "src/profiling/memory:shared_ring_buffer_write_fuzzer",
-      "src/profiling/memory:unwinding_fuzzer",
-      "src/protozero:protozero_decoder_fuzzer",
-      "src/trace_processor:trace_processor_fuzzer",
-      "src/traced/probes/ftrace:cpu_reader_fuzzer",
-      "test:end_to_end_shared_memory_fuzzer",
-      "test:producer_socket_fuzzer",
-    ]
-  }
-}
-
-# WARNING: this builds correctly only when using the generated Android.bp.
-#
-# 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 is deemed acceptable as, at the time of writing, there is no interest in
-# building this library standalone.
-if (perfetto_build_with_android) {
-  # TODO(fmayer): Investigate shared library for common pieces.
-  shared_library("heapprofd_client") {
-    configs -= [ "//gn/standalone:android_liblog" ]
-    cflags = [ "-DPERFETTO_ANDROID_ASYNC_SAFE_LOG" ]
-    deps = [
-      "src/profiling/memory:malloc_hooks",
-    ]
-  }
-}
-
-if (should_build_heapprofd) {
-  executable("heapprofd") {
-    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",
-    ]
-    sources = [
-      "src/profiling/memory/main.cc",
-    ]
-  }
-}
-
-if (perfetto_build_standalone) {
-  executable("idle_alloc") {
-    sources = [
-      "tools/idle_alloc.cc",
-    ]
-  }
-}
diff --git a/buildtools/BUILD.gn b/buildtools/BUILD.gn
index 9687116..4939305 100644
--- a/buildtools/BUILD.gn
+++ b/buildtools/BUILD.gn
@@ -12,8 +12,11 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import("//gn/standalone/libc++/libc++.gni")
 import("../gn/perfetto.gni")
+import("../gn/standalone/libc++/libc++.gni")
+
+# We should never get here in embedder builds.
+assert(perfetto_build_standalone || is_perfetto_build_generator)
 
 # This is to make sure that we don't add accidental dependencies from build
 # files in src/ or include/ to buildtools. All deps (outside of /gn/*) should
diff --git a/gn/BUILD.gn b/gn/BUILD.gn
index 75ddaea..6ac8191 100644
--- a/gn/BUILD.gn
+++ b/gn/BUILD.gn
@@ -27,8 +27,7 @@
 # deal with several build systems.
 # The way this works is the following:
 # - This rule generates a header that contains a bunch of lines like:
-#   #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_BUILD() (0)
-#   #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_EMBEDDER_BUILD() (0)
+#   #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_BUILD()
 # - The generated header is included by base/build_config.h
 # - Source files in the codebase #include base/build_config and use the
 #   pattern #if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
@@ -43,21 +42,22 @@
   }
   perfetto_force_dlog_on = perfetto_force_dlog == "on"
   perfetto_force_dlog_off = perfetto_force_dlog == "off"
-  perfetto_version_gen =
-      perfetto_build_standalone && !is_perfetto_build_generator
 
   response_file_contents = [
     "--flags",  # Keep this marker first.
     "PERFETTO_ANDROID_BUILD=$perfetto_build_with_android",
-    "PERFETTO_EMBEDDER_BUILD=$perfetto_build_with_embedder",
     "PERFETTO_CHROMIUM_BUILD=$build_with_chromium",
     "PERFETTO_STANDALONE_BUILD=$perfetto_build_standalone",
     "PERFETTO_START_DAEMONS=$start_daemons_for_testing",
-    "PERFETTO_IPC=$perfetto_build_with_ipc_layer",
+    "PERFETTO_IPC=$enable_perfetto_ipc",
+    "PERFETTO_WATCHDOG=$enable_perfetto_watchdog",
     "PERFETTO_COMPONENT_BUILD=$perfetto_component_build",
     "PERFETTO_FORCE_DLOG_ON=$perfetto_force_dlog_on",
     "PERFETTO_FORCE_DLOG_OFF=$perfetto_force_dlog_off",
-    "PERFETTO_VERSION_GEN=$perfetto_version_gen",
+    "PERFETTO_VERSION_GEN=$enable_perfetto_version_gen",
+    "PERFETTO_TP_LINENOISE=$enable_perfetto_trace_processor_linenoise",
+    "PERFETTO_TP_JSON=$enable_perfetto_trace_processor_json",
+    "PERFETTO_TP_PERCENTILE=$enable_perfetto_trace_processor_percentile",
   ]
 
   rel_out_path = rebase_path(gen_header_path, "$root_build_dir")
@@ -194,7 +194,7 @@
 
 # The Google C++ Benchmark library.
 # Only avilable in standalone builds.
-if (perfetto_build_standalone) {
+if (enable_perfetto_benchmarks) {
   group("benchmark") {
     testonly = true
     public_deps = [
@@ -213,7 +213,7 @@
   }
 }
 
-if (enable_perfetto_trace_processor) {
+if (enable_perfetto_trace_processor_sqlite) {
   group("sqlite") {
     if (perfetto_root_path == "//") {
       public_deps = [
@@ -223,11 +223,16 @@
       public_deps = [
         "//third_party/sqlite:sqlite",
       ]
+      public_configs = [ ":sqlite_third_party_include_path" ]
     }
   }
 
-  # For now JsonCpp is supported only in standalone and Chrome builds,
-  # not in Android.
+  config("sqlite_third_party_include_path") {
+    include_dirs = [ "//third_party/sqlite" ]
+  }
+}  # if (enable_perfetto_trace_processor_sqlite)
+
+if (enable_perfetto_trace_processor_json) {
   group("jsoncpp") {
     if (perfetto_root_path == "//") {
       public_configs = [ "//buildtools:jsoncpp_config" ]
@@ -240,20 +245,20 @@
       ]
     }
   }
+}
 
+if (enable_perfetto_trace_processor_linenoise) {
   # Used by the trace_processor_shell for REPL history.
   # Only avilable in standalone builds.
   group("linenoise") {
-    if (perfetto_build_standalone && (is_linux || is_android || is_mac)) {
-      public_deps = [
-        "//buildtools:linenoise",
-      ]
-    }
+    public_deps = [
+      "//buildtools:linenoise",
+    ]
   }
-}  # if (enable_perfetto_trace_processor)
+}  # if (enable_perfetto_trace_processor_linenoise)
 
 # Only used by src/profiling in standalone and android builds.
-if (perfetto_build_standalone || perfetto_build_with_android) {
+if (enable_perfetto_heapprofd) {
   group("libunwindstack") {
     public_configs = [ "//buildtools:libunwindstack_config" ]
     public_deps = [
@@ -263,8 +268,7 @@
 }
 
 # Zlib is used both by trace_processor and by perfetto_cmd.
-if (enable_perfetto_trace_processor || perfetto_build_standalone ||
-    perfetto_build_with_android) {
+if (enable_perfetto_trace_processor || enable_perfetto_platform_services) {
   group("zlib") {
     if (perfetto_root_path == "//") {
       public_configs = [ "//buildtools:zlib_config" ]
@@ -281,12 +285,11 @@
 }
 
 # Used by fuzzers.
-if (use_libfuzzer) {
+if (enable_perfetto_fuzzers) {
   group("libfuzzer") {
-    if (perfetto_build_standalone) {
-      public_deps = [
-        "//buildtools:libfuzzer",
-      ]
-    }
+    assert(perfetto_root_path == "//")
+    public_deps = [
+      "//buildtools:libfuzzer",
+    ]
   }
 }
diff --git a/gn/fuzzer.gni b/gn/fuzzer.gni
index ace0356..6a4bc24 100644
--- a/gn/fuzzer.gni
+++ b/gn/fuzzer.gni
@@ -14,7 +14,7 @@
 
 import("perfetto.gni")
 
-if (perfetto_build_standalone) {
+if (perfetto_root_path == "//") {
   import("//gn/standalone/fuzzer.gni")
 } else {
   # TODO: integrate fuzzer support for chromium builds.
diff --git a/gn/perfetto.gni b/gn/perfetto.gni
index b2ca295..0653d07 100644
--- a/gn/perfetto.gni
+++ b/gn/perfetto.gni
@@ -13,6 +13,7 @@
 # limitations under the License.
 
 import("//build_overrides/build.gni")
+import("wasm_vars.gni")
 
 # Summary of our typical build configurations:
 
@@ -51,6 +52,12 @@
 #    perfetto_build_with_android = false
 #    perfetto_build_with_embedder = true
 
+# +----------------------------------------------------------------------------+
+# | Toolchain / environment related configuration                              |
+# +----------------------------------------------------------------------------+
+# This section contains a bunch of variables that are related with the toolchain
+# and the build environment. Only tools/gen_xxx should customize them.
+
 # Note that |build_with_chromium| is a global convention used by several
 # projects, set outside of our control.
 
@@ -59,11 +66,6 @@
   build_with_chromium = false
 }
 
-perfetto_force_dlog_default = ""
-if (build_with_chromium) {
-  perfetto_force_dlog_default = "off"
-}
-
 declare_args() {
   # The Android blueprint file generator set this to true (as well as
   # is_perfetto_build_generator). This is just about being built in the
@@ -79,28 +81,8 @@
   # based on GN (e.g. v8) should NOT set this and instead directly sets
   # perfetto_build_with_embedder=true in their GN files.
   is_perfetto_embedder = false
-
-  # Whether the ftrace producer and the service should be started
-  # by the integration test or assumed to be running.
-  start_daemons_for_testing = true
-
-  # Allow the embedder to use the IPC layer. In turn this allows to use the
-  # system backend in the client library.
-  # tools/gen_amalgamated sets this to true.
-  enable_perfetto_ipc = false
-
-  # Makes the trace processor targets reachable.
-  enable_perfetto_trace_processor = false
-
-  # Whether DLOG should be enabled on debug builds (""), all builds ("on"), or
-  # none ("off"). We disable it by default for embedders to avoid spamming their
-  # console.
-  perfetto_force_dlog = perfetto_force_dlog_default
 }
 
-assert(perfetto_force_dlog == "" || perfetto_force_dlog == "on" ||
-       perfetto_force_dlog == "off")
-
 # This can be overridden by embedders (e.g. v8) in their .gn(i) files. This must
 # be different from the GN args flag (is_perfetto_embedder) because of the way
 # GN works.
@@ -117,33 +99,120 @@
 # can ovverride it in its GN files.
 if (perfetto_build_standalone || is_perfetto_build_generator) {
   perfetto_root_path = "//"
+  import("//gn/standalone/android.gni")  # For android_api_level
+  import("//gn/standalone/sanitizers/vars.gni")  # For is_fuzzer
 } else if (!defined(perfetto_root_path)) {
   perfetto_root_path = "//third_party/perfetto/"
+  import("//build/config/android/config.gni")  # For android_api_level
 }
 
+# Whether the ftrace producer and the service should be started
+# by the integration test or assumed to be running.
 # If we're building in the Android tree, we expect that the testing infra
 # will start the binaries in the system image before the tests are run.
-if (perfetto_build_with_android) {
-  start_daemons_for_testing = false
+# In all other cases (i.e. when true), a temporary in-process instance will be
+# brought up by our own integrationtest harness.
+start_daemons_for_testing = !perfetto_build_with_android
+
+# +----------------------------------------------------------------------------+
+# | Tunable build variables for embedders                                      |
+# +----------------------------------------------------------------------------+
+# The variables in this section allow embedders to enable/disable features
+# at the build-system level. This allows to opt-in into the various services
+# and tools.
+
+perfetto_force_dlog_default = ""
+if (build_with_chromium) {
+  perfetto_force_dlog_default = "off"
 }
 
-# Only perfetto itself (standalone or with android) and chromium should link
-# in the IPC layer.
-#
-# This includes building things that rely on POSIX sockets, this places
-# limitations on the supported operating systems.
-perfetto_build_with_ipc_layer =
-    (is_android || is_linux || is_mac) &&
-    (perfetto_build_standalone || perfetto_build_with_android ||
-     build_with_chromium || enable_perfetto_ipc)
+declare_args() {
+  # Platform-wide tracing executables (traced, traced_probes, perfetto_cmd).
+  enable_perfetto_platform_services =
+      perfetto_build_standalone || perfetto_build_with_android
 
-# Trace processor is enabled only in standalone, chromium and all generator
-# builds.
-enable_perfetto_trace_processor =
-    perfetto_build_standalone || build_with_chromium ||
-    is_perfetto_build_generator
+  # Allow the embedder to use the IPC layer. In turn this allows to use the
+  # system backend in the client library.
+  # This includes building things that rely on POSIX sockets, this places
+  # limitations on the supported operating systems.
+  enable_perfetto_ipc = (is_android || is_linux || is_mac) &&
+                        (perfetto_build_standalone ||
+                         perfetto_build_with_android || build_with_chromium)
 
-# Cross-checks.
+  # Makes the heap profiling daemon target reachable. It works only on Android,
+  # but is built on Linux as well for test/compiler coverage.
+  # On Android, it requires API level 26 due to libunwindstack.
+  enable_perfetto_heapprofd =
+      perfetto_build_with_android ||
+      (perfetto_build_standalone && is_clang &&
+       (is_linux || (is_android && android_api_level >= 26)))
+
+  # The Trace Processor: offline analytical engine to process traces and compute
+  # metrics using a SQL engine.
+  enable_perfetto_trace_processor =
+      perfetto_build_standalone || build_with_chromium ||
+      is_perfetto_build_generator
+
+  # Enables base::Watchdog. Is supported only on Linux-based platforms.
+  enable_perfetto_watchdog =
+      perfetto_build_with_android ||
+      (perfetto_build_standalone && (is_linux || is_android) && !is_wasm)
+
+  # Misc host executable under tools/.
+  enable_perfetto_tools =
+      perfetto_build_standalone || perfetto_build_with_android
+
+  # Allows to build the UI (TypeScript/ HTML / WASM)
+  enable_perfetto_ui = perfetto_build_standalone
+
+  enable_perfetto_unittests = perfetto_build_standalone ||
+                              build_with_chromium || perfetto_build_with_android
+
+  enable_perfetto_integration_tests =
+      perfetto_build_standalone || perfetto_build_with_android
+
+  enable_perfetto_benchmarks = perfetto_build_standalone
+
+  enable_perfetto_fuzzers =
+      perfetto_build_standalone && defined(is_fuzzer) && is_fuzzer
+
+  # Enables the gen_git_revision tool that generates a .h that contains a macro
+  # with the current git revision. Works only in standalone GN checkouts.
+  # If disabled, the version string will be "unknown".
+  enable_perfetto_version_gen =
+      perfetto_build_standalone && !is_perfetto_build_generator
+
+  # Only for local development. When true the binaries (perfetto, traced, ...)
+  # are monolithic and don't use a common shared library. This is mainly to
+  # avoid LD_LIBRARY_PATH dances when testing locally.
+  monolithic_binaries = false
+
+  # Whether DLOG should be enabled on debug builds (""), all builds ("on"), or
+  # none ("off"). We disable it by default for embedders to avoid spamming their
+  # console.
+  perfetto_force_dlog = perfetto_force_dlog_default
+}
+
+declare_args() {
+  enable_perfetto_trace_processor_sqlite = enable_perfetto_trace_processor
+
+  # Enables the optional SQLite percentile module.
+  enable_perfetto_trace_processor_percentile =
+      enable_perfetto_trace_processor && perfetto_build_standalone
+
+  # Enables JSON support in the trace processor.
+  enable_perfetto_trace_processor_json =
+      enable_perfetto_trace_processor && !perfetto_build_with_android
+
+  # Enables the REPL interactive prompt in the trace processor.
+  enable_perfetto_trace_processor_linenoise =
+      perfetto_build_standalone && enable_perfetto_trace_processor &&
+      (is_linux || is_android || is_mac)
+}
+
+# +---------------------------------------------------------------------------+
+# | Cross-checks                                                              |
+# +---------------------------------------------------------------------------+
 
 # Exactly one between build_with_android, build_standalone and
 # build_with_embedder must be true.
@@ -162,8 +231,17 @@
 assert(!perfetto_build_with_android || is_perfetto_build_generator)
 
 # The IPC layer based on UNIX sockets can't be built on Win.
-assert(!perfetto_build_with_ipc_layer || !is_win)
+assert(!enable_perfetto_ipc || !is_win)
 
 # We should never end up in a state where is_perfetto_embedder=true but
 # perfetto_build_with_embedder=false.
 assert(!is_perfetto_embedder || perfetto_build_with_embedder)
+
+# The monolithic binaries is not supported when building in the Android tree.
+assert(!monolithic_binaries || !perfetto_build_with_android)
+
+# Watchdog must be on in Android builds.
+assert(enable_perfetto_watchdog || !perfetto_build_with_android)
+
+assert(perfetto_force_dlog == "" || perfetto_force_dlog == "on" ||
+       perfetto_force_dlog == "off")
diff --git a/gn/perfetto_benchmarks.gni b/gn/perfetto_benchmarks.gni
new file mode 100644
index 0000000..83f780f
--- /dev/null
+++ b/gn/perfetto_benchmarks.gni
@@ -0,0 +1,22 @@
+# Copyright (C) 2019 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("perfetto.gni")
+
+perfetto_benchmarks_targets = [
+  "gn:default_deps",
+  "src/traced/probes/ftrace:benchmarks",
+  "test:benchmark_main",
+  "test:end_to_end_benchmarks",
+]
diff --git a/gn/perfetto_fuzzers.gni b/gn/perfetto_fuzzers.gni
new file mode 100644
index 0000000..b5e0fa4
--- /dev/null
+++ b/gn/perfetto_fuzzers.gni
@@ -0,0 +1,33 @@
+# Copyright (C) 2019 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("perfetto.gni")
+
+perfetto_fuzzers_targets = [
+  "gn:default_deps",
+  "src/ipc:buffered_frame_deserializer_fuzzer",
+  "src/protozero:protozero_decoder_fuzzer",
+  "src/trace_processor:trace_processor_fuzzer",
+  "src/traced/probes/ftrace:cpu_reader_fuzzer",
+  "test:end_to_end_shared_memory_fuzzer",
+  "test:producer_socket_fuzzer",
+]
+
+if (enable_perfetto_heapprofd) {
+  perfetto_fuzzers_targets += [
+    "src/profiling/memory:shared_ring_buffer_fuzzer",
+    "src/profiling/memory:shared_ring_buffer_write_fuzzer",
+    "src/profiling/memory:unwinding_fuzzer",
+  ]
+}
diff --git a/gn/perfetto_host_executable.gni b/gn/perfetto_host_executable.gni
new file mode 100644
index 0000000..ebaf3f6
--- /dev/null
+++ b/gn/perfetto_host_executable.gni
@@ -0,0 +1,57 @@
+# Copyright (C) 2019 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("perfetto.gni")
+
+# A template to make host tools handier. The main problem it solves is that when
+# building host toolchain tools on an Android build, the executables end up in
+# out/xxx/gcc_like_host, which is an inconvenient location. Our developers
+# (and also some of our scripts) expect them to live in out/xxx/.
+# This template takes care takes care of building the target only on the host
+# toolchain and copy it over in the root build directory.
+template("perfetto_host_executable") {
+  if (is_perfetto_build_generator) {
+    # On Android in-tree builds we don't need anything special in GN. However
+    # remember to add the target to the |target_host_only| list in
+    # tools/gen_android_bp to instruct the Android.bp generator.
+    executable(target_name) {
+      forward_variables_from(invoker, "*")
+    }
+  } else {
+    if (current_toolchain == host_toolchain) {
+      executable("${target_name}_host") {
+        forward_variables_from(invoker, "*")
+      }
+    } else {
+      not_needed(invoker, "*")
+    }
+
+    copy(target_name) {
+      if (defined(invoker.testonly)) {
+        testonly = invoker.testonly
+      }
+      deps = [
+        ":${target_name}_host($host_toolchain)",
+      ]
+      host_out_dir = get_label_info(":${target_name}_host($host_toolchain)",
+                                    "root_out_dir")
+      sources = [
+        "$host_out_dir/${target_name}_host",
+      ]
+      outputs = [
+        "$root_out_dir/$target_name",
+      ]
+    }
+  }  # if (is_perfetto_build_generator)
+}
diff --git a/gn/perfetto_integrationtests.gni b/gn/perfetto_integrationtests.gni
new file mode 100644
index 0000000..66da53e
--- /dev/null
+++ b/gn/perfetto_integrationtests.gni
@@ -0,0 +1,40 @@
+# Copyright (C) 2019 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("perfetto.gni")
+
+perfetto_integrationtests_targets = [
+  "gn:default_deps",
+  "gn:gtest_main",
+  "src/tracing:client_api_integrationtests",
+]
+
+if (enable_perfetto_platform_services) {
+  perfetto_integrationtests_targets += [
+    "src/traced/probes/ftrace:integrationtests",
+    "test:end_to_end_integrationtests",
+  ]
+}
+
+if (enable_perfetto_heapprofd) {
+  perfetto_integrationtests_targets +=
+      [ "src/profiling/memory:end_to_end_tests" ]
+}
+
+# This test requires extra data files that are not easily available in Android
+# builds.
+if (enable_perfetto_trace_processor && perfetto_build_standalone) {
+  perfetto_integrationtests_targets +=
+      [ "src/trace_processor:integrationtests" ]
+}
diff --git a/gn/perfetto_unittests.gni b/gn/perfetto_unittests.gni
new file mode 100644
index 0000000..e7c5a44
--- /dev/null
+++ b/gn/perfetto_unittests.gni
@@ -0,0 +1,58 @@
+# Copyright (C) 2019 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("perfetto.gni")
+
+perfetto_unittests_targets = [
+  "gn:default_deps",
+  "gn:gtest_main",
+  "src/base:unittests",
+  "src/protozero:unittests",
+  "src/tracing:unittests",
+]
+
+if (enable_perfetto_tools) {
+  perfetto_unittests_targets += [
+    "tools/ftrace_proto_gen:unittests",
+    "tools/sanitizers_unittests",
+  ]
+}
+
+if (enable_perfetto_ipc) {
+  perfetto_unittests_targets += [ "src/ipc:unittests" ]
+}
+
+if (enable_perfetto_platform_services) {
+  perfetto_unittests_targets += [
+    "src/perfetto_cmd:unittests",
+    "src/traced/probes:unittests",
+    "src/traced/probes/filesystem:unittests",
+    "src/traced/probes/ftrace:unittests",
+    "src/traced/service:unittests",
+  ]
+}
+
+if (enable_perfetto_heapprofd) {
+  perfetto_unittests_targets += [
+    "src/profiling/memory:unittests",
+    "src/profiling/memory:ring_buffer_unittests",
+  ]
+}
+
+if (enable_perfetto_trace_processor) {
+  perfetto_unittests_targets += [
+    "src/trace_processor:unittests",
+    "src/trace_processor/metrics:unittests",
+  ]
+}
diff --git a/gn/proto_library.gni b/gn/proto_library.gni
index a572c9e..b4c1ab0 100644
--- a/gn/proto_library.gni
+++ b/gn/proto_library.gni
@@ -116,7 +116,6 @@
     "sources",
     "visibility",
     "testonly",
-    "generate_descriptor",
   ]
   type_expansion_token = "@TYPE@"
 
@@ -153,6 +152,7 @@
         proto_out_dir = proto_path
         generate_python = false
         generate_cc = false
+        generate_descriptor = invoker.generate_descriptor
         deps = deps_
         forward_variables_from(invoker, vars_to_forward)
       }
diff --git a/gn/standalone/wasm.gni b/gn/standalone/wasm.gni
index 0100351..b3a6c1a 100644
--- a/gn/standalone/wasm.gni
+++ b/gn/standalone/wasm.gni
@@ -12,8 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-wasm_toolchain = "//gn/standalone/toolchain:wasm"
-is_wasm = current_toolchain == wasm_toolchain
+import("../wasm_vars.gni")
+
 emsdk_dir = rebase_path("//buildtools/emsdk", "")
 nodejs_dir = rebase_path("//buildtools/nodejs", "")
 
diff --git a/gn/test.gni b/gn/test.gni
index 81d38ac..d177acb 100644
--- a/gn/test.gni
+++ b/gn/test.gni
@@ -14,7 +14,7 @@
 
 import("perfetto.gni")
 
-if (perfetto_build_standalone || perfetto_build_with_android) {
+if (perfetto_root_path == "//") {
   template("test") {
     executable(target_name) {
       forward_variables_from(invoker, "*")
@@ -32,3 +32,18 @@
     }
   }
 }
+
+# This is to avoid that unittest targets get discovered and built in the
+# "default" GN target of embedder builds. See notes in the comments of the
+# root BUILD.gn.
+template("perfetto_unittest_source_set") {
+  if (enable_perfetto_unittests) {
+    source_set(target_name) {
+      forward_variables_from(invoker, "*")
+    }
+  } else {
+    group(target_name) {
+      not_needed(invoker, "*")
+    }
+  }
+}
diff --git a/gn/wasm.gni b/gn/wasm.gni
index 87326c9..a8bc0a9 100644
--- a/gn/wasm.gni
+++ b/gn/wasm.gni
@@ -12,14 +12,12 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import("//build_overrides/build.gni")
 import("perfetto.gni")
+import("wasm_vars.gni")
 
-if (perfetto_build_standalone) {
+if (perfetto_root_path == "//") {
   import("//gn/standalone/wasm.gni")
 } else {
-  is_wasm = false  # The WASM toolchain is supported only in standalone builds.
-
   # Create a dummy template to avoid GN warnings in non-standalone builds.
   template("wasm_lib") {
     source_set("${target_name}_${invoker.name}_unused") {
diff --git a/gn/wasm_vars.gni b/gn/wasm_vars.gni
new file mode 100644
index 0000000..39998f5
--- /dev/null
+++ b/gn/wasm_vars.gni
@@ -0,0 +1,16 @@
+# Copyright (C) 2019 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.
+
+wasm_toolchain = "//gn/standalone/toolchain:wasm"
+is_wasm = current_toolchain == wasm_toolchain
diff --git a/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h b/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h
index 1274e36..bef52ba 100644
--- a/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h
+++ b/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h
@@ -5,14 +5,17 @@
 #define GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
 
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_BUILD() (1)
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_EMBEDDER_BUILD() (0)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_CHROMIUM_BUILD() (0)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_STANDALONE_BUILD() (0)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_START_DAEMONS() (0)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_IPC() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_WATCHDOG() (1)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPONENT_BUILD() (0)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_ON() (0)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_OFF() (0)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_VERSION_GEN() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_LINENOISE() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_JSON() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_PERCENTILE() (0)
 
 #endif  // GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
diff --git a/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h b/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
index fee1ad9..d32a21c 100644
--- a/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
+++ b/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
@@ -5,14 +5,17 @@
 #define GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
 
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_BUILD() (0)
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_EMBEDDER_BUILD() (0)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_CHROMIUM_BUILD() (0)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_STANDALONE_BUILD() (1)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_START_DAEMONS() (1)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_IPC() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_WATCHDOG() (1)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPONENT_BUILD() (0)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_ON() (0)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_OFF() (0)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_VERSION_GEN() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_LINENOISE() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_JSON() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_PERCENTILE() (1)
 
 #endif  // GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
diff --git a/include/perfetto/ext/base/BUILD.gn b/include/perfetto/ext/base/BUILD.gn
index 2a574a0..db82b08 100644
--- a/include/perfetto/ext/base/BUILD.gn
+++ b/include/perfetto/ext/base/BUILD.gn
@@ -49,7 +49,7 @@
     "watchdog_posix.h",
     "weak_ptr.h",
   ]
-  if (perfetto_build_with_ipc_layer) {
+  if (enable_perfetto_ipc) {
     sources += [ "unix_socket.h" ]
   }
   public_configs = [ "../../../../gn:asan_instrumentation" ]
diff --git a/include/perfetto/ext/base/watchdog.h b/include/perfetto/ext/base/watchdog.h
index a10fde1..d248dd2 100644
--- a/include/perfetto/ext/base/watchdog.h
+++ b/include/perfetto/ext/base/watchdog.h
@@ -23,15 +23,7 @@
 
 // The POSIX watchdog is only supported on Linux and Android in non-embedder
 // builds.
-#if (PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||    \
-     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)) && \
-    !PERFETTO_BUILDFLAG(PERFETTO_EMBEDDER_BUILD)
-#define PERFETTO_USE_POSIX_WATCHDOG() 1
-#else
-#define PERFETTO_USE_POSIX_WATCHDOG() 0
-#endif
-
-#if PERFETTO_USE_POSIX_WATCHDOG()
+#if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
 #include "perfetto/ext/base/watchdog_posix.h"
 #else
 #include "perfetto/ext/base/watchdog_noop.h"
diff --git a/include/perfetto/protozero/message.h b/include/perfetto/protozero/message.h
index b5347dc..213a436 100644
--- a/include/perfetto/protozero/message.h
+++ b/include/perfetto/protozero/message.h
@@ -46,9 +46,7 @@
 class PERFETTO_EXPORT Message {
  public:
   friend class MessageHandleBase;
-  // Grant end_to_end_shared_memory_fuzzer access in order to write raw
-  // bytes into the buffer.
-  friend class ::perfetto::shm_fuzz::FakeProducer;
+
   // Adjust the |nested_messages_arena_| size when changing this, or the
   // static_assert in the .cc file will bark.
   static constexpr uint32_t kMaxNestingDepth = 10;
@@ -171,6 +169,8 @@
     return message;
   }
 
+  ScatteredStreamWriter* stream_writer_for_testing() { return stream_writer_; }
+
  private:
   Message(const Message&) = delete;
   Message& operator=(const Message&) = delete;
diff --git a/protos/perfetto/trace/BUILD.gn b/protos/perfetto/trace/BUILD.gn
index 02c504a..1945126 100644
--- a/protos/perfetto/trace/BUILD.gn
+++ b/protos/perfetto/trace/BUILD.gn
@@ -120,3 +120,12 @@
     ]
   }
 }
+
+# This target exports perfetto trace protos allowing both host and device
+# targets to implement custom parsers based on our protos.
+static_library("perfetto_trace_protos") {
+  complete_static_lib = true
+  deps = [
+    ":lite",
+  ]
+}
diff --git a/src/android_internal/BUILD.gn b/src/android_internal/BUILD.gn
index d1bea0f..819532a 100644
--- a/src/android_internal/BUILD.gn
+++ b/src/android_internal/BUILD.gn
@@ -14,6 +14,15 @@
 
 import("../../gn/perfetto.gni")
 
+# This target is supported only in in-tree builds of Android. It contains
+# code that is not NDK-clean and references other repos in the Android tree.
+shared_library("libperfetto_android_internal") {
+  deps = [
+    ":android_internal",
+    "../../gn:default_deps",
+  ]
+}
+
 source_set("headers") {
   deps = [
     "../../gn:default_deps",
@@ -45,7 +54,7 @@
 # This target proxies calls to Android internal libraries that are not part of
 # the NDK. See README.md.
 source_set("android_internal") {
-  visibility = [ "//:libperfetto_android_internal" ]
+  visibility = [ ":libperfetto_android_internal" ]
   deps = [
     ":headers",
     "../../gn:default_deps",
diff --git a/src/base/BUILD.gn b/src/base/BUILD.gn
index 1d2e8a3..9f53d4b 100644
--- a/src/base/BUILD.gn
+++ b/src/base/BUILD.gn
@@ -14,8 +14,11 @@
 
 import("//build_overrides/build.gni")
 import("../../gn/perfetto.gni")
+import("../../gn/test.gni")
 import("../../gn/wasm.gni")
 
+enable_stack_trace = is_debug && perfetto_build_standalone && !is_wasm
+
 source_set("base") {
   deps = [
     "../../gn:default_deps",
@@ -50,12 +53,12 @@
     ]
   }
 
-  if (is_debug && perfetto_build_standalone && !is_wasm) {
+  if (enable_stack_trace) {
     deps += [ ":debug_crash_stack_trace" ]
   }
 }
 
-if (is_debug && perfetto_build_standalone && !is_wasm) {
+if (enable_stack_trace) {
   source_set("debug_crash_stack_trace") {
     sources = [
       "debug_crash_stack_trace.cc",
@@ -72,7 +75,7 @@
   }
 }
 
-if (perfetto_build_with_ipc_layer) {
+if (enable_perfetto_ipc) {
   # This cannot be in :base as it does not build on WASM.
   source_set("unix_socket") {
     deps = [
@@ -108,7 +111,7 @@
   }
 }
 
-source_set("unittests") {
+perfetto_unittest_source_set("unittests") {
   testonly = true
   deps = [
     ":base",
@@ -133,7 +136,7 @@
     "weak_ptr_unittest.cc",
   ]
 
-  # TODO(brucedawson): Enable these for Windows when possible.
+  # TODO: Enable these for Windows when possible.
   if (!is_win) {
     sources += [
       "metatrace_unittest.cc",
@@ -145,6 +148,7 @@
     ]
   }
   if (perfetto_build_standalone || perfetto_build_with_android) {
+    # This causes some problems on the chromium waterfall.
     sources += [ "unix_socket_unittest.cc" ]
     if (is_linux || is_android) {
       sources += [ "watchdog_unittest.cc" ]
diff --git a/src/base/watchdog_posix.cc b/src/base/watchdog_posix.cc
index 98a3d3c..401ecdb 100644
--- a/src/base/watchdog_posix.cc
+++ b/src/base/watchdog_posix.cc
@@ -16,7 +16,7 @@
 
 #include "perfetto/ext/base/watchdog.h"
 
-#if PERFETTO_USE_POSIX_WATCHDOG()
+#if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
 
 #include <fcntl.h>
 #include <inttypes.h>
@@ -259,4 +259,4 @@
 }  // namespace base
 }  // namespace perfetto
 
-#endif  // PERFETTO_USE_POSIX_WATCHDOG()
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
diff --git a/src/ipc/BUILD.gn b/src/ipc/BUILD.gn
index 15ae075..e476e1c 100644
--- a/src/ipc/BUILD.gn
+++ b/src/ipc/BUILD.gn
@@ -16,17 +16,11 @@
 import("../../gn/ipc_library.gni")
 import("../../gn/perfetto.gni")
 import("../../gn/proto_library.gni")
-
-# For use_libfuzzer.
-if (perfetto_root_path == "//") {
-  import("//gn/standalone/sanitizers/vars.gni")
-} else {
-  import("//build/config/sanitizers/sanitizers.gni")
-}
+import("../../gn/test.gni")
 
 # This build file should not be leaked into all embedders. Only select
 # projects should be depending on our IPC layer.
-assert(perfetto_build_with_ipc_layer)
+assert(enable_perfetto_ipc)
 
 source_set("ipc") {
   public_configs = [ "../../gn:default_config" ]
@@ -63,7 +57,7 @@
   ]
 }
 
-source_set("unittests") {
+perfetto_unittest_source_set("unittests") {
   testonly = true
   deps = [
     ":ipc",
diff --git a/src/perfetto_cmd/BUILD.gn b/src/perfetto_cmd/BUILD.gn
index 1892db6..fe6cf12 100644
--- a/src/perfetto_cmd/BUILD.gn
+++ b/src/perfetto_cmd/BUILD.gn
@@ -14,7 +14,38 @@
 
 import("../../gn/perfetto.gni")
 import("../../gn/proto_library.gni")
+import("../../gn/test.gni")
 
+# The command line client for Perfetto. Allows to configure / start / stop
+# tracing, acting as a Consumer.
+executable("perfetto") {
+  deps = [
+    ":perfetto_cmd",
+    "../../gn:default_deps",
+  ]
+  sources = [
+    "main.cc",
+  ]
+}
+
+# Tool to finalize long running traces.
+# This connects to traced as a producer and sends the triggers passed on the
+# commandline. This is a subset of what the perfetto binary can do but we
+# need a separate binary for programs that cannot (for good reason) use the
+# additional functionality (for example starting traces via consumer socket)
+# due to selinux rules.
+executable("trigger_perfetto") {
+  deps = [
+    ":trigger_perfetto_cmd",
+    "../../gn:default_deps",
+  ]
+  sources = [
+    "trigger_perfetto_main.cc",
+  ]
+}
+
+# Contains all the implementation but not the main() entry point. This target
+# is shared both by the executable and tests.
 source_set("perfetto_cmd") {
   public_deps = [
     ":protos",
@@ -86,7 +117,7 @@
   proto_path = perfetto_root_path
 }
 
-source_set("unittests") {
+perfetto_unittest_source_set("unittests") {
   testonly = true
   public_deps = []
   deps = [
diff --git a/src/profiling/memory/BUILD.gn b/src/profiling/memory/BUILD.gn
index 24b4701..70f66c5 100644
--- a/src/profiling/memory/BUILD.gn
+++ b/src/profiling/memory/BUILD.gn
@@ -12,17 +12,68 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import("//build_overrides/build.gni")
 import("../../../gn/fuzzer.gni")
 import("../../../gn/perfetto.gni")
+import("../../../gn/test.gni")
 
-# For use_libfuzzer.
-if (!build_with_chromium) {
-  import("//gn/standalone/sanitizers/vars.gni")
-} else {
-  import("//build/config/sanitizers/sanitizers.gni")
+assert(enable_perfetto_heapprofd)
+
+# The Android heap profiling daemon.
+executable("heapprofd") {
+  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",
+  ]
+  sources = [
+    "main.cc",
+  ]
 }
 
+# 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 = [
+      ":malloc_hooks",
+    ]
+  }
+
+  # This will export publicly visible symbols for the malloc_hooks.
+  source_set("malloc_hooks") {
+    deps = [
+      ":client",
+      ":proc_utils",
+      ":scoped_spinlock",
+      ":wire_protocol",
+      "../../../gn:default_deps",
+      "../../base",
+      "../../base:unix_socket",
+    ]
+    cflags = [
+      "-isystem",
+      rebase_path("../../../buildtools/bionic/libc", root_build_dir),
+    ]
+    sources = [
+      "malloc_hooks.cc",
+    ]
+  }
+}  # if (perfetto_build_with_android)
+
 source_set("wire_protocol") {
   public_deps = [
     "../../../gn:libunwindstack",
@@ -134,10 +185,12 @@
     ":scoped_spinlock",
     ":wire_protocol",
     "../../../gn:default_deps",
-    "../../../gn:libunwindstack",
     "../../base",
     "../../base:unix_socket",
   ]
+  public_deps = [
+    "../../../gn:libunwindstack",
+  ]
   sources = [
     "client.cc",
     "client.h",
@@ -145,7 +198,7 @@
   ]
 }
 
-source_set("unittests") {
+perfetto_unittest_source_set("unittests") {
   testonly = true
   deps = [
     ":client",
@@ -196,26 +249,6 @@
   }
 }
 
-# This will export publicly visibile symbols for the malloc_hooks.
-source_set("malloc_hooks") {
-  deps = [
-    ":client",
-    ":proc_utils",
-    ":scoped_spinlock",
-    ":wire_protocol",
-    "../../../gn:default_deps",
-    "../../base",
-    "../../base:unix_socket",
-  ]
-  cflags = [
-    "-isystem",
-    rebase_path("../../../buildtools/bionic/libc", root_build_dir),
-  ]
-  sources = [
-    "malloc_hooks.cc",
-  ]
-}
-
 perfetto_fuzzer_test("unwinding_fuzzer") {
   testonly = true
   sources = [
diff --git a/src/protozero/BUILD.gn b/src/protozero/BUILD.gn
index d83c88a..b767a9a 100644
--- a/src/protozero/BUILD.gn
+++ b/src/protozero/BUILD.gn
@@ -15,6 +15,7 @@
 import("../../gn/fuzzer.gni")
 import("../../gn/perfetto.gni")
 import("../../gn/proto_library.gni")
+import("../../gn/test.gni")
 
 source_set("protozero") {
   public_configs = [ "../../gn:default_config" ]
@@ -36,16 +37,14 @@
   ]
 }
 
-if (!build_with_chromium) {
-  static_library("libprotozero") {
-    complete_static_lib = true
-    deps = [
-      ":protozero",
-    ]
-  }
+static_library("libprotozero") {
+  complete_static_lib = true
+  deps = [
+    ":protozero",
+  ]
 }
 
-source_set("unittests") {
+perfetto_unittest_source_set("unittests") {
   testonly = true
   deps = [
     ":protozero",
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index b366c06..aa193a7 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -14,9 +14,13 @@
 
 import("../../gn/fuzzer.gni")
 import("../../gn/perfetto.gni")
+import("../../gn/test.gni")
 import("../../gn/wasm.gni")
 
-if (perfetto_build_standalone) {
+# Prevent that this file is accidentally included in embedder builds.
+assert(enable_perfetto_trace_processor)
+
+if (enable_perfetto_ui) {
   wasm_lib("trace_processor_wasm") {
     name = "trace_processor"
     sources = [
@@ -196,7 +200,7 @@
   public_deps = [
     "../../include/perfetto/trace_processor",
   ]
-  if (perfetto_build_standalone || build_with_chromium) {
+  if (enable_perfetto_trace_processor_json) {
     sources += [
       "export_json.cc",
       "export_json.h",
@@ -211,7 +215,7 @@
   }
 }
 
-source_set("trace_processor_shell") {
+executable("trace_processor_shell") {
   testonly = true  # We need this for proto full.
   deps = [
     ":lib",
@@ -220,11 +224,11 @@
     "../base",
     "metrics:lib",
   ]
-  if (perfetto_build_standalone) {
-    deps += [
-      "../../gn:linenoise",
-      "../../gn/standalone:gen_git_revision",
-    ]
+  if (enable_perfetto_version_gen) {
+    deps += [ "../../gn/standalone:gen_git_revision" ]
+  }
+  if (enable_perfetto_trace_processor_linenoise) {
+    deps += [ "../../gn:linenoise" ]
   }
 
   sources = [
@@ -232,7 +236,7 @@
   ]
 }
 
-source_set("unittests") {
+perfetto_unittest_source_set("unittests") {
   testonly = true
   sources = [
     "args_table_unittest.cc",
@@ -280,7 +284,7 @@
     "sqlite:unittests",
     "tables:unittests",
   ]
-  if (perfetto_build_standalone || build_with_chromium) {
+  if (enable_perfetto_trace_processor_json) {
     sources += [
       "export_json_unittest.cc",
       "json_trace_tokenizer_unittest.cc",
@@ -305,7 +309,7 @@
     "../base:test_support",
     "sqlite",
   ]
-  if (perfetto_build_standalone || build_with_chromium) {
+  if (enable_perfetto_trace_processor_json) {
     deps += [ "../../gn:jsoncpp" ]
   }
 }
diff --git a/src/trace_processor/db/BUILD.gn b/src/trace_processor/db/BUILD.gn
index 91dfa0e..c835ea2 100644
--- a/src/trace_processor/db/BUILD.gn
+++ b/src/trace_processor/db/BUILD.gn
@@ -12,6 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import("../../../gn/test.gni")
+
 source_set("lib") {
   sources = [
     "bit_vector.cc",
@@ -31,7 +33,7 @@
   ]
 }
 
-source_set("unittests") {
+perfetto_unittest_source_set("unittests") {
   testonly = true
   sources = [
     "bit_vector_unittest.cc",
diff --git a/src/trace_processor/forwarding_trace_parser.cc b/src/trace_processor/forwarding_trace_parser.cc
index ce4b368..b3aced7 100644
--- a/src/trace_processor/forwarding_trace_parser.cc
+++ b/src/trace_processor/forwarding_trace_parser.cc
@@ -27,8 +27,7 @@
 
 // JSON parsing and exporting is only supported in the standalone and
 // Chromium builds.
-#if PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) || \
-    PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
 #include "src/trace_processor/json_trace_parser.h"
 #include "src/trace_processor/json_trace_tokenizer.h"
 #endif
@@ -69,8 +68,7 @@
     switch (trace_type) {
       case kJsonTraceType: {
         PERFETTO_DLOG("JSON trace detected");
-#if PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) || \
-    PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
         reader_.reset(new JsonTraceTokenizer(context_));
         // JSON traces have no guarantees about the order of events in them.
         int64_t window_size_ns = std::numeric_limits<int64_t>::max();
diff --git a/src/trace_processor/json_trace_parser.cc b/src/trace_processor/json_trace_parser.cc
index 627a5f0..5dc2816 100644
--- a/src/trace_processor/json_trace_parser.cc
+++ b/src/trace_processor/json_trace_parser.cc
@@ -32,10 +32,8 @@
 #include "src/trace_processor/slice_tracker.h"
 #include "src/trace_processor/trace_processor_context.h"
 
-#if !PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) && \
-    !PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
-#error The JSON trace parser is supported only in the standalone and \
-Chromium builds for now.
+#if !PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
+#error JSON parsing and exporting is not supported in this build configuration
 #endif
 
 namespace perfetto {
diff --git a/src/trace_processor/json_trace_utils.cc b/src/trace_processor/json_trace_utils.cc
index 292b7c1..0d6ba70 100644
--- a/src/trace_processor/json_trace_utils.cc
+++ b/src/trace_processor/json_trace_utils.cc
@@ -19,10 +19,10 @@
 #include <json/value.h>
 #include <limits>
 
-#if !PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) && \
-    !PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
-#error The JSON trace parser is supported only in the standalone and \
-Chromium builds for now.
+#include "perfetto/base/build_config.h"
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
+#error JSON parsing and exporting is not supported in this build configuration
 #endif
 
 namespace perfetto {
diff --git a/src/trace_processor/metrics/BUILD.gn b/src/trace_processor/metrics/BUILD.gn
index 2713ed7..5ed8eab 100644
--- a/src/trace_processor/metrics/BUILD.gn
+++ b/src/trace_processor/metrics/BUILD.gn
@@ -13,6 +13,7 @@
 # limitations under the License.
 
 import("../../../gn/perfetto.gni")
+import("../../../gn/test.gni")
 
 sql_files = [
   "trace_metadata.sql",
@@ -81,7 +82,7 @@
   ]
 }
 
-source_set("unittests") {
+perfetto_unittest_source_set("unittests") {
   testonly = true
   sources = [
     "metrics_unittest.cc",
diff --git a/src/trace_processor/metrics/metrics.h b/src/trace_processor/metrics/metrics.h
index 7508d88..771bb16 100644
--- a/src/trace_processor/metrics/metrics.h
+++ b/src/trace_processor/metrics/metrics.h
@@ -17,6 +17,8 @@
 #ifndef SRC_TRACE_PROCESSOR_METRICS_METRICS_H_
 #define SRC_TRACE_PROCESSOR_METRICS_METRICS_H_
 
+#include <sqlite3.h>
+
 #include <unordered_map>
 #include <vector>
 
@@ -25,9 +27,7 @@
 #include "perfetto/protozero/message.h"
 #include "perfetto/protozero/scattered_heap_buffer.h"
 #include "perfetto/trace_processor/trace_processor.h"
-
 #include "src/trace_processor/metrics/descriptors.h"
-#include "src/trace_processor/sqlite/sqlite.h"
 
 #include "protos/perfetto/trace_processor/metrics_impl.pbzero.h"
 
diff --git a/src/trace_processor/span_join_operator_table.cc b/src/trace_processor/span_join_operator_table.cc
index 991b692..57b1598 100644
--- a/src/trace_processor/span_join_operator_table.cc
+++ b/src/trace_processor/span_join_operator_table.cc
@@ -16,7 +16,9 @@
 
 #include "src/trace_processor/span_join_operator_table.h"
 
+#include <sqlite3.h>
 #include <string.h>
+
 #include <algorithm>
 #include <set>
 #include <utility>
@@ -25,7 +27,6 @@
 #include "perfetto/ext/base/string_splitter.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/string_view.h"
-#include "src/trace_processor/sqlite/sqlite.h"
 #include "src/trace_processor/sqlite/sqlite_utils.h"
 
 namespace perfetto {
diff --git a/src/trace_processor/span_join_operator_table.h b/src/trace_processor/span_join_operator_table.h
index fecedc7..eb96161 100644
--- a/src/trace_processor/span_join_operator_table.h
+++ b/src/trace_processor/span_join_operator_table.h
@@ -17,6 +17,8 @@
 #ifndef SRC_TRACE_PROCESSOR_SPAN_JOIN_OPERATOR_TABLE_H_
 #define SRC_TRACE_PROCESSOR_SPAN_JOIN_OPERATOR_TABLE_H_
 
+#include <sqlite3.h>
+
 #include <array>
 #include <deque>
 #include <limits>
@@ -29,7 +31,6 @@
 #include "perfetto/trace_processor/basic_types.h"
 #include "perfetto/trace_processor/status.h"
 #include "src/trace_processor/sqlite/scoped_db.h"
-#include "src/trace_processor/sqlite/sqlite.h"
 #include "src/trace_processor/sqlite/sqlite_table.h"
 
 namespace perfetto {
diff --git a/src/trace_processor/sql_stats_table.cc b/src/trace_processor/sql_stats_table.cc
index 605f067..3356f8e 100644
--- a/src/trace_processor/sql_stats_table.cc
+++ b/src/trace_processor/sql_stats_table.cc
@@ -16,11 +16,12 @@
 
 #include "src/trace_processor/sql_stats_table.h"
 
+#include <sqlite3.h>
+
 #include <algorithm>
 #include <bitset>
 #include <numeric>
 
-#include "src/trace_processor/sqlite/sqlite.h"
 #include "src/trace_processor/sqlite/sqlite_utils.h"
 #include "src/trace_processor/trace_storage.h"
 
diff --git a/src/trace_processor/sqlite/BUILD.gn b/src/trace_processor/sqlite/BUILD.gn
index ec7ff62..f613c93 100644
--- a/src/trace_processor/sqlite/BUILD.gn
+++ b/src/trace_processor/sqlite/BUILD.gn
@@ -12,12 +12,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import("../../../gn/test.gni")
+
 source_set("sqlite") {
   sources = [
     "query_constraints.cc",
     "query_constraints.h",
     "scoped_db.h",
-    "sqlite.h",
     "sqlite3_str_split.cc",
     "sqlite3_str_split.h",
     "sqlite_table.cc",
@@ -33,7 +34,7 @@
   ]
 }
 
-source_set("unittests") {
+perfetto_unittest_source_set("unittests") {
   testonly = true
   sources = [
     "query_constraints_unittest.cc",
diff --git a/src/trace_processor/sqlite/query_constraints.cc b/src/trace_processor/sqlite/query_constraints.cc
index 98a2235..cc57838 100644
--- a/src/trace_processor/sqlite/query_constraints.cc
+++ b/src/trace_processor/sqlite/query_constraints.cc
@@ -16,10 +16,11 @@
 
 #include "src/trace_processor/sqlite/query_constraints.h"
 
+#include <sqlite3.h>
+
 #include <string>
 
 #include "perfetto/ext/base/string_splitter.h"
-#include "src/trace_processor/sqlite/sqlite.h"
 
 namespace perfetto {
 namespace trace_processor {
diff --git a/src/trace_processor/sqlite/query_constraints.h b/src/trace_processor/sqlite/query_constraints.h
index f06e5e1..2c47562 100644
--- a/src/trace_processor/sqlite/query_constraints.h
+++ b/src/trace_processor/sqlite/query_constraints.h
@@ -17,10 +17,11 @@
 #ifndef SRC_TRACE_PROCESSOR_SQLITE_QUERY_CONSTRAINTS_H_
 #define SRC_TRACE_PROCESSOR_SQLITE_QUERY_CONSTRAINTS_H_
 
+#include <sqlite3.h>
+
 #include <vector>
 
 #include "perfetto/ext/base/scoped_file.h"
-#include "src/trace_processor/sqlite/sqlite.h"
 
 namespace perfetto {
 namespace trace_processor {
diff --git a/src/trace_processor/sqlite/scoped_db.h b/src/trace_processor/sqlite/scoped_db.h
index 8d4b037..244f0b4 100644
--- a/src/trace_processor/sqlite/scoped_db.h
+++ b/src/trace_processor/sqlite/scoped_db.h
@@ -18,7 +18,6 @@
 #define SRC_TRACE_PROCESSOR_SQLITE_SCOPED_DB_H_
 
 #include "perfetto/ext/base/scoped_file.h"
-#include "src/trace_processor/sqlite/sqlite.h"
 
 extern "C" {
 struct sqlite3;
diff --git a/src/trace_processor/sqlite/sqlite.h b/src/trace_processor/sqlite/sqlite.h
deleted file mode 100644
index f86b635..0000000
--- a/src/trace_processor/sqlite/sqlite.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#ifndef SRC_TRACE_PROCESSOR_SQLITE_SQLITE_H_
-#define SRC_TRACE_PROCESSOR_SQLITE_SQLITE_H_
-
-#include "perfetto/base/build_config.h"
-
-#if PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) || \
-    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
-#include <sqlite3.h>
-#else
-#include "third_party/sqlite/sqlite3.h"
-#endif
-
-#endif  // SRC_TRACE_PROCESSOR_SQLITE_SQLITE_H_
diff --git a/src/trace_processor/sqlite/sqlite3_str_split_unittest.cc b/src/trace_processor/sqlite/sqlite3_str_split_unittest.cc
index 4f58040..c114ff8 100644
--- a/src/trace_processor/sqlite/sqlite3_str_split_unittest.cc
+++ b/src/trace_processor/sqlite/sqlite3_str_split_unittest.cc
@@ -16,11 +16,11 @@
 
 #include "src/trace_processor/sqlite/sqlite3_str_split.h"
 
+#include <sqlite3.h>
 #include <string>
 
 #include "perfetto/base/logging.h"
 #include "src/trace_processor/sqlite/scoped_db.h"
-#include "src/trace_processor/sqlite/sqlite.h"
 #include "test/gtest_and_gmock.h"
 
 namespace perfetto {
diff --git a/src/trace_processor/sqlite/sqlite_table.h b/src/trace_processor/sqlite/sqlite_table.h
index 04cbcc4..4fb5f12 100644
--- a/src/trace_processor/sqlite/sqlite_table.h
+++ b/src/trace_processor/sqlite/sqlite_table.h
@@ -17,6 +17,8 @@
 #ifndef SRC_TRACE_PROCESSOR_SQLITE_SQLITE_TABLE_H_
 #define SRC_TRACE_PROCESSOR_SQLITE_SQLITE_TABLE_H_
 
+#include <sqlite3.h>
+
 #include <functional>
 #include <memory>
 #include <string>
@@ -27,7 +29,6 @@
 #include "perfetto/trace_processor/basic_types.h"
 #include "perfetto/trace_processor/status.h"
 #include "src/trace_processor/sqlite/query_constraints.h"
-#include "src/trace_processor/sqlite/sqlite.h"
 
 namespace perfetto {
 namespace trace_processor {
diff --git a/src/trace_processor/sqlite/sqlite_utils.h b/src/trace_processor/sqlite/sqlite_utils.h
index 9c1ddeb..83d1181 100644
--- a/src/trace_processor/sqlite/sqlite_utils.h
+++ b/src/trace_processor/sqlite/sqlite_utils.h
@@ -18,6 +18,7 @@
 #define SRC_TRACE_PROCESSOR_SQLITE_SQLITE_UTILS_H_
 
 #include <math.h>
+#include <sqlite3.h>
 
 #include <functional>
 #include <limits>
@@ -26,7 +27,6 @@
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/optional.h"
 #include "src/trace_processor/sqlite/scoped_db.h"
-#include "src/trace_processor/sqlite/sqlite.h"
 #include "src/trace_processor/sqlite/sqlite_table.h"
 
 namespace perfetto {
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index c2aebaa..6a3f23b 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -71,16 +71,13 @@
 #include "protos/perfetto/metrics/android/mem_metric.pbzero.h"
 #include "protos/perfetto/metrics/metrics.pbzero.h"
 
-// JSON parsing and exporting is only supported in the standalone and
-// Chromium builds.
-#if PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) || \
-    PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
 #include "src/trace_processor/export_json.h"
 #endif
 
 // In Android and Chromium tree builds, we don't have the percentile module.
 // Just don't include it.
-#if PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD)
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_PERCENTILE)
 // defined in sqlite_src/ext/misc/percentile.c
 extern "C" int sqlite3_percentile_init(sqlite3* db,
                                        char** error,
@@ -100,7 +97,7 @@
   sqlite3_str_split_init(db);
 // In Android tree builds, we don't have the percentile module.
 // Just don't include it.
-#if PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD)
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_PERCENTILE)
   sqlite3_percentile_init(db, &error, nullptr);
   if (error) {
     PERFETTO_ELOG("Error initializing: %s", error);
@@ -190,10 +187,7 @@
   }
 }
 
-// Exporting traces in legacy JSON format is only supported
-// in the standalone and Chromium builds so far.
-#if PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) || \
-    PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
 void ExportJson(sqlite3_context* ctx, int /*argc*/, sqlite3_value** argv) {
   TraceStorage* storage = static_cast<TraceStorage*>(sqlite3_user_data(ctx));
   const char* filename =
@@ -280,8 +274,7 @@
   context_.heap_profile_tracker.reset(new HeapProfileTracker(&context_));
   context_.systrace_parser.reset(new SystraceParser(&context_));
 
-#if PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) || \
-    PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
   CreateJsonExportFunction(this->context_.storage.get(), db);
 #endif
 
diff --git a/src/trace_processor/trace_processor_impl.h b/src/trace_processor/trace_processor_impl.h
index 0f5d1a1..fa62585 100644
--- a/src/trace_processor/trace_processor_impl.h
+++ b/src/trace_processor/trace_processor_impl.h
@@ -17,6 +17,8 @@
 #ifndef SRC_TRACE_PROCESSOR_TRACE_PROCESSOR_IMPL_H_
 #define SRC_TRACE_PROCESSOR_TRACE_PROCESSOR_IMPL_H_
 
+#include <sqlite3.h>
+
 #include <atomic>
 #include <functional>
 #include <memory>
@@ -29,7 +31,6 @@
 #include "src/trace_processor/metrics/descriptors.h"
 #include "src/trace_processor/metrics/metrics.h"
 #include "src/trace_processor/sqlite/scoped_db.h"
-#include "src/trace_processor/sqlite/sqlite.h"
 #include "src/trace_processor/trace_processor_context.h"
 
 namespace perfetto {
diff --git a/src/trace_processor/trace_processor_shell.cc b/src/trace_processor/trace_processor_shell.cc
index 5cca3c9..a6355b2 100644
--- a/src/trace_processor/trace_processor_shell.cc
+++ b/src/trace_processor/trace_processor_shell.cc
@@ -52,7 +52,7 @@
 #define PERFETTO_HAS_AIO_H() 0
 #endif
 
-#if PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD)
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_LINENOISE)
 #include <linenoise.h>
 #include <pwd.h>
 #include <sys/types.h>
@@ -85,7 +85,7 @@
 namespace {
 TraceProcessor* g_tp;
 
-#if PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD)
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_LINENOISE)
 
 bool EnsureDir(const std::string& path) {
   return mkdir(path.c_str(), 0755) != -1 || errno == EEXIST;
@@ -163,7 +163,7 @@
   return line;
 }
 
-#endif
+#endif  // PERFETTO_TP_LINENOISE
 
 bool PrintStats() {
   auto it = g_tp->ExecuteQuery(
diff --git a/src/trace_processor/trace_sorter.h b/src/trace_processor/trace_sorter.h
index 2ea3d96..873f965 100644
--- a/src/trace_processor/trace_sorter.h
+++ b/src/trace_processor/trace_sorter.h
@@ -27,8 +27,7 @@
 #include "src/trace_processor/trace_processor_context.h"
 #include "src/trace_processor/trace_storage.h"
 
-#if PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) || \
-    PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
 #include <json/value.h>
 #else
 // Json traces are only supported in standalone and Chromium builds.
diff --git a/src/traced/probes/BUILD.gn b/src/traced/probes/BUILD.gn
index b61a611..ca0b1db 100644
--- a/src/traced/probes/BUILD.gn
+++ b/src/traced/probes/BUILD.gn
@@ -12,6 +12,23 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import("../../../gn/test.gni")
+
+# The unprivileged daemon that is allowed to access tracefs (for ftrace).
+# Registers as a Producer on the traced daemon.
+executable("traced_probes") {
+  deps = [
+    "../../../:libperfetto",
+    "../../../gn:default_deps",
+    "../../../include/perfetto/ext/traced",
+  ]
+  sources = [
+    "main.cc",
+  ]
+}
+
+# Contains all the implementation but not the main() entry point. This target
+# is shared both by the executable and tests.
 source_set("probes") {
   public_deps = [
     "../../../include/perfetto/ext/traced",
@@ -65,7 +82,7 @@
   ]
 }
 
-source_set("unittests") {
+perfetto_unittest_source_set("unittests") {
   testonly = true
   deps = [
     ":probes_src",
diff --git a/src/traced/probes/android_log/BUILD.gn b/src/traced/probes/android_log/BUILD.gn
index e7ace9e..eac5fd3 100644
--- a/src/traced/probes/android_log/BUILD.gn
+++ b/src/traced/probes/android_log/BUILD.gn
@@ -12,6 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import("../../../../gn/test.gni")
+
 source_set("android_log") {
   public_deps = [
     "../../../tracing",
@@ -31,7 +33,7 @@
   ]
 }
 
-source_set("unittests") {
+perfetto_unittest_source_set("unittests") {
   testonly = true
   deps = [
     ":android_log",
diff --git a/src/traced/probes/filesystem/BUILD.gn b/src/traced/probes/filesystem/BUILD.gn
index c8afd29..d3aeba5 100644
--- a/src/traced/probes/filesystem/BUILD.gn
+++ b/src/traced/probes/filesystem/BUILD.gn
@@ -12,6 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import("../../../../gn/test.gni")
+
 source_set("filesystem") {
   public_deps = [
     "../../../../protos/perfetto/trace/filesystem:zero",
@@ -40,7 +42,7 @@
   ]
 }
 
-source_set("unittests") {
+perfetto_unittest_source_set("unittests") {
   testonly = true
   deps = [
     ":filesystem",
diff --git a/src/traced/probes/ftrace/BUILD.gn b/src/traced/probes/ftrace/BUILD.gn
index 95a476a..e6440af 100644
--- a/src/traced/probes/ftrace/BUILD.gn
+++ b/src/traced/probes/ftrace/BUILD.gn
@@ -15,6 +15,7 @@
 import("../../../../gn/fuzzer.gni")
 import("../../../../gn/perfetto.gni")
 import("../../../../gn/proto_library.gni")
+import("../../../../gn/test.gni")
 
 # For use_libfuzzer.
 if (perfetto_root_path == "//") {
@@ -40,7 +41,7 @@
   ]
 }
 
-source_set("unittests") {
+perfetto_unittest_source_set("unittests") {
   testonly = true
   deps = [
     ":format_parser",
@@ -152,7 +153,7 @@
   ]
 }
 
-if (perfetto_build_standalone) {
+if (enable_perfetto_benchmarks) {
   source_set("benchmarks") {
     testonly = true
     deps = [
diff --git a/src/traced/probes/packages_list/BUILD.gn b/src/traced/probes/packages_list/BUILD.gn
index aa05442..b1092d1 100644
--- a/src/traced/probes/packages_list/BUILD.gn
+++ b/src/traced/probes/packages_list/BUILD.gn
@@ -12,6 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import("../../../../gn/test.gni")
+
 source_set("packages_list") {
   public_deps = [
     "../../../tracing",
@@ -31,7 +33,7 @@
   ]
 }
 
-source_set("unittests") {
+perfetto_unittest_source_set("unittests") {
   testonly = true
   deps = [
     ":packages_list",
diff --git a/src/traced/probes/ps/BUILD.gn b/src/traced/probes/ps/BUILD.gn
index 8fb3a1b..9918cc3 100644
--- a/src/traced/probes/ps/BUILD.gn
+++ b/src/traced/probes/ps/BUILD.gn
@@ -12,6 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import("../../../../gn/test.gni")
+
 source_set("ps") {
   public_deps = [
     "../../../tracing",
@@ -30,7 +32,7 @@
   ]
 }
 
-source_set("unittests") {
+perfetto_unittest_source_set("unittests") {
   testonly = true
   deps = [
     ":ps",
diff --git a/src/traced/probes/sys_stats/BUILD.gn b/src/traced/probes/sys_stats/BUILD.gn
index 15475c6..c7fa58b 100644
--- a/src/traced/probes/sys_stats/BUILD.gn
+++ b/src/traced/probes/sys_stats/BUILD.gn
@@ -12,6 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import("../../../../gn/test.gni")
+
 source_set("sys_stats") {
   public_deps = [
     "../../../tracing",
@@ -32,7 +34,7 @@
   ]
 }
 
-source_set("unittests") {
+perfetto_unittest_source_set("unittests") {
   testonly = true
   deps = [
     ":sys_stats",
diff --git a/src/traced/service/BUILD.gn b/src/traced/service/BUILD.gn
index b583081..d193ab4 100644
--- a/src/traced/service/BUILD.gn
+++ b/src/traced/service/BUILD.gn
@@ -12,6 +12,28 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import("../../../gn/test.gni")
+
+# The unprivileged trace daemon that listens for Producer and Consumer
+# connections, handles the coordination of the tracing sessions and owns the
+# log buffers.
+executable("traced") {
+  deps = [
+    # Both traced and traced_probes depend on "libprefetto" instead of directly
+    # on lib. This is to reduce binary size on android builds. All the code is
+    # built into libperfetto and the executables are just tiny shells that call
+    # into the xxx_main() defined in the library.
+    "../../../:libperfetto",
+    "../../../gn:default_deps",
+    "../../../include/perfetto/ext/traced",
+  ]
+  sources = [
+    "main.cc",
+  ]
+}
+
+# Contains all the implementation but not the main() entry point. This target
+# is shared both by the executable and tests.
 source_set("service") {
   public_deps = [
     "../../../include/perfetto/ext/traced",
@@ -29,7 +51,7 @@
   ]
 }
 
-source_set("unittests") {
+perfetto_unittest_source_set("unittests") {
   testonly = true
   deps = [
     ":service",
diff --git a/src/tracing/BUILD.gn b/src/tracing/BUILD.gn
index e5b98f4..a194748 100644
--- a/src/tracing/BUILD.gn
+++ b/src/tracing/BUILD.gn
@@ -14,6 +14,7 @@
 
 import("//build_overrides/build.gni")
 import("../../gn/perfetto.gni")
+import("../../gn/test.gni")
 
 # Core tracing library, platform independent, no transport layer.
 source_set("tracing") {
@@ -72,61 +73,58 @@
   ]
 }
 
-if (perfetto_build_standalone || perfetto_build_with_android ||
-    build_with_chromium) {
-  source_set("unittests") {
-    testonly = true
-    deps = [
-      ":test_support",
-      ":tracing",
-      "../../gn:default_deps",
-      "../../gn:gtest_and_gmock",
-      "../../protos/perfetto/config:lite",
-      "../../protos/perfetto/trace:lite",
-      "../../protos/perfetto/trace:zero",
-      "../base",
-      "../base:test_support",
-    ]
-    sources = [
-      "core/id_allocator_unittest.cc",
-      "core/null_trace_writer_unittest.cc",
-      "core/packet_stream_validator_unittest.cc",
-      "core/patch_list_unittest.cc",
-      "core/shared_memory_abi_unittest.cc",
-      "core/sliced_protobuf_input_stream_unittest.cc",
-      "core/trace_buffer_unittest.cc",
-      "core/trace_packet_unittest.cc",
-      "test/aligned_buffer_test.cc",
-      "test/aligned_buffer_test.h",
-      "test/fake_packet.cc",
-      "test/fake_packet.h",
-      "test/test_shared_memory.cc",
-      "test/test_shared_memory.h",
-    ]
+perfetto_unittest_source_set("unittests") {
+  testonly = true
+  deps = [
+    ":test_support",
+    ":tracing",
+    "../../gn:default_deps",
+    "../../gn:gtest_and_gmock",
+    "../../protos/perfetto/config:lite",
+    "../../protos/perfetto/trace:lite",
+    "../../protos/perfetto/trace:zero",
+    "../base",
+    "../base:test_support",
+  ]
+  sources = [
+    "core/id_allocator_unittest.cc",
+    "core/null_trace_writer_unittest.cc",
+    "core/packet_stream_validator_unittest.cc",
+    "core/patch_list_unittest.cc",
+    "core/shared_memory_abi_unittest.cc",
+    "core/sliced_protobuf_input_stream_unittest.cc",
+    "core/trace_buffer_unittest.cc",
+    "core/trace_packet_unittest.cc",
+    "test/aligned_buffer_test.cc",
+    "test/aligned_buffer_test.h",
+    "test/fake_packet.cc",
+    "test/fake_packet.h",
+    "test/test_shared_memory.cc",
+    "test/test_shared_memory.h",
+  ]
 
-    if (perfetto_build_with_ipc_layer) {
-      deps += [ ":ipc" ]
-      sources += [
-        "ipc/posix_shared_memory_unittest.cc",
-        "test/tracing_integration_test.cc",
-      ]
-    }
+  if (enable_perfetto_ipc) {
+    deps += [ ":ipc" ]
+    sources += [
+      "ipc/posix_shared_memory_unittest.cc",
+      "test/tracing_integration_test.cc",
+    ]
+  }
 
-    # These tests rely on test_task_runner.h which
-    # has no Windows implementation.
-    if (!is_win) {
-      sources += [
-        "core/shared_memory_arbiter_impl_unittest.cc",
-        "core/startup_trace_writer_unittest.cc",
-        "core/trace_writer_impl_unittest.cc",
-        "core/tracing_service_impl_unittest.cc",
-        "test/fake_producer_endpoint.h",
-        "test/mock_consumer.cc",
-        "test/mock_consumer.h",
-        "test/mock_producer.cc",
-        "test/mock_producer.h",
-      ]
-    }
+  # These tests rely on test_task_runner.h which
+  # has no Windows implementation.
+  if (!is_win) {
+    sources += [
+      "core/shared_memory_arbiter_impl_unittest.cc",
+      "core/startup_trace_writer_unittest.cc",
+      "core/trace_writer_impl_unittest.cc",
+      "core/tracing_service_impl_unittest.cc",
+      "test/fake_producer_endpoint.h",
+      "test/mock_consumer.cc",
+      "test/mock_consumer.h",
+      "test/mock_producer.cc",
+      "test/mock_producer.h",
+    ]
   }
 }
 
@@ -178,7 +176,7 @@
   }
 }
 
-if (perfetto_build_with_ipc_layer) {
+if (enable_perfetto_ipc) {
   # Posix specialization of the tracing library for Linux / Android / Mac.
   # Provides an IPC transport over a UNIX domain socket.
   static_library("ipc") {
@@ -211,38 +209,6 @@
   }
 }
 
-source_set("client_api") {
-  deps = [
-    ":common",
-    "../base",
-    "../tracing",
-  ]
-  public_deps = [
-    "../../gn:default_deps",
-    "../../include/perfetto/tracing",
-  ]
-  sources = [
-    "data_source.cc",
-    "internal/in_process_tracing_backend.cc",
-    "internal/in_process_tracing_backend.h",
-    "internal/tracing_muxer_impl.cc",
-    "platform.cc",
-    "tracing.cc",
-    "track_event.cc",
-    "virtual_destructors.cc",
-  ]
-
-  if (perfetto_build_with_ipc_layer) {
-    # TODO there should be an option to compile this out. This pulls IPC
-    # dependencies and bloats binary size.
-    deps += [ "../tracing:ipc" ]
-    sources += [
-      "internal/system_tracing_backend.cc",
-      "internal/system_tracing_backend.h",
-    ]
-  }
-}
-
 # Separate target because the embedder might not want this (e.g. on Windows).
 if (is_linux || is_mac || is_android) {
   source_set("platform_posix") {
@@ -271,7 +237,37 @@
   ]
 }
 
-if (perfetto_build_standalone || perfetto_build_with_android) {
+source_set("client_api") {
+  deps = [
+    ":common",
+    "../base",
+    "../tracing",
+  ]
+  public_deps = [
+    "../../gn:default_deps",
+    "../../include/perfetto/tracing",
+  ]
+  sources = [
+    "data_source.cc",
+    "internal/in_process_tracing_backend.cc",
+    "internal/in_process_tracing_backend.h",
+    "internal/tracing_muxer_impl.cc",
+    "platform.cc",
+    "tracing.cc",
+    "track_event.cc",
+    "virtual_destructors.cc",
+  ]
+
+  if (enable_perfetto_ipc) {
+    deps += [ "../tracing:ipc" ]
+    sources += [
+      "internal/system_tracing_backend.cc",
+      "internal/system_tracing_backend.h",
+    ]
+  }
+}
+
+if (enable_perfetto_integration_tests) {
   source_set("client_api_integrationtests") {
     testonly = true
     deps = [
diff --git a/src/tracing/core/tracing_service_impl.cc b/src/tracing/core/tracing_service_impl.cc
index 07fe0c5..4596a01 100644
--- a/src/tracing/core/tracing_service_impl.cc
+++ b/src/tracing/core/tracing_service_impl.cc
@@ -2127,8 +2127,7 @@
 }
 
 void TracingServiceImpl::UpdateMemoryGuardrail() {
-#if !PERFETTO_BUILDFLAG(PERFETTO_EMBEDDER_BUILD) && \
-    !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
+#if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
   uint64_t total_buffer_bytes = 0;
 
   // Sum up all the shared memory buffers.
diff --git a/test/BUILD.gn b/test/BUILD.gn
index 399584b..fae46eb 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -146,7 +146,7 @@
   }
 }
 
-if (perfetto_build_standalone) {
+if (enable_perfetto_benchmarks) {
   source_set("end_to_end_benchmarks") {
     testonly = true
     deps = [
@@ -179,4 +179,4 @@
       "benchmark_main.cc",
     ]
   }
-}
+}  # if (enable_perfetto_benchmarks)
diff --git a/test/configs/BUILD.gn b/test/configs/BUILD.gn
index 8c9b2e1..78ece58 100644
--- a/test/configs/BUILD.gn
+++ b/test/configs/BUILD.gn
@@ -14,40 +14,38 @@
 
 import("../../gn/perfetto.gni")
 
-if (perfetto_build_standalone) {
-  action_foreach("configs") {
-    testonly = true
-    script = "$root_out_dir/protoc_helper"
+action_foreach("configs") {
+  testonly = true
+  script = "$root_out_dir/protoc_helper"
 
-    deps = [
-      "../../tools:protoc_helper",
-    ]
+  deps = [
+    "../../tools:protoc_helper",
+  ]
 
-    sources = [
-      "android_log.cfg",
-      "atrace.cfg",
-      "background.cfg",
-      "bad_config.cfg",
-      "camera.cfg",
-      "client_api.cfg",
-      "ftrace.cfg",
-      "ftrace_largebuffer.cfg",
-      "heapprofd.cfg",
-      "long_trace.cfg",
-      "processes.cfg",
-      "summary.cfg",
-      "sys_stats.cfg",
-    ]
+  sources = [
+    "android_log.cfg",
+    "atrace.cfg",
+    "background.cfg",
+    "bad_config.cfg",
+    "camera.cfg",
+    "client_api.cfg",
+    "ftrace.cfg",
+    "ftrace_largebuffer.cfg",
+    "heapprofd.cfg",
+    "long_trace.cfg",
+    "processes.cfg",
+    "summary.cfg",
+    "sys_stats.cfg",
+  ]
 
-    outputs = [
-      "$root_out_dir/{{source_file_part}}.protobuf",
-    ]
+  outputs = [
+    "$root_out_dir/{{source_file_part}}.protobuf",
+  ]
 
-    args = [
-      "encode",
-      "--root=" + rebase_path(perfetto_root_path, ""),
-      "--input={{source}}",
-      "--output={{source_file_part}}.protobuf",
-    ]
-  }
+  args = [
+    "encode",
+    "--root=" + rebase_path(perfetto_root_path, ""),
+    "--input={{source}}",
+    "--output={{source_file_part}}.protobuf",
+  ]
 }
diff --git a/test/end_to_end_shared_memory_fuzzer.cc b/test/end_to_end_shared_memory_fuzzer.cc
index 7f3112b..052f888 100644
--- a/test/end_to_end_shared_memory_fuzzer.cc
+++ b/test/end_to_end_shared_memory_fuzzer.cc
@@ -36,9 +36,6 @@
 
 #include "protos/perfetto/trace/trace_packet.pbzero.h"
 
-namespace perfetto {
-namespace shm_fuzz {
-
 // If we're building on Android and starting the daemons ourselves,
 // create the sockets in a world-writable location.
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
@@ -48,6 +45,10 @@
 #define TEST_PRODUCER_SOCK_NAME ::perfetto::GetProducerSocket()
 #endif
 
+namespace perfetto {
+namespace shm_fuzz {
+namespace {
+
 // Fake producer writing a protozero message of data into shared memory
 // buffer, followed by a sentinel message to signal completion to the
 // consumer.
@@ -84,7 +85,7 @@
         static_cast<BufferID>(source_config.target_buffer()));
     {
       auto packet = trace_writer->NewTracePacket();
-      packet->stream_writer_->WriteBytes(data_, size_);
+      packet->stream_writer_for_testing()->WriteBytes(data_, size_);
     }
     trace_writer->Flush();
 
@@ -164,6 +165,7 @@
   return 0;
 }
 
+}  // namespace
 }  // namespace shm_fuzz
 }  // namespace perfetto
 
diff --git a/test/producer_socket_fuzzer.cc b/test/producer_socket_fuzzer.cc
index cb6dc4f..430b2de 100644
--- a/test/producer_socket_fuzzer.cc
+++ b/test/producer_socket_fuzzer.cc
@@ -21,14 +21,7 @@
 
 namespace perfetto {
 namespace socket_fuzz {
-// If we're building on Android and starting the daemons ourselves,
-// create the sockets in a world-writable location.
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
-    PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
-#define TEST_PRODUCER_SOCK_NAME "/data/local/tmp/traced_producer"
-#else
-#define TEST_PRODUCER_SOCK_NAME ::perfetto::GetProducerSocket()
-#endif
+namespace {
 
 class FakeEventListener : public base::UnixSocket::EventListener {
  public:
@@ -58,8 +51,6 @@
   std::function<void()> data_sent_;
 };
 
-int FuzzSharedMemory(const uint8_t* data, size_t size);
-
 int FuzzSharedMemory(const uint8_t* data, size_t size) {
   if (!data)
     return 0;
@@ -77,6 +68,7 @@
   task_runner.RunUntilCheckpoint("data_sent");
   return 0;
 }
+}  // namespace
 }  // namespace socket_fuzz
 }  // namespace perfetto
 
diff --git a/tools/BUILD.gn b/tools/BUILD.gn
index bba515c..52c34f1 100644
--- a/tools/BUILD.gn
+++ b/tools/BUILD.gn
@@ -12,27 +12,34 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-copy("copy_protoc_helper") {
-  testonly = true
-  sources = [
-    "protoc_helper.py",
-  ]
-  outputs = [
-    "${root_out_dir}/protoc_helper",
-  ]
-}
+import("../gn/perfetto.gni")
 
-group("protoc_helper") {
+# Prevent that this file is accidentally included in embedder builds.
+assert(enable_perfetto_tools)
+
+# Lists all tools. The root "all" target depends on this.
+group("tools") {
   testonly = true
-  public_deps = [
-    ":copy_protoc_helper",
-  ]
   deps = [
-    "../gn:protoc($host_toolchain)",
+    ":idle_alloc",
+    ":protoc_helper",
+    "ftrace_proto_gen",
+    "proto_to_cpp",
+    "protoprofile",
+    "trace_to_text",
+    "trace_to_text:trace_to_text_lite",
   ]
+  if (is_linux || is_android) {
+    deps += [
+      "busy_threads",
+      "cpu_utilization",
+      "dump_ftrace_stats",
+      "skippy",
+    ]
+  }
 }
 
-if (is_linux) {
+if (is_linux && enable_perfetto_heapprofd) {
   executable("profiling_sample_distribution") {
     sources = [
       "profiling_sample_distribution.cc",
@@ -44,3 +51,25 @@
     ]
   }
 }
+
+copy("protoc_helper") {
+  testonly = true
+  deps = [
+    "../gn:protoc($host_toolchain)",
+  ]
+  sources = [
+    "protoc_helper.py",
+  ]
+  outputs = [
+    "${root_out_dir}/protoc_helper",
+  ]
+}
+
+executable("idle_alloc") {
+  deps = [
+    "../gn:default_deps",
+  ]
+  sources = [
+    "idle_alloc.cc",
+  ]
+}
diff --git a/tools/ftrace_proto_gen/BUILD.gn b/tools/ftrace_proto_gen/BUILD.gn
index 9d7dbea..a63d696 100644
--- a/tools/ftrace_proto_gen/BUILD.gn
+++ b/tools/ftrace_proto_gen/BUILD.gn
@@ -12,10 +12,27 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-source_set("unittests") {
+import("../../gn/perfetto_host_executable.gni")
+import("../../gn/test.gni")
+
+perfetto_host_executable("ftrace_proto_gen") {
+  testonly = true
+  sources = [
+    "main.cc",
+  ]
+  deps = [
+    ":lib",
+    "../../gn:default_deps",
+    "../../gn:protobuf_full",
+    "../../src/base",
+    "../../src/traced/probes/ftrace:format_parser",
+  ]
+}
+
+perfetto_unittest_source_set("unittests") {
   testonly = true
   deps = [
-    ":ftrace_proto_gen_src",
+    ":lib",
     "../../gn:default_deps",
     "../../gn:gtest_and_gmock",
     "../../gn:protobuf_full",
@@ -25,7 +42,7 @@
   ]
 }
 
-source_set("ftrace_proto_gen_src") {
+source_set("lib") {
   testonly = true
   sources = [
     "ftrace_descriptor_gen.cc",
@@ -42,17 +59,3 @@
     "../../src/traced/probes/ftrace:format_parser",
   ]
 }
-
-executable("ftrace_proto_gen") {
-  testonly = true
-  sources = [
-    "main.cc",
-  ]
-  deps = [
-    ":ftrace_proto_gen_src",
-    "../../gn:default_deps",
-    "../../gn:protobuf_full",
-    "../../src/base",
-    "../../src/traced/probes/ftrace:format_parser",
-  ]
-}
diff --git a/tools/gen_android_bp b/tools/gen_android_bp
index aed5755..ef6bc40 100755
--- a/tools/gen_android_bp
+++ b/tools/gen_android_bp
@@ -33,43 +33,6 @@
 
 import gn_utils
 
-# Default targets to translate to the blueprint file.
-default_targets = [
-    '//:libperfetto',
-    '//:libperfetto_client_experimental',
-    '//:libperfetto_android_internal',
-    '//:perfetto_integrationtests',
-    '//:perfetto_trace_protos',
-    '//:perfetto_unittests',
-    '//:perfetto',
-    '//:trace_processor_shell',
-    '//:traced',
-    '//:traced_probes',
-    '//:trace_to_text',
-    '//:heapprofd_client',
-    '//:heapprofd',
-    '//:trigger_perfetto',
-]
-
-# Targets which are testonly but should still be a cc_binary.
-non_test_binaries = [
-    '//:trace_processor_shell',
-]
-
-# Defines a custom init_rc argument to be applied to the corresponding output
-# blueprint target.
-target_initrc = {
-    '//:traced': 'perfetto.rc',
-    '//:heapprofd': 'heapprofd.rc',
-}
-
-target_host_supported = [
-    '//:perfetto_trace_protos',
-]
-
-target_host_only = [
-    '//:trace_to_text',
-]
 
 # Arguments for the GN output directory.
 gn_args = ' '.join([
@@ -80,6 +43,44 @@
     'target_os="android"',
 ])
 
+# Default targets to translate to the blueprint file.
+default_targets = [
+    '//:libperfetto_client_experimental',
+    '//:libperfetto',
+    '//:perfetto_integrationtests',
+    '//:perfetto_unittests',
+    '//protos/perfetto/trace:perfetto_trace_protos',
+    '//src/android_internal:libperfetto_android_internal',
+    '//src/perfetto_cmd:perfetto',
+    '//src/perfetto_cmd:trigger_perfetto',
+    '//src/profiling/memory:heapprofd_client',
+    '//src/profiling/memory:heapprofd',
+    '//src/trace_processor:trace_processor_shell',
+    '//src/traced/probes:traced_probes',
+    '//src/traced/service:traced',
+    '//tools/trace_to_text:trace_to_text',
+]
+
+# Targets which are testonly but should still be a cc_binary.
+non_test_binaries = [
+    '//src/trace_processor:trace_processor_shell',
+]
+
+# Defines a custom init_rc argument to be applied to the corresponding output
+# blueprint target.
+target_initrc = {
+    '//src/traced/service:traced': 'perfetto.rc',
+    '//src/profiling/memory:heapprofd': 'heapprofd.rc',
+}
+
+target_host_supported = [
+    '//protos/perfetto/trace:perfetto_trace_protos',
+]
+
+target_host_only = [
+    '//tools/trace_to_text:trace_to_text',
+]
+
 # All module names are prefixed with this string to avoid collisions.
 module_prefix = 'perfetto_'
 
@@ -372,6 +373,12 @@
 
 def label_to_module_name(label):
     """Turn a GN label (e.g., //:perfetto_tests) into a module name."""
+    # If the label is explicibly listed in the default target list, don't prefix
+    # its name and return just the target name. This is so tools like
+    # "trace_to_text" stay as such in the Android tree.
+    if label in default_targets:
+        return label.split(':')[-1]
+
     module = re.sub(r'^//:?', '', label)
     module = re.sub(r'[^a-zA-Z0-9_]', '_', module)
     if not module.startswith(module_prefix) and label not in default_targets:
diff --git a/tools/gen_bazel b/tools/gen_bazel
index b8f3798..3578fba 100755
--- a/tools/gen_bazel
+++ b/tools/gen_bazel
@@ -63,24 +63,17 @@
 
 # Default targets to translate to the blueprint file.
 default_targets = [
-  '//:trace_processor_shell',
+  '//src/trace_processor:trace_processor_shell',
   '//src/protozero:libprotozero',
   '//src/trace_processor:trace_processor',
-  '//tools/trace_to_text:trace_to_text_host(//gn/standalone/toolchain:gcc_like_host)',
+  '//tools/trace_to_text:trace_to_text',
   '//tools/trace_to_text:libpprofbuilder',
   '//protos/perfetto/config:merged_config_gen',
   '//protos/perfetto/trace:merged_trace_gen',
   '//protos/perfetto/trace_processor:lite_gen',
-  '//protos/perfetto/metrics:lite_gen'
+  '//protos/perfetto/metrics:lite_gen',
 ]
 
-# Aliases to add to the BUILD file.
-alias_targets = {
-  '//src/protozero:libprotozero': 'libprotozero',
-  '//src/trace_processor:trace_processor': 'trace_processor',
-  '//tools/trace_to_text:trace_to_text_host': 'trace_to_text',
-}
-
 # The directory where the generated perfetto_build_flags.h will be copied into.
 buildflags_dir = 'include/perfetto/base/build_configs/bazel'
 
@@ -596,7 +589,10 @@
 
     label_no_toolchain = gn_utils.label_without_toolchain(gn_target_name)
     target_name_path = gn_utils.label_to_target_name_with_path(label_no_toolchain)
-    target_name = alias_targets.get(label_no_toolchain, target_name_path)
+    if label_no_toolchain in default_targets:
+        target_name = label_no_toolchain.split(':')[-1]
+    else:
+      target_name = target_name_path
     target = Target(target_type, target_name, gn_name=label_no_toolchain)
     target.srcs.update(
         Label(gn_utils.label_to_path(src))
diff --git a/tools/proto_to_cpp/BUILD.gn b/tools/proto_to_cpp/BUILD.gn
index 3515e77..aaa7c7e 100644
--- a/tools/proto_to_cpp/BUILD.gn
+++ b/tools/proto_to_cpp/BUILD.gn
@@ -12,31 +12,16 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-if (current_toolchain == host_toolchain) {
-  executable("proto_to_cpp_host") {
-    testonly = true
-    deps = [
-      "../../gn:default_deps",
-      "../../gn:protobuf_full",
-      "../../src/base",
-    ]
-    sources = [
-      "proto_to_cpp.cc",
-    ]
-  }
-}
+import("../../gn/perfetto_host_executable.gni")
 
-copy("proto_to_cpp") {
+perfetto_host_executable("proto_to_cpp") {
   testonly = true
-  host_out_dir_ =
-      get_label_info(":proto_to_cpp_host($host_toolchain)", "root_out_dir")
   deps = [
-    ":proto_to_cpp_host($host_toolchain)",
+    "../../gn:default_deps",
+    "../../gn:protobuf_full",
+    "../../src/base",
   ]
   sources = [
-    "${host_out_dir_}/proto_to_cpp_host",
-  ]
-  outputs = [
-    "${root_out_dir}/proto_to_cpp",
+    "proto_to_cpp.cc",
   ]
 }
diff --git a/tools/protoprofile/BUILD.gn b/tools/protoprofile/BUILD.gn
index 7c3f83f..fe31432 100644
--- a/tools/protoprofile/BUILD.gn
+++ b/tools/protoprofile/BUILD.gn
@@ -12,8 +12,15 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import("../../gn/perfetto.gni")
-import("../../gn/proto_library.gni")
+import("../../gn/perfetto_host_executable.gni")
+
+perfetto_host_executable("protoprofile") {
+  testonly = true
+  deps = [
+    ":common",
+    "../../gn:default_deps",
+  ]
+}
 
 source_set("common") {
   testonly = true
@@ -30,11 +37,3 @@
     "../../gn:protobuf_full",
   ]
 }
-
-executable("protoprofile") {
-  testonly = true
-  deps = [
-    ":common",
-    "../../gn:default_deps",
-  ]
-}
diff --git a/tools/trace_to_text/BUILD.gn b/tools/trace_to_text/BUILD.gn
index e2bfb14..5cd2e36 100644
--- a/tools/trace_to_text/BUILD.gn
+++ b/tools/trace_to_text/BUILD.gn
@@ -13,9 +13,29 @@
 # limitations under the License.
 
 import("../../gn/perfetto.gni")
-import("../../gn/proto_library.gni")
+import("../../gn/perfetto_host_executable.gni")
 import("../../gn/wasm.gni")
 
+perfetto_host_executable("trace_to_text") {
+  testonly = true
+  deps = [
+    ":full",
+    "../../gn:default_deps",
+  ]
+}
+
+# This is just to check that we can build a version of trace_to_text against
+# libprotobuf-lite. This configuration is only used by WASM. Unfortunately,
+# however, the WASM linker is very permissive and failures show up only when
+# loading the executable in the browser.
+perfetto_host_executable("trace_to_text_lite") {
+  testonly = true
+  deps = [
+    ":lite",
+    "../../gn:default_deps",
+  ]
+}
+
 source_set("utils") {
   public_deps = [
     "../../gn:default_deps",
@@ -91,12 +111,12 @@
   ]
 }
 
-if (perfetto_build_standalone) {
-  static_library("libpprofbuilder") {
-    deps = [
-      ":pprofbuilder",
-    ]
-  }
+# Exposed in bazel builds.
+static_library("libpprofbuilder") {
+  complete_static_lib = true
+  deps = [
+    ":pprofbuilder",
+  ]
 }
 
 # The core source files that are used both by the "full" version (the host
@@ -136,8 +156,8 @@
   } else {
     defines += [ "PERFETTO_NOLOCALSYMBOLIZE" ]
   }
-  if (perfetto_build_standalone) {
-    deps += [ "../../gn/standalone:gen_git_revision" ]
+  if (enable_perfetto_version_gen) {
+    deps += [ "//gn/standalone:gen_git_revision" ]
   }
 }
 
@@ -168,25 +188,6 @@
   ]
 }
 
-if (current_toolchain == host_toolchain) {
-  executable("trace_to_text_host") {
-    testonly = true
-    deps = [
-      ":full",
-      "../../gn:default_deps",
-    ]
-  }
-
-  # WASM is too permissive, build a normal version of the binary to test for
-  # missing symbols.
-  executable("trace_to_text_lite_host") {
-    deps = [
-      ":lite",
-      "../../gn:default_deps",
-    ]
-  }
-}
-
 wasm_lib("trace_to_text_wasm") {
   name = "trace_to_text"
   deps = [
@@ -194,21 +195,3 @@
     "../../gn:default_deps",
   ]
 }
-
-# The one for the android tree is defined in the top-level BUILD.gn.
-if (!perfetto_build_with_android) {
-  copy("trace_to_text") {
-    testonly = true
-    host_out_dir_ =
-        get_label_info(":trace_to_text_host($host_toolchain)", "root_out_dir")
-    deps = [
-      ":trace_to_text_host($host_toolchain)",
-    ]
-    sources = [
-      "${host_out_dir_}/trace_to_text_host",
-    ]
-    outputs = [
-      "${root_out_dir}/trace_to_text",
-    ]
-  }
-}
diff --git a/tools/trace_to_text/main.cc b/tools/trace_to_text/main.cc
index d098e45..225bf70 100644
--- a/tools/trace_to_text/main.cc
+++ b/tools/trace_to_text/main.cc
@@ -25,7 +25,7 @@
 #include "tools/trace_to_text/trace_to_text.h"
 #include "tools/trace_to_text/symbolize_profile.h"
 
-#if PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD)
+#if PERFETTO_BUILDFLAG(PERFETTO_VERSION_GEN)
 #include "perfetto_version.gen.h"
 #else
 #define PERFETTO_GET_GIT_REVISION() "unknown"
diff --git a/ui/BUILD.gn b/ui/BUILD.gn
index 20ad749..5c0a988 100644
--- a/ui/BUILD.gn
+++ b/ui/BUILD.gn
@@ -16,6 +16,9 @@
 import("../gn/wasm.gni")
 import("../protos/perfetto/trace_processor/proto_files.gni")
 
+# Prevent that this file is accidentally included in embedder builds.
+assert(enable_perfetto_ui)
+
 ui_dir = "$root_build_dir/ui"
 chrome_extension_dir = "$root_build_dir/chrome_extension"
 ui_gen_dir = "$target_out_dir/gen"