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