• 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_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_FORCE_DLOG_ON=$perfetto_force_dlog_on",
81    "PERFETTO_FORCE_DLOG_OFF=$perfetto_force_dlog_off",
82    "PERFETTO_FORCE_DCHECK_ON=$perfetto_force_dcheck_on",
83    "PERFETTO_FORCE_DCHECK_OFF=$perfetto_force_dcheck_off",
84    "PERFETTO_VERBOSE_LOGS=$perfetto_verbose_logs_enabled",
85    "PERFETTO_VERSION_GEN=$enable_perfetto_version_gen",
86    "PERFETTO_TP_PERCENTILE=$enable_perfetto_trace_processor_percentile",
87    "PERFETTO_TP_LINENOISE=$enable_perfetto_trace_processor_linenoise",
88    "PERFETTO_TP_HTTPD=$enable_perfetto_trace_processor_httpd",
89    "PERFETTO_TP_JSON=$enable_perfetto_trace_processor_json",
90    "PERFETTO_LOCAL_SYMBOLIZER=$perfetto_local_symbolizer",
91    "PERFETTO_ZLIB=$enable_perfetto_zlib",
92    "PERFETTO_TRACED_PERF=$enable_perfetto_traced_perf",
93    "PERFETTO_HEAPPROFD=$enable_perfetto_heapprofd",
94    "PERFETTO_STDERR_CRASH_DUMP=$enable_perfetto_stderr_crash_dump",
95    "PERFETTO_X64_CPU_OPT=$enable_perfetto_x64_cpu_opt",
96    "PERFETTO_LLVM_DEMANGLE=$enable_perfetto_llvm_demangle",
97    "PERFETTO_SYSTEM_CONSUMER=$enable_perfetto_system_consumer",
98  ]
99
100  rel_out_path = rebase_path(gen_header_path, "$root_build_dir")
101  args = [
102    "--out",
103    rel_out_path,
104    "--rsp",
105    "{{response_file_name}}",
106  ]
107
108  outputs = [ gen_header_path ]
109}
110
111# All targets should depend on this target to inherit the right flags and
112# include directories.
113group("default_deps") {
114  visibility = [ "../*" ]  # Prevent chromium targets from depending on this
115                           # (breaks component).
116  public_configs = [ ":default_config" ]
117  deps = [ ":gen_buildflags" ]
118  if (perfetto_build_standalone) {
119    public_deps = [
120      "//gn/standalone:check_build_deps",
121      "//gn/standalone/libc++:deps",
122      "//gn/standalone/sanitizers:deps",
123    ]
124    if (is_android) {
125      public_deps += [ "//gn/standalone:check_build_deps_android" ]
126    }
127  }
128}
129
130# The config that all targets in the perfetto codebase inherit by virtue of
131# having explicit deps on //gn:default_deps. This config is NOT propagated up to
132# embedders that depend on perfetto (e.g. chrome). :public_config (see below) is
133# used for that.
134config("default_config") {
135  visibility = [ "../*" ]  # Prevent chromium targets from depending on this
136                           # (breaks component).
137  configs = [ ":public_config" ]
138  defines = [ "PERFETTO_IMPLEMENTATION" ]
139  include_dirs = [
140    "..",
141    "../src/profiling/memory/include",
142  ]
143
144  if (build_with_chromium && is_android) {
145    # Included for __android_log_print
146    libs = [ "log" ]
147  }
148}
149
150# This config is propagated to embedders via libperfetto. It's also included in
151# the default_config above.
152config("public_config") {
153  include_dirs = [
154    "../include",
155
156    # For perfetto_build_flags.h
157    buildflag_gen_dir_,
158
159    # For generated files (proto libraries etc). We add the directory here
160    # because we stop propagation of the configs for individual proto libraries
161    # to avoid duplicate include directory command line flags in compiler
162    # invocations, see proto_library.gni, crbug.com/1043279, crbug.com/gn/142.
163    "$root_gen_dir/$perfetto_root_path",
164  ]
165}
166
167config("asan_instrumentation") {
168  if (use_sanitizer_configs_without_instrumentation) {
169    defines = [ "ADDRESS_SANITIZER_WITHOUT_INSTRUMENTATION" ]
170  }
171}
172
173if (perfetto_root_path != "//") {
174  config("gtest_and_gmock_embedder_config") {
175    include_dirs = [
176      "//testing/gtest/include",
177      "//testing/gmock/include",
178    ]
179  }
180}
181
182group("gtest_and_gmock") {
183  testonly = true
184
185  if (perfetto_root_path == "//") {
186    public_deps = [
187      "//buildtools:gmock",
188      "//buildtools:gtest",
189    ]
190  } else {
191    public_configs = [ ":gtest_and_gmock_embedder_config" ]
192    public_deps = [
193      "//testing/gmock",
194      "//testing/gtest",
195    ]
196  }
197}
198
199group("gtest_main") {
200  testonly = true
201
202  if (perfetto_root_path == "//") {
203    public_deps = [ "//buildtools:gtest_main" ]
204  } else if (build_with_chromium) {
205    public_deps = [ "//base/test:run_all_unittests" ]
206  } else {
207    public_deps = [ "//testing/gtest:gtest_main" ]
208  }
209}
210
211# Full protobuf is just for host tools .No binary shipped on device should
212# depend on this.
213protobuf_full_deps_allowlist = [
214  "../buildtools/grpc:*",
215  "../src/ipc/protoc_plugin:*",
216  "../src/protozero/protoc_plugin:*",
217  "../src/protozero/filtering:filter_util",
218  "../src/trace_processor:trace_processor_shell",
219  "../src/protozero/filtering:filter_util",
220  "../tools/*",
221  "../src/tools/*",
222]
223
224group("protoc") {
225  public_deps = [ "${perfetto_protobuf_target_prefix}:protoc($host_toolchain)" ]
226}
227
228config("system_protoc") {
229  libs = [ "protoc" ]  # This will link against libprotoc.so
230}
231
232# pkg_deps selects the appropriate pkg-config based on current_toolchain and
233# this is a no-op if |perfetto_use_pkgconfig| is false.
234pkg_config("pkgconfig_protobuf") {
235  pkg_deps = [ "protobuf" ]
236}
237
238config("system_protobuf") {
239  if (perfetto_use_pkgconfig) {
240    configs = [ ":pkgconfig_protobuf" ]
241  } else {
242    # Fallback if pkg-config isn't enabled.
243    libs = [ "protobuf" ]  # This will link against libprotobuf.so
244  }
245}
246
247# protoc compiler library, it's used for building protoc plugins.
248group("protoc_lib") {
249  visibility = protobuf_full_deps_allowlist
250  if (current_toolchain == host_toolchain) {
251    if (perfetto_use_system_protobuf) {
252      public_configs = [
253        ":system_protobuf",
254        ":system_protoc",
255        ":protobuf_gen_config",
256      ]
257    } else {
258      public_deps = [ "${perfetto_protobuf_target_prefix}:protoc_lib" ]
259    }
260  }
261}
262
263group("protobuf_full") {
264  visibility = protobuf_full_deps_allowlist
265  if (perfetto_use_system_protobuf) {
266    public_configs = [ ":system_protobuf" ]
267  } else {
268    public_deps = [ "${perfetto_protobuf_target_prefix}:protobuf_full" ]
269  }
270}
271
272group("protobuf_lite") {
273  if (perfetto_use_system_protobuf) {
274    public_configs = [ ":system_protobuf" ]
275  } else {
276    public_deps = [ "${perfetto_protobuf_target_prefix}:protobuf_lite" ]
277  }
278}
279
280# This config is applied to the .pb.{cc,h} generated by proto_library(). This
281# config is propagated up to the source sets that depend on generated proto
282# headers and proto libraries. Therefore this should stay as lean and clean as
283# possible in terms of -W-no* suppressions. Thankfully the autogenerated .pb.h
284# headers violate less warnings than the libprotobuf_* library itself.
285# This config is defined here (as opposed to //buildtools/BUILD.gn) so that when
286# perfetto_use_system_protobuf=true, the right compiler flags are passed.
287config("protobuf_gen_config") {
288  visibility = [ "*" ]  # This is injected by standalone/proto_library.gni
289  defines = [
290    "GOOGLE_PROTOBUF_NO_RTTI",
291    "GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
292  ]
293  cflags = []
294  if (!is_clang && !is_win) {
295    cflags += [ "-Wno-deprecated-declarations" ]
296  }
297  if (is_clang && is_win) {
298    cflags += [
299      "-Wno-reserved-id-macro",
300      "-Wno-language-extension-token",
301      "-Wno-sign-conversion",
302      "-Wno-suggest-destructor-override",
303      "-Wno-undefined-reinterpret-cast",
304      "-Wno-inconsistent-missing-destructor-override",
305      "-Wno-unused-parameter",
306      "-Wno-shadow-field-in-constructor",
307      "-Wno-zero-as-null-pointer-constant",
308
309      # Fixed in upstream protobuf v3.22.0
310      # d37cbfd4485f("Update inlined_string_field.h"), but we don't have that.
311      "-Wno-undef",
312    ]
313  }
314
315  if (!perfetto_use_system_protobuf) {
316    cflags += [
317      # Using -isystem instead of include_dirs (-I), so we don't need to
318      # suppress warnings coming from libprotobuf headers. Doing so would mask
319      # warnings in our own code.
320      perfetto_isystem_cflag,
321      rebase_path("../buildtools/protobuf/src", root_build_dir),
322    ]
323  }
324}
325
326# The Google C++ Benchmark library.
327# Only available in standalone builds.
328if (enable_perfetto_benchmarks) {
329  group("benchmark") {
330    testonly = true
331    public_deps = [ "//buildtools:benchmark" ]
332  }
333}
334
335# Libbacktrace, used for printing stack traces from crash handler, only in
336# standalone debug builds.
337if (perfetto_build_standalone && (is_linux || is_android)) {
338  group("libbacktrace") {
339    public_deps = [ "//buildtools:libbacktrace" ]
340  }
341}
342
343if (enable_perfetto_trace_processor_sqlite) {
344  group("sqlite") {
345    if (perfetto_root_path == "//") {
346      public_deps = [ "//buildtools:sqlite" ]
347    } else {
348      if (build_with_chromium) {
349        public_deps = [ "//third_party/sqlite:sqlite_dev" ]
350      } else {
351        public_deps = [ "//third_party/sqlite:sqlite" ]
352      }
353      public_configs = [ ":sqlite_third_party_include_path" ]
354    }
355  }
356}
357
358config("sqlite_third_party_include_path") {
359  if (build_with_chromium) {
360    include_dirs = [ "//third_party/sqlite/dev" ]
361  } else {
362    include_dirs = [ "//third_party/sqlite" ]
363  }
364}
365
366if (enable_perfetto_trace_processor_json) {
367  group("jsoncpp") {
368    if (perfetto_root_path == "//") {
369      public_configs = [ "//buildtools:jsoncpp_config" ]
370      public_deps = [ "//buildtools:jsoncpp" ]
371    } else {
372      public_deps = [ "//third_party/jsoncpp:jsoncpp" ]
373    }
374  }
375}
376
377if (enable_perfetto_grpc) {
378  group("grpc") {
379    public_configs = [ "//buildtools:grpc_public_config" ]
380    public_deps = [ "//buildtools/grpc:grpc++" ]
381  }
382}
383
384if (enable_perfetto_trace_processor_linenoise) {
385  # Used by the trace_processor_shell for REPL history.
386  # Only available in standalone builds.
387  group("linenoise") {
388    public_deps = [ "//buildtools:linenoise" ]
389  }
390}  # if (enable_perfetto_trace_processor_linenoise)
391
392# Only used by src/profiling in standalone and android builds.
393if (enable_perfetto_heapprofd || enable_perfetto_traced_perf) {
394  group("libunwindstack") {
395    public_configs = [ "//buildtools:libunwindstack_config" ]
396    public_deps = [ "//buildtools:libunwindstack" ]
397  }
398}
399
400# Used by src/profiling/perf for perf_regs.h.
401if (enable_perfetto_traced_perf) {
402  group("bionic_kernel_uapi_headers") {
403    public_configs = [ "//buildtools:bionic_kernel_uapi_headers" ]
404  }
405}
406
407config("system_zlib_config") {
408  libs = [ "z" ]
409}
410
411# Zlib is used both by trace_processor and by perfetto_cmd.
412if (enable_perfetto_zlib) {
413  group("zlib") {
414    if (perfetto_use_system_zlib) {
415      public_configs = [ "//gn:system_zlib_config" ]
416    } else if (perfetto_root_path == "//") {
417      public_configs = [ "//buildtools:zlib_config" ]
418      public_deps = [ "//buildtools:zlib" ]
419    } else {
420      public_configs = [ "//third_party/zlib:zlib_config" ]
421      public_deps = [ "//third_party/zlib" ]
422    }
423  }
424}
425
426if (enable_perfetto_llvm_demangle) {
427  group("llvm_demangle") {
428    public_deps = [ "//buildtools:llvm_demangle" ]
429  }
430}
431
432# Allows overriding platform-specific functionality used by base at a
433# build-system level. This allows e.g. different implementations of base
434# functions in Google3.
435group("base_platform") {
436  public_deps = [ "../src/base:perfetto_base_default_platform" ]
437}
438
439# Used by fuzzers.
440if (enable_perfetto_fuzzers && use_libfuzzer) {
441  group("libfuzzer") {
442    assert(perfetto_root_path == "//")
443    public_deps = [ "//buildtools:libfuzzer" ]
444  }
445}
446
447# Python libraries which need to be installed on the system
448# or provided (for other build systems).
449perfetto_py_library("pandas_py") {
450}
451perfetto_py_library("tp_vendor_py") {
452}
453perfetto_py_library("tp_resolvers_py") {
454}
455perfetto_py_library("protobuf_py") {
456}
457