| # Copyright 2018 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import("//build/config/clang/clang.gni") |
| import("//build/config/profile/config.gni") |
| import("//build/toolchain/variant.gni") |
| |
| # Common flags for all coverage-based variants defined below. |
| # IMPORTANT: This should not include any rust or linker flags! |
| _coverage_common_flags = [ |
| "-fprofile-instr-generate", |
| "-fcoverage-mapping", |
| ] |
| |
| _profile_source_files_lines = [] |
| foreach(file, dont_profile_source_files) { |
| # Escape "/" and "." since this is parsed as a regex. |
| # Note that the compiler internally expands "*" into ".*". |
| # See: https://clang.llvm.org/docs/SanitizerSpecialCaseList.html |
| file = rebase_path(file, root_build_dir) |
| file = string_replace(file, "/", "\/") |
| file = string_replace(file, ".", "\.") |
| _profile_source_files_lines += [ "!src:$file" ] |
| } |
| foreach(file, profile_source_files) { |
| # Escape "/" and "." since this is parsed as a regex. |
| # Note that the compiler internally expands "*" into ".*". |
| # See: https://clang.llvm.org/docs/SanitizerSpecialCaseList.html |
| file = rebase_path(file, root_build_dir) |
| file = string_replace(file, "/", "\/") |
| file = string_replace(file, ".", "\.") |
| _profile_source_files_lines += [ "src:$file" ] |
| } |
| |
| # This can't use a generated_file() target because there's no way to |
| # express the deps to make GN accept the file in the inputs list if it's |
| # the output of some target. |
| _profile_source_files_file = "$root_out_dir/profile-source-files.list" |
| write_file(_profile_source_files_file, |
| _profile_source_files_lines, |
| "list lines") |
| profile_source_files_list_files += [ _profile_source_files_file ] |
| |
| _coverage_inputs = profile_source_files_list_files |
| foreach(file, profile_source_files_list_files) { |
| _coverage_common_flags += |
| [ "-fprofile-list=" + rebase_path(file, root_build_dir) ] |
| } |
| |
| # A toolchain like user.basic that doesn't support the Fuchsia compiler ABI |
| # can't be using the prebuilt runtime from the toolchain, so it shouldn't get |
| # any implicit dependencies or configuration meant for that runtime. If a |
| # special-case runtime such as //src/lib/llvm-profdata is used it will be in |
| # explicit deps and take care of those linking details for itself. |
| _has_compiler_abi = toolchain_variant.tags + [ "no-compiler-abi" ] - |
| [ "no-compiler-abi" ] == toolchain_variant.tags |
| _fuchsia_prebuilt_runtime = _has_compiler_abi && is_fuchsia && !is_kernel |
| |
| variant("coverage") { |
| common_flags = _coverage_common_flags |
| inputs = _coverage_inputs |
| |
| if (_fuchsia_prebuilt_runtime) { |
| # The statically-linked profiling runtime depends on libzircon. |
| # TODO(https://fxbug.dev/42139818): Ensure this works with |
| # shared_library() instances too! |
| deps = [ "//src/zircon/lib/zircon" ] |
| |
| dynamic_linker_flags = "-dynamic-linker=coverage/ld.so.1" |
| ldflags = [ "-Wl,$dynamic_linker_flags" ] |
| rustflags = [ "-Clink-arg=$dynamic_linker_flags" ] |
| } |
| |
| cflags = [] |
| |
| # Enable runtime counter relocation in Linux. |
| if (is_linux) { |
| cflags += [ |
| "-mllvm", |
| "-runtime-counter-relocation", |
| ] |
| } |
| |
| # Enable coverage from system headers in Fuchsia. |
| if (is_fuchsia) { |
| cflags += [ |
| "-mllvm", |
| "-system-headers-coverage", |
| ] |
| } |
| } |
| |
| # This can be appended with: |
| # ``` |
| # configs += [ "//build/config/profile:no-coverage" ] |
| # ``` |
| # in any particular target where the coverage information is never |
| # worth collecting, such as certain kinds of generated code. |
| config("no-coverage") { |
| if (toolchain_variant.tags + [ "coverage" ] - [ "coverage" ] != |
| toolchain_variant.tags) { |
| cflags = [ |
| "-fno-profile-instr-generate", |
| "-fno-coverage-mapping", |
| ] |
| rustflags = [ "-Cno-instrument-coverage" ] |
| } |
| } |
| |
| # This variant is similar to `coverage` but only instruments sources that are |
| # interesting for measuring CTS coverage. |
| variant("coverage-cts") { |
| common_flags = _coverage_common_flags |
| inputs = _coverage_inputs |
| |
| common_flags += |
| [ "-fprofile-list=" + rebase_path("profile-cts.list", root_build_dir) ] |
| inputs += [ "profile-cts.list" ] |
| |
| if (_fuchsia_prebuilt_runtime) { |
| # The statically-linked profiling runtime depends on libzircon. |
| # TODO(https://fxbug.dev/42139818): Ensure this works with shared_library() instances too! |
| deps = [ "//src/zircon/lib/zircon" ] |
| |
| dynamic_linker_flags = "-dynamic-linker=coverage-cts/ld.so.1" |
| ldflags = [ "-Wl,$dynamic_linker_flags" ] |
| rustflags = [ "-Clink-arg=$dynamic_linker_flags" ] |
| } |
| |
| cflags = [] |
| |
| # Enable runtime counter relocation in Linux. |
| if (is_linux) { |
| cflags += [ |
| "-mllvm", |
| "-runtime-counter-relocation", |
| ] |
| } |
| |
| # Enable coverage from system headers in Fuchsia. |
| if (is_fuchsia) { |
| cflags += [ |
| "-mllvm", |
| "-system-headers-coverage", |
| ] |
| } |
| } |
| |
| # Only enable either "coverage-rust" or clang coverage (variant("profile") or variant("coverage")), |
| # not both. |
| # |
| # DO NOT NAME THIS WITH PREFIX `rust-`. The prefix will be stripped in some cases, and fail to |
| # work with other cases that do not expect the stripped prefix. |
| variant("coverage-rust") { |
| rustflags = [ "-Cinstrument-coverage" ] |
| |
| if (_fuchsia_prebuilt_runtime) { |
| # The statically-linked profiling runtime depends on libzircon. |
| # TODO(https://fxbug.dev/42139818): Ensure this works with shared_library() instances too! |
| deps = [ "//src/zircon/lib/zircon" ] |
| |
| dynamic_linker_flags = "-dynamic-linker=coverage-rust/ld.so.1" |
| ldflags = [ "-Wl,$dynamic_linker_flags" ] |
| rustflags += [ "-Clink-arg=$dynamic_linker_flags" ] |
| |
| # TODO(https://fxbug.dev/42077482): Ensure this works for no_coverage Rust cases. |
| libs = [ "./llvm_profile_counter_bias.ld" ] |
| } else if (is_linux) { |
| rustflags += [ "-Cllvm-args=-runtime-counter-relocation" ] |
| } |
| } |
| |
| # Enable PGO instrumentation to collect profiles. |
| variant("profile") { |
| common_flags = [ "-fprofile-generate" ] |
| |
| # We need to link the profile runtime manually into Rust binaries to satisfy |
| # compiler generated symbol references in the instrumented C++ code. |
| libclang_rt_profile = |
| rebase_path(exec_script("/usr/bin/env", |
| [ |
| "${rebased_clang_prefix}/clang", |
| "--target=${current_target_tuple}", |
| "-print-file-name=libclang_rt.profile.a", |
| ], |
| "trim string"), |
| root_build_dir) |
| rustflags = [ "-Clink-arg=${libclang_rt_profile}" ] |
| |
| if (_fuchsia_prebuilt_runtime) { |
| # The statically-linked profiling runtime depends on libzircon. |
| # TODO(https://fxbug.dev/42139818): Ensure this works with shared_library() instances too! |
| deps = [ "//src/zircon/lib/zircon" ] |
| |
| dynamic_linker_flags = "-dynamic-linker=profile/ld.so.1" |
| ldflags = [ "-Wl,$dynamic_linker_flags" ] |
| rustflags += [ "-Clink-arg=$dynamic_linker_flags" ] |
| } |
| |
| if (is_fuchsia || is_kernel) { |
| # TODO(https://fxbug.dev/42053322): Value profiling isn't supported by the runtime. |
| cflags = [ |
| "-mllvm", |
| "-disable-vp", |
| ] |
| } |
| } |
| |
| # PGO-optimized build that uses collected profiles. |
| config("profile-use") { |
| if (pgo_profile_path != "") { |
| cflags = |
| [ "-fprofile-use=" + rebase_path(pgo_profile_path, root_build_dir) ] |
| |
| # TODO(https://fxbug.dev/336358027): Suppress the following warning in PGO |
| # optimized build: "Function control flow change detected (hash mismatch)" |
| cflags += [ "-Wno-backend-plugin" ] |
| } |
| } |