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