Move build flags to generated file, stop using cflags

Design doc: go/perfetto-buildflags
Stop passing -DPERFETTO_XXX to cc invocations.
In GN builds, use a perfetto_build_flags.h file generated
at build-time via genrule. For Android, Blaze/Bazel and
amalgamated builds, generate the header when running
tools/gen_xxx, check it into build_configs/xxx/,
point include_dirs that directory in each build system.
This CL also cleans up some GN files that were using
build_with_embedder for the wrong purposes (to check
whether we should use //gn/standalone or the
embedder-provided GN files). The amalgamated build needs
embedder=true but uses standalone GN.

Test: manually tested the following:
  - tools/gen_amalgamated: builds
  - manual chrome roll (linux): builds
  - manual v8 roll (mac): builds

Bug: 132678367
Change-Id: I79aa98d9b08090586c8d23c6fdafe88168ca63a2
diff --git a/Android.bp b/Android.bp
index a77d471..83ca36b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -215,7 +215,6 @@
   cflags: [
     "-DGOOGLE_PROTOBUF_NO_RTTI",
     "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
-    "-DPERFETTO_BUILD_WITH_ANDROID",
   ],
 }
 
@@ -256,12 +255,15 @@
   static_libs: [
     "libasync_safe",
   ],
+  export_include_dirs: [
+    "include",
+    "include/perfetto/base/build_configs/android_tree",
+  ],
   defaults: [
     "perfetto_defaults",
   ],
   cflags: [
     "-DPERFETTO_ANDROID_ASYNC_SAFE_LOG",
-    "-DPERFETTO_BUILD_WITH_ANDROID",
   ],
   include_dirs: [
     "bionic/libc",
@@ -406,6 +408,10 @@
   static_libs: [
     "perfetto_src_tracing_ipc",
   ],
+  export_include_dirs: [
+    "include",
+    "include/perfetto/base/build_configs/android_tree",
+  ],
   generated_headers: [
     "perfetto_protos_perfetto_common_lite_gen_headers",
     "perfetto_protos_perfetto_common_zero_gen_headers",
@@ -451,7 +457,6 @@
   cflags: [
     "-DGOOGLE_PROTOBUF_NO_RTTI",
     "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
-    "-DPERFETTO_BUILD_WITH_ANDROID",
   ],
 }
 
@@ -480,12 +485,13 @@
   static_libs: [
     "libhealthhalutils",
   ],
+  export_include_dirs: [
+    "include",
+    "include/perfetto/base/build_configs/android_tree",
+  ],
   defaults: [
     "perfetto_defaults",
   ],
-  cflags: [
-    "-DPERFETTO_BUILD_WITH_ANDROID",
-  ],
   product_variables: {
     pdk: {
       enabled: false,
@@ -606,6 +612,7 @@
   ],
   export_include_dirs: [
     "include",
+    "include/perfetto/base/build_configs/android_tree",
   ],
   generated_headers: [
     "perfetto_protos_perfetto_common_lite_gen_headers",
@@ -691,7 +698,6 @@
   cflags: [
     "-DGOOGLE_PROTOBUF_NO_RTTI",
     "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
-    "-DPERFETTO_BUILD_WITH_ANDROID",
   ],
 }
 
@@ -856,7 +862,6 @@
     "-DGOOGLE_PROTOBUF_NO_RTTI",
     "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
     "-DHAVE_HIDDEN",
-    "-DPERFETTO_BUILD_WITH_ANDROID",
   ],
 }
 
@@ -870,8 +875,10 @@
     "-Wno-unused-parameter",
     "-fvisibility=hidden",
   ],
