xref: /aosp_15_r20/external/perfetto/gn/BUILD.gn (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1# Copyright (C) 2017 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import("perfetto.gni")
16import("perfetto_python.gni")
17import("pkg_config.gni")
18import("proto_library.gni")
19
20if (perfetto_root_path == "//") {
21  import("//gn/standalone/sanitizers/vars.gni")
22} else {
23  import("//build/config/sanitizers/sanitizers.gni")
24}
25
26# Genereates a header files that contains a macro definition for each build flag
27# that is required by the codebase. This is to avoid sprinkling cflags all over
28# the places, which is very fragile especially for our codebase that needs to
29# deal with several build systems.
30# The way this works is the following:
31# - This rule generates a header that contains a bunch of lines like:
32#   #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_BUILD()
33# - The generated header is included by base/build_config.h
34# - Source files in the codebase #include base/build_config and use the
35#   pattern #if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
36buildflag_gen_dir_ = "$root_gen_dir/$perfetto_root_path/build_config"
37action("gen_buildflags") {
38  script = "write_buildflag_header.py"
39  gen_header_path = "$buildflag_gen_dir_/perfetto_build_flags.h"
40
41  perfetto_component_build = false
42  if (defined(is_component_build) && is_component_build) {
43    perfetto_component_build = true
44  }
45  perfetto_force_dlog_on = perfetto_force_dlog == "on"
46  perfetto_force_dlog_off = perfetto_force_dlog == "off"
47
48  perfetto_force_dcheck_on = perfetto_force_dcheck == "on"
49  perfetto_force_dcheck_off = perfetto_force_dcheck == "off"
50
51  # We can't just use (is_linux || is_android) in perfetto.gni because that
52  # doesn't work in Android Mac host builds. We lose the GN notion of OS once
53  # we run the tools/gen_xxx generators.
54  if (enable_perfetto_watchdog) {
55    perfetto_watchdog = "PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() || " +
56                        "PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX()"
57  } else {
58    perfetto_watchdog = "0"
59  }
60
61  # We need local symbolization to run diff tests in chrome.
62  if (enable_perfetto_tools ||
63      (enable_perfetto_trace_processor && build_with_chromium)) {
64    perfetto_local_symbolizer =
65        "PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() || " +
66        "PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() ||" +
67        "PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN()"
68  } else {
69    perfetto_local_symbolizer = "0"
70  }
71  response_file_contents = [
72    "--flags",  # Keep this marker first.
73    "PERFETTO_ANDROID_BUILD=$perfetto_build_with_android",
74    "PERFETTO_CHROMIUM_BUILD=$build_with_chromium",
75    "PERFETTO_STANDALONE_BUILD=$perfetto_build_standalone",
76    "PERFETTO_START_DAEMONS=$start_daemons_for_testing",
77    "PERFETTO_IPC=$enable_perfetto_ipc",
78    "PERFETTO_WATCHDOG=$perfetto_watchdog",
79    "PERFETTO_COMPONENT_BUILD=$perfetto_component_build",
80    "PERFETTO_ENABLE_ETM_IMPORTER=$enable_perfetto_etm_importer",
81    "PERFETTO_FORCE_DLOG_ON=$perfetto_force_dlog_on",
82    "PERFETTO_FORCE_DLOG_OFF=$perfetto_force_dlog_off",
83    "PERFETTO_FORCE_DCHECK_ON=$perfetto_force_dcheck_on",
84    "PERFETTO_FORCE_DCHECK_OFF=$perfetto_force_dcheck_off",
85    "PERFETTO_VERBOSE_LOGS=$perfetto_verbose_logs_enabled",
86    "PERFETTO_VERSION_GEN=$enable_perfetto_version_gen",
87    "PERFETTO_TP_PERCENTILE=$enable_perfetto_trace_processor_percentile",
88    "PERFETTO_TP_LINENOISE=$enable_perfetto_trace_processor_linenoise",
89    "PERFETTO_TP_HTTPD=$enable_perfetto_trace_processor_httpd",
90    "PERFETTO_TP_JSON=$enable_perfetto_trace_processor_json",
91    "PERFETTO_TP_INSTRUMENTS=$enable_perfetto_trace_processor_mac_instruments",
92    "PERFETTO_LOCAL_SYMBOLIZER=$perfetto_local_symbolizer",
93    "PERFETTO_ZLIB=$enable_perfetto_zlib",
94    "PERFETTO_TRACED_PERF=$enable_perfetto_traced_perf",
95    "PERFETTO_HEAPPROFD=$enable_perfetto_heapprofd",
96    "PERFETTO_STDERR_CRASH_DUMP=$enable_perfetto_stderr_crash_dump",
97    "PERFETTO_X64_CPU_OPT=$enable_perfetto_x64_cpu_opt",
98    "PERFETTO_LLVM_DEMANGLE=$enable_perfetto_llvm_demangle",
99    "PERFETTO_SYSTEM_CONSUMER=$enable_perfetto_system_consumer",
100    "PERFETTO_THREAD_SAFETY_ANNOTATIONS=$perfetto_thread_safety_annotations",
101  ]
102
103  rel_out_path = rebase_path(gen_header_path, "$root_build_dir")
104  args = [
105    "--out",
106    rel_out_path,
107    "--rsp",
108    "{{response_file_name}}",
109  ]
110
111  outputs = [ gen_header_path ]
112}
113
114# All targets should depend on this target to inherit the right flags and
115# include directories.
116group("default_deps") {
117  visibility = [ "../*" ]  # Prevent chromium targets from depending on this
118                           # (breaks component).
119  public_configs = [ ":default_config" ]
120  deps = [ ":gen_buildflags" ]
121  if (perfetto_build_standalone) {
122    public_deps = [
123      "//gn/standalone:check_build_deps",
124      "//gn/standalone/libc++:deps",
125      "//gn/standalone/sanitizers:deps",
126    ]
127    if (is_android) {
128      public_deps += [ "//gn/standalone:check_build_deps_android" ]
129    }
130  }
131}
132
133# The config that all targets in the perfetto codebase inherit by virtue of
134# having explicit deps on //gn:default_deps. This config is NOT propagated up to
135# embedders that depend on perfetto (e.g. chrome). :public_config (see below) is
136# used for that.
137config("default_config") {
138  visibility = [ "../*" ]  # Prevent chromium targets from depending on this
139                           # (breaks component).
140  configs = [ ":public_config" ]
141  defines = [ "PERFETTO_IMPLEMENTATION" ]
142  include_dirs = [
143    "..",
144    "../src/profiling/memory/include",
145  ]
146
147  if (build_with_chromium && is_android) {
148    # Included for __android_log_print
149    libs = [ "log" ]
150  }
151}
152
153# This config is propagated to embedders via libperfetto. It's also included in
154# the default_config above.
155config("public_config") {
156  include_dirs = [
157    "../include",
158
159    # For perfetto_build_flags.h
160    buildflag_gen_dir_,
161
162    # For generated files (proto libraries etc). We add the directory here
163    # because we stop propagation of the configs for individual proto libraries
164    # to avoid duplicate include directory command line flags in compiler
165    # invocations, see proto_library.gni, crbug.com/1043279, crbug.com/gn/142.
166    "$root_gen_dir/$perfetto_root_path",
167  ]
168}
169
170config("asan_instrumentation") {
171  if (use_sanitizer_configs_without_instrumentation) {
172    defines = [ "ADDRESS_SANITIZER_WITHOUT_INSTRUMENTATION" ]
173  }
174}
175
176if (perfetto_root_path != "//") {
177  config("gtest_and_gmock_embedder_config") {
178    include_dirs = [
179      "//testing/gtest/include",
180      "//testing/gmock/include",
181    ]
182  }
183}
184
185group("gtest_and_gmock") {
186  testonly = true
187
188  if (perfetto_root_path == "//") {
189    public_deps = [
190      "//buildtools:gmock",
191      "//buildtools:gtest",
192    ]
193  } else {
194    public_configs = [ ":gtest_and_gmock_embedder_config" ]
195    public_deps = [
196      "//testing/gmock",
197      "//testing/gtest",
198    ]
199  }
200}
201
202group("gtest_main") {
203  testonly = true
204
205  if (perfetto_root_path == "//") {
206    public_deps = [ "//buildtools:gtest_main" ]
207  } else if (build_with_chromium) {
208    public_deps = [ "//base/test:run_all_unittests" ]
209  } else {
210    public_deps = [ "//testing/gtest:gtest_main" ]
211  }
212}
213
214# Full protobuf is just for host tools .No binary shipped on device should
215# depend on this.
216protobuf_full_deps_allowlist = [
217  "../buildtools/grpc:*",
218  "../src/ipc/protoc_plugin:*",
219  "../src/protozero/protoc_plugin:*",
220  "../src/protozero/filtering:filter_util",
221  "../src/trace_processor:trace_processor_shell",
222  "../src/protozero/filtering:filter_util",
223  "../tools/*",
224  "../src/tools/*",
225]
226
227group("protoc") {
228  public_deps = [ "${perfetto_protobuf_target_prefix}:protoc($host_toolchain)" ]
229}
230
231config("system_protoc") {
232  libs = [ "protoc" ]  # This will link against libprotoc.so
233}
234
235# pkg_deps selects the appropriate pkg-config based on current_toolchain and
236# this is a no-op if |perfetto_use_pkgconfig| is false.
237pkg_config("pkgconfig_protobuf") {
238  pkg_deps = [ "protobuf" ]
239}
240
241config("system_protobuf") {
242  if (perfetto_use_pkgconfig) {
243    configs = [ ":pkgconfig_protobuf" ]
244  } else {
245    # Fallback if pkg-config isn't enabled.
246    libs = [ "protobuf" ]  # This will link against libprotobuf.so
247  }
248}
249
250# protoc compiler library, it's used for building protoc plugins.
251group("protoc_lib") {
252  visibility = protobuf_full_deps_allowlist
253  if (current_toolchain == host_toolchain) {
254    if (perfetto_use_system_protobuf) {
255      public_configs = [
256        ":system_protobuf",
257        ":system_protoc",
258        ":protobuf_gen_config",
259      ]
260    } else {
261      public_deps = [ "${perfetto_protobuf_target_prefix}:protoc_lib" ]
262    }
263  }
264}
265
266group("protobuf_full") {
267  visibility = protobuf_full_deps_allowlist
268  if (perfetto_use_system_protobuf) {
269    public_configs = [ ":system_protobuf" ]
270  } else {
271    public_deps = [ "${perfetto_protobuf_target_prefix}:protobuf_full" ]
272  }
273}
274
275group("protobuf_lite") {
276  if (perfetto_use_system_protobuf) {
277    public_configs = [ ":system_protobuf" ]
278  } else {
279    public_deps = [ "${perfetto_protobuf_target_prefix}:protobuf_lite" ]
280  }
281}
282
283# This config is applied to the .pb.{cc,h} generated by proto_library(). This
284# config is propagated up to the source sets that depend on generated proto
285# headers and proto libraries. Therefore this should stay as lean and clean as
286# possible in terms of -W-no* suppressions. Thankfully the autogenerated .pb.h
287# headers violate less warnings than the libprotobuf_* library itself.
288# This config is defined here (as opposed to //buildtools/BUILD.gn) so that when
289# perfetto_use_system_protobuf=true, the right compiler flags are passed.
290config("protobuf_gen_config") {
291  visibility = [ "*" ]  # This is injected by standalone/proto_library.gni
292  defines = [
293    "GOOGLE_PROTOBUF_NO_RTTI",
294    "GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
295  ]
296  cflags = []
297  if (is_gcc) {
298    cflags += [ "-Wno-deprecated-declarations" ]
299  }
300  if (is_clang && is_win) {
301    cflags += [
302      "-Wno-reserved-id-macro",
303      "-Wno-language-extension-token",
304      "-Wno-sign-conversion",
305      "-Wno-suggest-destructor-override",
306      "-Wno-undefined-reinterpret-cast",
307      "-Wno-inconsistent-missing-destructor-override",
308      "-Wno-unused-parameter",
309      "-Wno-shadow-field-in-constructor",
310      "-Wno-zero-as-null-pointer-constant",
311
312      # Fixed in upstream protobuf v3.22.0
313      # d37cbfd4485f("Update inlined_string_field.h"), but we don't have that.
314      "-Wno-undef",
315    ]
316  }
317
318  if (!perfetto_use_system_protobuf) {
319    cflags += [
320      # Using -isystem instead of include_dirs (-I), so we don't need to
321      # suppress warnings coming from libprotobuf headers. Doing so would mask
322      # warnings in our own code.
323      perfetto_isystem_cflag,
324      rebase_path("../buildtools/protobuf/src", root_build_dir),
325    ]
326  }
327}
328
329# The Google C++ Benchmark library.
330# Only available in standalone builds.
331if (enable_perfetto_benchmarks) {
332  group("benchmark") {
333    testonly = true
334    public_deps = [ "//buildtools:benchmark" ]
335  }
336}
337
338# Libbacktrace, used for printing stack traces from crash handler, only in
339# standalone debug builds.
340if (perfetto_build_standalone && (is_linux || is_android)) {
341  group("libbacktrace") {
342    public_deps = [ "//buildtools:libbacktrace" ]
343  }
344}
345
346if (enable_perfetto_trace_processor_sqlite) {
347  group("sqlite") {
348    if (perfetto_root_path == "//") {
349      public_deps = [ "//buildtools:sqlite" ]
350    } else {
351      if (build_with_chromium) {
352        public_deps = [ "//third_party/sqlite:sqlite_dev" ]
353      } else {
354        public_deps = [ "//third_party/sqlite:sqlite" ]
355      }
356      public_configs = [ ":sqlite_third_party_include_path" ]
357    }
358  }
359}
360
361config("sqlite_third_party_include_path") {
362  if (build_with_chromium) {
363    include_dirs = [ "//third_party/sqlite/dev" ]
364  } else {
365    include_dirs = [ "//third_party/sqlite" ]
366  }
367}
368
369if (enable_perfetto_trace_processor_mac_instruments) {
370  group("expat") {
371    if (perfetto_root_path == "//") {
372      public_deps = [ "//buildtools:expat" ]
373    } else {
374      public_deps = [ "//third_party/expat:expat" ]
375    }
376  }
377}
378
379if (enable_perfetto_trace_processor_json) {
380  group("jsoncpp") {
381    if (perfetto_root_path == "//") {
382      public_configs = [ "//buildtools:jsoncpp_config" ]
383      public_deps = [ "//buildtools:jsoncpp" ]
384    } else {
385      public_deps = [ "//third_party/jsoncpp:jsoncpp" ]
386    }
387  }
388}
389
390if (enable_perfetto_grpc) {
391  group("grpc") {
392    public_configs = [ "//buildtools:grpc_public_config" ]
393    public_deps = [ "//buildtools/grpc:grpc++" ]
394  }
395
396  group("cpp_httplib") {
397    public_deps = [ "//buildtools:cpp_httplib" ]
398  }
399}
400
401if (enable_perfetto_trace_processor_linenoise) {
402  # Used by the trace_processor_shell for REPL history.
403  # Only available in standalone builds.
404  group("linenoise") {
405    public_deps = [ "//buildtools:linenoise" ]
406  }
407}  # if (enable_perfetto_trace_processor_linenoise)
408
409# Only used by src/profiling in standalone and android builds.
410if (enable_perfetto_heapprofd || enable_perfetto_traced_perf) {
411  group("libunwindstack") {
412    public_configs = [ "//buildtools:libunwindstack_config" ]
413    public_deps = [ "//buildtools:libunwindstack" ]
414  }
415}
416
417# Used by src/profiling/perf for perf_regs.h.
418if (enable_perfetto_traced_perf) {
419  group("bionic_kernel_uapi_headers") {
420    public_configs = [ "//buildtools:bionic_kernel_uapi_headers" ]
421  }
422}
423
424config("system_zlib_config") {
425  libs = [ "z" ]
426}
427
428# Zlib is used both by trace_processor and by perfetto_cmd.
429if (enable_perfetto_zlib) {
430  group("zlib") {
431    if (perfetto_use_system_zlib) {
432      public_configs = [ "//gn:system_zlib_config" ]
433    } else if (perfetto_root_path == "//") {
434      public_configs = [ "//buildtools:zlib_config" ]
435      public_deps = [ "//buildtools:zlib" ]
436    } else {
437      public_configs = [ "//third_party/zlib:zlib_config" ]
438      public_deps = [ "//third_party/zlib" ]
439    }
440  }
441}
442
443if (enable_perfetto_llvm_demangle) {
444  group("llvm_demangle") {
445    public_deps = [ "//buildtools:llvm_demangle" ]
446  }
447}
448
449# Allows overriding platform-specific functionality used by base at a
450# build-system level. This allows e.g. different implementations of base
451# functions in Google3.
452group("base_platform") {
453  public_deps = [ "../src/base:perfetto_base_default_platform" ]
454}
455
456# Used by fuzzers.
457if (enable_perfetto_fuzzers && use_libfuzzer) {
458  group("libfuzzer") {
459    assert(perfetto_root_path == "//")
460    public_deps = [ "//buildtools:libfuzzer" ]
461  }
462}
463
464# Python libraries which need to be installed on the system
465# or provided (for other build systems).
466perfetto_py_library("pandas_py") {
467}
468perfetto_py_library("tp_vendor_py") {
469}
470perfetto_py_library("tp_resolvers_py") {
471}
472perfetto_py_library("protobuf_py") {
473}
474
475if (enable_perfetto_etm_importer) {
476  group("open_csd") {
477    visibility = [ "//src/trace_processor/importers/etm:etm_impl" ]
478    public_deps = [ "//buildtools:open_csd" ]
479  }
480}
481