Stop generating data-source specific C++ classes in tracing/core

We generate C++ classes from proto for a bunch of core classes
like DataSourceConfig, DataSourceDescriptor etc. This is to
prevent spreading protobuf dependencies all over the places.
However, at some point in the past we started adding data-source
specific sub-messages to DataSourceConfig and doing to required
to generate C++ classes for things that don't really belong to
tracing/core (e.g. FtraceConfig, SysStatsConfig, etc).

This CL introduces a decoupling using a proto annotation [lazy=true].
When fields are annotated as such, the generated C++ stub exposes
the field as a raw byte array. This allows to break the dependency
between tracing/core and those configs and pushes the decoding
responsibility to the actual data sources.

This is a step towards getting rid of libprotobuf dependencies
in tracing/core for the client library.
Note that at the moment the generated classes still depend on
libprotobuf for the FromProto / ToProto conversions.

Bug: 132880619
Change-Id: I29751565277e7cb60928571e3eaf513477cf9968
diff --git a/tools/gen_tracing_cpp_headers_from_protos b/tools/gen_tracing_cpp_headers_from_protos
index 9ae472a..44187a7 100755
--- a/tools/gen_tracing_cpp_headers_from_protos
+++ b/tools/gen_tracing_cpp_headers_from_protos
@@ -17,31 +17,35 @@
 import subprocess
 import sys
 
+CORE_H = 'include/perfetto/tracing/core'
+CORE_CPP = 'src/tracing/core'
+
 PROTOS = (
-  'perfetto/common/android_log_constants.proto',
-  'perfetto/common/commit_data_request.proto',
-  'perfetto/common/observable_events.proto',
-  'perfetto/common/sys_stats_counters.proto',
-  'perfetto/common/trace_stats.proto',
-  'perfetto/config/android/android_log_config.proto',
-  'perfetto/config/chrome/chrome_config.proto',
-  'perfetto/config/data_source_config.proto',
-  'perfetto/config/data_source_descriptor.proto',
-  'perfetto/config/ftrace/ftrace_config.proto',
-  'perfetto/config/inode_file/inode_file_config.proto',
-  'perfetto/config/power/android_power_config.proto',
-  'perfetto/config/process_stats/process_stats_config.proto',
-  'perfetto/config/profiling/heapprofd_config.proto',
-  'perfetto/config/sys_stats/sys_stats_config.proto',
-  'perfetto/config/test_config.proto',
-  'perfetto/config/trace_config.proto',
+    ('perfetto/common/commit_data_request.proto', CORE_H, CORE_CPP),
+    ('perfetto/common/observable_events.proto', CORE_H, CORE_CPP),
+    ('perfetto/common/trace_stats.proto', CORE_H, CORE_CPP),
+    ('perfetto/config/chrome/chrome_config.proto', CORE_H, CORE_CPP),
+    ('perfetto/config/data_source_config.proto', CORE_H, CORE_CPP),
+    ('perfetto/config/data_source_descriptor.proto', CORE_H, CORE_CPP),
+    ('perfetto/config/test_config.proto', CORE_H, CORE_CPP),
+    ('perfetto/config/trace_config.proto', CORE_H, CORE_CPP),
+
+    # Generate ftrace cpp/h files into their own directory.
+    ('perfetto/config/ftrace/ftrace_config.proto',
+        'src/traced/probes/ftrace', 'src/traced/probes/ftrace'),
+
+    # Generate profiling cpp/h files into their own directory.
+    ('perfetto/config/profiling/heapprofd_config.proto',
+        'src/profiling/memory', 'src/profiling/memory'),
 )
 
+
 HEADER_PATH = 'include/perfetto/tracing/core'
 CPP_PATH = 'src/tracing/core'
 INCLUDE_PATH = 'perfetto/tracing/core'
 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 
+
 def run(cmd):
   print('\nRunning ' + ' '.join(cmd))
   subprocess.check_call(cmd)
@@ -56,16 +60,20 @@
     return 1
   out_dir = sys.argv[1]
   arch = 'mac' if sys.platform == 'darwin' else 'linux64'
-  clang_format_path = os.path.join(ROOT_DIR, 'buildtools', arch, 'clang-format')
+  clang_format_path = os.path.join(
+      ROOT_DIR, 'buildtools', arch, 'clang-format')
   clang_format = [clang_format_path, '-i', '--sort-includes']
+  ninja = os.path.join(ROOT_DIR, 'tools', 'ninja')
+  run([ninja, '-C', out_dir, 'proto_to_cpp'])
   tool = os.path.join(out_dir, 'proto_to_cpp')
-  if not os.path.exists(tool):
-    print('Could not find %s, run ninja -C %s proto_to_cpp' % (tool, out_dir))
-  for proto in PROTOS:
-    run([tool, proto] + [HEADER_PATH, CPP_PATH, INCLUDE_PATH])
+  assert(os.path.exists(tool))
+  for args in PROTOS:
+    proto, header_dir, cpp_dir = args
+    include_dir = header_dir.replace('include/', '')
+    run([tool, proto] + [header_dir, cpp_dir, include_dir])
     fname = os.path.basename(proto).replace('.proto', '')
-    run(clang_format + [os.path.join(HEADER_PATH, fname + '.h')])
-    run(clang_format + [os.path.join(CPP_PATH, fname + '.cc')])
+    run(clang_format + [os.path.join(header_dir, fname + '.h')])
+    run(clang_format + [os.path.join(cpp_dir, fname + '.cc')])
 
 
 if __name__ == '__main__':