-  local_include_dirs: [
-    "include",
+  include_dirs: [
+    "external/perfetto",
+    "external/perfetto/include",
+    "external/perfetto/include/perfetto/base/build_configs/android_tree",
   ],
   product_variables: {
     debuggable: {
@@ -1132,7 +1139,6 @@
   cflags: [
     "-DGOOGLE_PROTOBUF_NO_RTTI",
     "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
-    "-DPERFETTO_BUILD_WITH_ANDROID",
   ],
 }
 
@@ -3526,7 +3532,6 @@
   cflags: [
     "-DGOOGLE_PROTOBUF_NO_RTTI",
     "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
-    "-DPERFETTO_BUILD_WITH_ANDROID",
   ],
 }
 
@@ -3660,7 +3665,6 @@
   cflags: [
     "-DGOOGLE_PROTOBUF_NO_RTTI",
     "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
-    "-DPERFETTO_BUILD_WITH_ANDROID",
   ],
 }
 
@@ -3932,6 +3936,7 @@
   ],
   export_include_dirs: [
     "include",
+    "include/perfetto/base/build_configs/android_tree",
   ],
   generated_headers: [
     "perfetto_protos_perfetto_common_lite_gen_headers",
@@ -4017,7 +4022,6 @@
   cflags: [
     "-DGOOGLE_PROTOBUF_NO_RTTI",
     "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
-    "-DPERFETTO_BUILD_WITH_ANDROID",
   ],
 }
 
@@ -4056,6 +4060,7 @@
   host_supported: true,
   export_include_dirs: [
     "include",
+    "include/perfetto/base/build_configs/android_tree",
   ],
   generated_headers: [
     "perfetto_protos_perfetto_common_lite_gen_headers",
@@ -4461,7 +4466,6 @@
     "-DGOOGLE_PROTOBUF_NO_RTTI",
     "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
     "-DHAVE_HIDDEN",
-    "-DPERFETTO_BUILD_WITH_ANDROID",
   ],
 }
 
@@ -4623,7 +4627,6 @@
     "-DGOOGLE_PROTOBUF_NO_RTTI",
     "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
     "-DHAVE_HIDDEN",
-    "-DPERFETTO_BUILD_WITH_ANDROID",
   ],
   target: {
     android: {
@@ -4865,7 +4868,6 @@
     "-DGOOGLE_PROTOBUF_NO_RTTI",
     "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
     "-DHAVE_HIDDEN",
-    "-DPERFETTO_BUILD_WITH_ANDROID",
   ],
 }
 
@@ -4885,9 +4887,6 @@
   defaults: [
     "perfetto_defaults",
   ],
-  cflags: [
-    "-DPERFETTO_BUILD_WITH_ANDROID",
-  ],
 }
 
 // GN target: //:traced_probes
@@ -4903,9 +4902,6 @@
   defaults: [
     "perfetto_defaults",
   ],
-  cflags: [
-    "-DPERFETTO_BUILD_WITH_ANDROID",
-  ],
   required: [
     "libperfetto_android_internal",
     "trigger_perfetto",
@@ -5065,7 +5061,6 @@
   cflags: [
     "-DGOOGLE_PROTOBUF_NO_RTTI",
     "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
-    "-DPERFETTO_BUILD_WITH_ANDROID",
   ],
 }
 
@@ -5087,9 +5082,6 @@
     "test/task_runner_thread_delegates.cc",
     "test/test_helper.cc",
   ],
-  export_include_dirs: [
-    ".",
-  ],
   shared_libs: [
     "libprotobuf-cpp-lite",
   ],
@@ -5099,8 +5091,8 @@
     "perfetto_src_tracing_ipc",
     "perfetto_trace_protos",
   ],
-  cflags: [
-    "-DPERFETTO_BUILD_WITH_ANDROID",
+  defaults: [
+    "perfetto_defaults",
   ],
 }
 
@@ -5114,15 +5106,12 @@
   shared_libs: [
     "libprotobuf-cpp-lite",
   ],
-  export_include_dirs: [
-    ".",
-  ],
   static_libs: [
     "libgtest",
     "perfetto_src_tracing_ipc",
   ],
-  cflags: [
-    "-DPERFETTO_BUILD_WITH_ANDROID",
+  defaults: [
+    "perfetto_defaults",
   ],
 }
 
