Commit 9619c710 authored by Yuke Liao's avatar Yuke Liao Committed by Commit Bot

[code coverage] Hook coverage wrapper to build toolchains

This CL hooks the Clang code coverage wrapper into the build
toolchains, and specifically, a new build flag:
coverage_instrumentation_input_file is added to allow turning on/off
the wrapper and pass the list-files-to-instrument around.

Bug: 898695
Change-Id: I405ccbfc1796afa44534794d711f2953fac78f6d
Reviewed-on: https://chromium-review.googlesource.com/c/1309999
Commit-Queue: Yuke Liao <liaoyuke@chromium.org>
Reviewed-by: default avatarTakuto Ikuta <tikuta@chromium.org>
Reviewed-by: default avatarDirk Pranke <dpranke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#604858}
parent 6c40eacf
......@@ -6,22 +6,9 @@ import("//build/config/coverage/coverage.gni")
config("default_coverage") {
if (use_clang_coverage) {
cflags = [
"-fprofile-instr-generate",
"-fcoverage-mapping",
# Following experimental flags removes unused header functions from the
# coverage mapping data embedded in the test binaries, and the reduction
# of binary size enables building Chrome's large unit test targets on
# MacOS. Please refer to crbug.com/796290 for more details.
"-mllvm",
"-limited-coverage-experimental=true",
]
ldflags = []
if (!is_win) {
ldflags += [ "-fprofile-instr-generate" ]
cflags += [ "-fno-use-cxa-atexit" ]
} else {
# Windows directly calls link.exe instead of the compiler driver when
# linking. Hence, pass the runtime libraries instead of
......@@ -37,5 +24,26 @@ config("default_coverage") {
"use_clang_coverage=true not supported yet for this target_cpu")
}
}
# Coverage flags are only on by default when instrument all source files.
# Otherwise, coverage flags are dynamically passed to the compile command
# via the //build/toolchain/clang_code_coverage_wrapper.py script.
if (coverage_instrumentation_input_file == "") {
cflags = [
"-fprofile-instr-generate",
"-fcoverage-mapping",
# Following experimental flags removes unused header functions from the
# coverage mapping data embedded in the test binaries, and the reduction
# of binary size enables building Chrome's large unit test targets on
# MacOS. Please refer to crbug.com/796290 for more details.
"-mllvm",
"-limited-coverage-experimental=true",
]
if (!is_win) {
cflags += [ "-fno-use-cxa-atexit" ]
}
}
}
}
......@@ -4,10 +4,26 @@
import("//build/toolchain/toolchain.gni")
# There are two ways to enable code coverage instrumentation:
# 1. When |use_clang_coverage| is true and |coverage_instrumentation_input_file|
# is empty, all source files are instrumented.
# 2. When |use_clang_coverage| is true and |coverage_instrumentation_input_file|
# is NOT empty and points to a text file on the file system, ONLY source
# files specified in the input file are instrumented.
declare_args() {
# Enable Clang's Source-based Code Coverage.
use_clang_coverage = false
# The path to the coverage instrumentation input file should be a source root
# absolute path (e.g. //out/Release/coverage_instrumentation_input.txt), and
# the file consists of multiple lines where each line represents a path to a
# source file, and the paths must be relative to the root build directory.
# e.g. ../../base/task/post_task.cc for build directory 'out/Release'.
coverage_instrumentation_input_file = ""
}
assert(!use_clang_coverage || is_clang,
"Clang Source-based Code Coverage requires clang.")
assert(coverage_instrumentation_input_file == "" || use_clang_coverage,
"Instrument a subset of source files requires enabling clang coverage.")
......@@ -4,6 +4,7 @@
import("//build/config/clang/clang.gni")
import("//build/config/compiler/compiler.gni")
import("//build/config/coverage/coverage.gni")
import("//build/config/sanitizers/sanitizers.gni")
import("//build/config/v8_target_cpu.gni")
import("//build/toolchain/cc_wrapper.gni")
......@@ -193,6 +194,28 @@ template("gcc_toolchain") {
compiler_prefix = "${analyzer_wrapper} " + compiler_prefix
}
if (defined(toolchain_args.coverage_instrumentation_input_file)) {
toolchain_coverage_instrumentation_input_file =
toolchain_args.coverage_instrumentation_input_file
} else {
toolchain_coverage_instrumentation_input_file =
coverage_instrumentation_input_file
}
_use_clang_coverage_wrapper =
toolchain_coverage_instrumentation_input_file != ""
if (_use_clang_coverage_wrapper) {
assert(!use_clang_static_analyzer,
"Clang static analyzer wrapper and Clang code coverage wrapper " +
"cannot be used together.")
_coverage_wrapper =
rebase_path("//build/toolchain/clang_code_coverage_wrapper.py",
root_build_dir) + " --files-to-instrument=" +
rebase_path(toolchain_coverage_instrumentation_input_file,
root_build_dir)
compiler_prefix = "${_coverage_wrapper} " + compiler_prefix
}
cc = compiler_prefix + invoker.cc
cxx = compiler_prefix + invoker.cxx
asm = asm_prefix + invoker.cc
......
......@@ -8,6 +8,7 @@
import("../goma.gni")
import("//build/config/clang/clang.gni")
import("//build/config/coverage/coverage.gni")
if (is_ios) {
import("//build/config/ios/ios_sdk.gni")
}
......@@ -135,6 +136,29 @@ template("mac_toolchain") {
ld = cxx
}
if (defined(toolchain_args.coverage_instrumentation_input_file)) {
toolchain_coverage_instrumentation_input_file =
toolchain_args.coverage_instrumentation_input_file
} else {
toolchain_coverage_instrumentation_input_file =
coverage_instrumentation_input_file
}
_use_clang_coverage_wrapper =
toolchain_coverage_instrumentation_input_file != ""
if (_use_clang_coverage_wrapper) {
assert(!use_clang_static_analyzer,
"Clang static analyzer wrapper and Clang code coverage wrapper " +
"cannot be used together.")
_coverage_wrapper =
rebase_path("//build/toolchain/clang_code_coverage_wrapper.py",
root_build_dir) + " --files-to-instrument=" +
rebase_path(toolchain_coverage_instrumentation_input_file,
root_build_dir)
cc = _coverage_wrapper + " ${cc}"
cxx = _coverage_wrapper + " ${cxx}"
}
linker_driver =
"TOOL_VERSION=${tool_versions.linker_driver} " +
rebase_path("//build/toolchain/mac/linker_driver.py", root_build_dir)
......
......@@ -54,6 +54,7 @@ template("nacl_toolchain") {
# We do not support clang code coverage in the NaCl toolchains.
use_clang_coverage = false
coverage_instrumentation_input_file = ""
}
}
}
......@@ -30,15 +30,15 @@ everything is huge, while it's negligible for instrument what-is-needed.
## How to use the coverage wrapper?
To get the coverage wrapper hook into your build, add the following flags to
your `args.gn` file.
your `args.gn` file, assuming build directory is `out/Release`.
```
use_clang_coverage = true
coverage_instrumentation_input_file = "coverage_instrumentation_input.txt"
coverage_instrumentation_input_file = "//out/Release/coverage_instrumentation_input.txt"
```
The path to the coverage instrumentation input file should be relative to the
root build directory, and the file consists of multiple lines where each line
The path to the coverage instrumentation input file should be a source root
absolute path, and the file consists of multiple lines where each line
represents a path to a source file, and the specified paths must be relative to
the root build directory. e.g. `../../base/task/post_task.cc` for build
directory `out/Release`.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment