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