@@ -5152,12 +5141,11 @@
     "libprotobuf-cpp-lite",
     "liblog",
   ],
-  local_include_dirs: [
-    "include",
-  ],
   cflags: [
     "-DGOOGLE_PROTOBUF_NO_RTTI",
     "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
-    "-DPERFETTO_BUILD_WITH_ANDROID",
+  ],
+  defaults: [
+    "perfetto_defaults",
   ],
 }
\ No newline at end of file
diff --git a/Android.bp.extras b/Android.bp.extras
index 1defc2e..354c97a 100644
--- a/Android.bp.extras
+++ b/Android.bp.extras
@@ -16,9 +16,6 @@
     "test/task_runner_thread_delegates.cc",
     "test/test_helper.cc",
   ],
-  export_include_dirs: [
-    ".",
-  ],
   shared_libs: [
     "libprotobuf-cpp-lite",
   ],
@@ -28,8 +25,8 @@
     "perfetto_src_tracing_ipc",
     "perfetto_trace_protos",
   ],
-  cflags: [
-    "-DPERFETTO_BUILD_WITH_ANDROID",
+  defaults: [
+    "perfetto_defaults",
   ],
 }
 
@@ -43,15 +40,12 @@
   shared_libs: [
     "libprotobuf-cpp-lite",
   ],
-  export_include_dirs: [
-    ".",
-  ],
   static_libs: [
     "libgtest",
     "perfetto_src_tracing_ipc",
   ],
-  cflags: [
-    "-DPERFETTO_BUILD_WITH_ANDROID",
+  defaults: [
+    "perfetto_defaults",
   ],
 }
 
@@ -81,12 +75,11 @@
     "libprotobuf-cpp-lite",
     "liblog",
   ],
-  local_include_dirs: [
-    "include",
-  ],
   cflags: [
     "-DGOOGLE_PROTOBUF_NO_RTTI",
     "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
-    "-DPERFETTO_BUILD_WITH_ANDROID",
+  ],
+  defaults: [
+    "perfetto_defaults",
   ],
 }
diff --git a/gn/BUILD.gn b/gn/BUILD.gn
index 3bc618a..1bc618e 100644
--- a/gn/BUILD.gn
+++ b/gn/BUILD.gn
@@ -21,10 +21,62 @@
   import("//build/config/sanitizers/sanitizers.gni")
 }
 
