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