blob: 3794329581f345f7bff3dce775708ec547d5b096 [file] [log] [blame]
# 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" ]
}
}