blob: 2bcebb0c651d7515a899c6ec35214843e6eafece [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) ]
}
variant("coverage") {
common_flags = _coverage_common_flags
inputs = _coverage_inputs
if (!is_kernel && is_fuchsia) {
# The statically-linked profiling runtime depends on libzircon.
# TODO(fxbug.dev/61522): 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 (!is_kernel && is_fuchsia) {
# The statically-linked profiling runtime depends on libzircon.
# TODO(fxbug.dev/61522): 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 (!is_kernel && is_fuchsia) {
# The statically-linked profiling runtime depends on libzircon.
# TODO(fxbug.dev/61522): 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(fxbug.dev/126803): Ensure this works for no_coverage Rust cases.
libs = [ "./llvm_profile_counter_bias.ld" ]
} else if (is_linux) {
rustflags += [ "-Cllvm-args=-runtime-counter-relocation" ]
}
}
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 (!is_kernel && is_fuchsia) {
# The statically-linked profiling runtime depends on libzircon.
# TODO(fxbug.dev/61522): 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(fxbug.dev/102391): Value profiling isn't supported by the runtime.
cflags = [
"-mllvm",
"-disable-vp",
]
}
}