+# Genereates a header files that contains a macro definition for each build flag
+# that is required by the codebase. This is to avoid sprinkling cflags all over
+# the places, which is very fragile especially for our codebase that needs to
+# 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)
+# - 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)
+buildflag_gen_dir_ = "$root_gen_dir/$perfetto_root_path/build_config"
+action("gen_buildflags") {
+  script = "write_buildflag_header.py"
+  gen_header_path = "$buildflag_gen_dir_/perfetto_build_flags.h"
+
+  perfetto_component_build = false
+  if (defined(is_component_build) && is_component_build) {
+    perfetto_component_build = true
+  }
+  perfetto_force_dlog_on = perfetto_force_dlog == "on"
+  perfetto_force_dlog_off = perfetto_force_dlog == "off"
+
+  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_COMPONENT_BUILD=$perfetto_component_build",
+    "PERFETTO_FORCE_DLOG_ON=$perfetto_force_dlog_on",
+    "PERFETTO_FORCE_DLOG_OFF=$perfetto_force_dlog_off",
+  ]
+
+  rel_out_path = rebase_path(gen_header_path, "$root_build_dir")
+  args = [
+    "--out",
+    rel_out_path,
+    "--rsp",
+    "{{response_file_name}}",
+  ]
+
+  outputs = [
+    gen_header_path,
+  ]
+}
+
 # All targets should depend on this target to inherit the right flags and
 # include directories.
 group("default_deps") {
   public_configs = [ ":default_config" ]
+  deps = [
+    ":gen_buildflags",
+  ]
   if (perfetto_build_standalone) {
     public_deps = [
       "//gn/standalone/libc++:deps",
@@ -54,36 +106,13 @@
   include_dirs = [
     "../include",
 
+    # For perfetto_build_flags.h
+    buildflag_gen_dir_,
+
     # The below are needed due to generated protobuf headers including other
     # headers with a path relative to the perfetto root.
     "${root_gen_dir}/${perfetto_root_path}/protos",
   ]
-
-  defines = []
-
-  if (perfetto_build_with_android) {
-    defines += [ "PERFETTO_BUILD_WITH_ANDROID" ]
-  } else if (perfetto_build_with_embedder) {
-    defines += [ "PERFETTO_BUILD_WITH_EMBEDDER" ]
-
-    if (build_with_chromium) {
-      defines += [ "PERFETTO_BUILD_WITH_CHROMIUM" ]
-    }  # if (build_with_chromium)
-
-    if (defined(is_component_build) && is_component_build) {
-      defines += [ "PERFETTO_BUILD_AS_COMPONENT" ]
-    }  # if (is_component_build)
-  }  # if (build_with_embedder)
-
-  if (perfetto_force_dlog == "on") {
-    defines += [ "PERFETTO_FORCE_DLOG=1" ]
-  } else if (perfetto_force_dlog == "off") {
-    defines += [ "PERFETTO_FORCE_DLOG=0" ]
-  }
-
-  if (perfetto_build_with_ipc_layer) {
-    defines += [ "PERFETTO_BUILD_IPC" ]
-  }
 }
 
 config("asan_instrumentation") {
diff --git a/gn/write_buildflag_header.py b/gn/write_buildflag_header.py
new file mode 100644
index 0000000..e9ef32e
--- /dev/null
+++ b/gn/write_buildflag_header.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+# 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.
+
+# This writes headers for build flags. See the gen_buildflags target in
+# /gn/BUILD.gn for usage.
+#
+# The parameters are passed in a response file so we don't have to worry
+# about command line lengths. The name of the response file is passed on the
+# command line.
+#
+# The format of the response file is:
+#    [--flags <list of one or more flag values>]
+
+import argparse
+import os
+import shlex
+import sys
+
+def main():
+  parser = argparse.ArgumentParser()
+  parser.add_argument('--rsp', help='Input response file containing the flags.')
+  parser.add_argument('--out', help='Output path of the generated header file.')
+  args = parser.parse_args()
+
+  flags = []
+  with open(args.rsp, 'r') as def_file:
+    marker_seen = False
+    for flag in shlex.split(def_file.read()):
+      if not marker_seen:
+        marker_seen = flag == '--flags'
+        continue
+      key, value = flag.split('=', 1)
+      value = '1' if value == 'true' else '0' if value == 'false' else value
+      flags.append((key, value))
+
+  guard = '%s_' % args.out.upper()
+  guard = guard.replace('/', '_').replace('\\', '_').replace('.', '_')
+  tmp_out = args.out + '.tmp'
+  with open(tmp_out, 'w') as out:
+    out.write('// Generated by %s\n\n' % __file__)
+    out.write('// fix_include_guards: off\n')
+    out.write('#ifndef %s\n' % guard)
+    out.write('#define %s\n\n' % guard)
+    for kv in flags:
+      out.write('#define PERFETTO_BUILDFLAG_DEFINE_%s() (%s)\n' % kv)
+    out.write('\n#endif  // %s\n' % guard)
+  os.rename(tmp_out, args.out)
+
+if __name__ == '__main__':
+  sys.exit(main())
+
diff --git a/include/perfetto/base/build_config.h b/include/perfetto/base/build_config.h
index e02bea1..0ed2cb2 100644
--- a/include/perfetto/base/build_config.h
+++ b/include/perfetto/base/build_config.h
@@ -17,6 +17,18 @@
 #ifndef INCLUDE_PERFETTO_BASE_BUILD_CONFIG_H_
 #define INCLUDE_PERFETTO_BASE_BUILD_CONFIG_H_
 
+// perfetto_build_flags.h contains the tweakable build flags defined via GN.
+// - In GN builds (e.g., standalone, chromium, v8) this file is generated at
+//   build time via the gen_rule //gn/gen_buildflags.
+// - In Android in-tree builds, this file is generated by tools/gen_android_bp
+//   and checked in into include/perfetto/base/build_configs/android_tree/. The
+//   default cflags add this path to the default include path.
+// - Similarly, in bazel builds, this file is generated by tools/gen_bazel and
+//   checked in into include/perfetto/base/build_configs/bazel/.
+// - In amaglamated builds, this file is generated by tools/gen_amalgamated and
+//   added to the amalgamated headers.
+#include "perfetto_build_flags.h"  // no-include-violation-check
+
 // Allows to define build flags that give a compiler error if the header that
 // defined the flag is not included, instead of silently ignoring the #if block.
 #define PERFETTO_BUILDFLAG_CAT_INDIRECT(a, b) a##b
@@ -88,75 +100,10 @@
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_MSVC() 0
 #endif
 
-// TODO(primiano): remove all the defines below that depend on GN variables
-// (as opposite to builtin defines coming from the compiler/sysroot). They
-// should be moved to a generated header file, using the same pattern of
-// chromium's buildflag_header.
-
-#if defined(PERFETTO_BUILD_WITH_ANDROID)
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_BUILD() 1
-#else
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_BUILD() 0
-#endif
-
-#if defined(PERFETTO_BUILD_WITH_EMBEDDER)
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_EMBEDDER_BUILD() 1
-#else
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_EMBEDDER_BUILD() 0
-#endif
-
-#if defined(PERFETTO_BUILD_WITH_CHROMIUM)
-#if !defined(PERFETTO_BUILD_WITH_EMBEDDER)
-#error PERFETTO_BUILD_WITH_EMBEDDER must be defined when \
-       PERFETTO_BUILD_WITH_CHROMIUM is defined
-#endif
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_CHROMIUM_BUILD() 1
-#else
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_CHROMIUM_BUILD() 0
-#endif
-
-#if !defined(PERFETTO_BUILD_WITH_EMBEDDER) && \
-    !defined(PERFETTO_BUILD_WITH_ANDROID)
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_STANDALONE_BUILD() 1
-#else
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_STANDALONE_BUILD() 0
-#endif
-
-#if defined(PERFETTO_START_DAEMONS_FOR_TESTING)
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_START_DAEMONS() 1
-#else
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_START_DAEMONS() 0
-#endif
-
 #if defined(PERFETTO_BUILD_WITH_ANDROID_USERDEBUG)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_USERDEBUG_BUILD() 1
 #else
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_USERDEBUG_BUILD() 0
 #endif
 
-#if defined(PERFETTO_BUILD_IPC)
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_IPC() 1
-#else
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_IPC() 0
-#endif
-
-#if defined(PERFETTO_BUILD_AS_COMPONENT)
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPONENT_BUILD() 1
-#else
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPONENT_BUILD() 0
-#endif
-
-#if defined(PERFETTO_FORCE_DLOG)
-#if PERFETTO_FORCE_DLOG
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_ON() 1
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_OFF() 0
-#else
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_ON() 0
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_OFF() 1
-#endif
-#else  // defined(PERFETTO_FORCE_DLOG)
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_ON() 0
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_OFF() 0
-#endif
-
 #endif  // INCLUDE_PERFETTO_BASE_BUILD_CONFIG_H_
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
new file mode 100644
index 0000000..ce2a9f3
--- /dev/null
+++ b/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h
@@ -0,0 +1,17 @@
+// Generated by ../../gn/write_buildflag_header.py
+
+// fix_include_guards: off
+#ifndef GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
+#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_COMPONENT_BUILD() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_ON() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_OFF() (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
new file mode 100644
index 0000000..770d1c6
--- /dev/null
+++ b/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
@@ -0,0 +1,17 @@
+// Generated by ../../gn/write_buildflag_header.py
+
+// fix_include_guards: off
+#ifndef GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
+#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_COMPONENT_BUILD() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_ON() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_OFF() (0)
+
+#endif  // GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
diff --git a/test/cts/Android.bp b/test/cts/Android.bp
index 6340440..c7cee36 100644
--- a/test/cts/Android.bp
+++ b/test/cts/Android.bp
@@ -33,7 +33,7 @@
     },
   },
   stl: "libc++_static",
-  cflags: [
-    "-DPERFETTO_BUILD_WITH_ANDROID",
+  defaults: [
+    "perfetto_defaults",
   ],
 }
diff --git a/test/cts/heapprofd_test_apps/jni/Android.bp b/test/cts/heapprofd_test_apps/jni/Android.bp
index a518779..de090d2 100644
--- a/test/cts/heapprofd_test_apps/jni/Android.bp
+++ b/test/cts/heapprofd_test_apps/jni/Android.bp
@@ -28,4 +28,7 @@
   ],
   compile_multilib: "both",
   stl: "libc++_static",
+  defaults: [
+    "perfetto_defaults",
+  ],
 }
diff --git a/test/cts/producer/jni/Android.bp b/test/cts/producer/jni/Android.bp
index aae7201..939a37b 100644
--- a/test/cts/producer/jni/Android.bp
+++ b/test/cts/producer/jni/Android.bp
@@ -16,7 +16,7 @@
   ],
   compile_multilib: "both",
   stl: "libc++_static",
-  cflags: [
-    "-DPERFETTO_BUILD_WITH_ANDROID",
+  defaults: [
+    "perfetto_defaults",
   ],
 }
diff --git a/tools/gen_android_bp b/tools/gen_android_bp
index 2d57628..b07568c 100755
--- a/tools/gen_android_bp
+++ b/tools/gen_android_bp
@@ -111,7 +111,7 @@
 cflag_whitelist = r'^-DPERFETTO.*$'
 
 # Compiler defines which are passed through to the blueprint.
-define_whitelist = r'^(GOOGLE_PROTO.*)|(PERFETTO_BUILD_WITH_ANDROID)|(ZLIB_.*)|(USE_MMAP)|(HAVE_HIDDEN)$'
+define_whitelist = r'^(GOOGLE_PROTO.*)|(ZLIB_.*)|(USE_MMAP)|(HAVE_HIDDEN)$'
 
 # Shared libraries which are not in PDK.
 library_not_in_pdk = {
@@ -119,6 +119,9 @@
     'libservices',
 }
 
