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/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