+# The directory where the generated perfetto_build_flags.h will be copied into.
+buildflags_dir = 'include/perfetto/base/build_configs/android_tree'
+
 # Additional arguments to apply to Android.bp rules.
 additional_args = {
     'heapprofd_client': [
@@ -133,7 +136,6 @@
     ],
 }
 
-
 def enable_gmock(module):
     module.static_libs.append('libgmock')
 
@@ -429,6 +431,11 @@
         if "gen_merged_sql_metrics" in dep_name:
           dep_mod = create_merged_sql_metrics_target(blueprint, desc, dep_name)
           module.generated_headers.append(dep_mod.name)
+        elif dep_name.startswith(gn_utils.BUILDFLAGS_TARGET):
+            # Ignore the dependency on the gen_buildflags genrule. That is run
+            # separately in this generator and the generated file is copied over
+            # into the repo (see usage of |buildflags_dir| in this script).
+            return
         else:
           create_modules_from_target(blueprint, desc, dep_name)
           # Depend both on the generated sources and headers -- see
@@ -619,6 +626,7 @@
         target_name: GN target for module generation.
     """
     target = desc[target_name]
+    export_include_dirs = [ 'include', buildflags_dir ]
     if target['type'] == 'executable':
         if 'host' in target['toolchain'] or target_name in target_host_only:
             module_type = 'cc_binary_host'
@@ -631,12 +639,12 @@
         modules = make_genrules_for_action(blueprint, desc, target_name)
     elif target['type'] == 'static_library':
         module = Module('cc_library_static', label_to_module_name(target_name))
-        module.export_include_dirs = ['include']
+        module.export_include_dirs = export_include_dirs
         modules = [module]
     elif target['type'] == 'shared_library':
-        modules = [
-            Module('cc_library_shared', label_to_module_name(target_name))
-        ]
+        module = Module('cc_library_shared', label_to_module_name(target_name))
+        module.export_include_dirs = export_include_dirs
+        modules = [module]
     else:
         raise Error('Unknown target type: %s' % target['type'])
 
@@ -705,7 +713,15 @@
 
     # Default settings used by all modules.
     defaults = Module('cc_defaults', defaults_module)
-    defaults.local_include_dirs = ['include']
+
+    # We have to use include_dirs passing the path relative to the android tree.
+    # This is because: (i) perfetto_cc_defaults is used also by
+    # test/**/Android.bp; (ii) if we use local_include_dirs instead, paths
+    # become relative to the Android.bp that *uses* cc_defaults (not the one
+    # that defines it).s
+    defaults.include_dirs = [tree_path,
+                             tree_path + '/include',
+                             tree_path + '/' + buildflags_dir]
     defaults.cflags = [
         '-Wno-error=return-type',
         '-Wno-sign-compare',
@@ -788,6 +804,9 @@
     with open(out_files[-1], 'w') as f:
         f.write('\n'.join(output))
 
+    # Generate the perfetto_build_flags.h file.
+    out_files.append(os.path.join(buildflags_dir, 'perfetto_build_flags.h.swp'))
+    gn_utils.gen_buildflags(gn_args, out_files[-1])
 
     # Either check the contents or move the files to their final destination.
     return gn_utils.check_or_commit_generated_files (out_files, args.check_only)
diff --git a/tools/gen_bazel b/tools/gen_bazel
index b47ca41..b8f3798 100755
--- a/tools/gen_bazel
+++ b/tools/gen_bazel
@@ -81,6 +81,9 @@
   '//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'
+
 
 def enable_sqlite(module):
   module.deps.add(Label('//third_party/sqlite'))
@@ -670,6 +673,10 @@
   with open(out_files[-1], 'w') as f:
     proto_build.write(Writer(f))
 
+  # Generate the build flags file.
+  out_files.append(os.path.join(buildflags_dir, 'perfetto_build_flags.h.swp'))
+  gn_utils.gen_buildflags(gn_args, out_files[-1])
+
   return gn_utils.check_or_commit_generated_files(out_files, args.check_only)
 
 
diff --git a/tools/gn_utils.py b/tools/gn_utils.py
index ca3e003..30c646b 100644
--- a/tools/gn_utils.py
+++ b/tools/gn_utils.py
@@ -26,6 +26,9 @@
 import sys
 
 
+BUILDFLAGS_TARGET = '//gn:gen_buildflags'
+
+
 def _check_command_output(cmd, cwd):
   try:
     output = subprocess.check_output(
@@ -147,6 +150,20 @@
   name = re.sub(r'[^a-zA-Z0-9_]', '_', name)
   return name
 
+
+def gen_buildflags(gn_args, target_file):
+    """Generates the perfetto_build_flags.h for the given config.
+
+    target_file: the path, relative to the repo root, where the generated
+        buildflag header will be copied into.
+    """
+    tmp_out = prepare_out_directory(gn_args, 'tmp.gen_buildflags')
+    build_targets(tmp_out, [BUILDFLAGS_TARGET], quiet=True)
+    src = os.path.join(tmp_out, 'gen', 'build_config', 'perfetto_build_flags.h')
+    shutil.copy(src, os.path.join(repo_root(), target_file))
+    shutil.rmtree(tmp_out)
+
+
 def check_or_commit_generated_files(tmp_files, check):
     """Checks that gen files are unchanged or renames them to the final location