diff options
author | Ulf Adams <ulfjack@google.com> | 2018-04-19 02:55:15 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-04-19 02:56:57 -0700 |
commit | 9566f677a1093e3a3c0ddaed3f9ab34dd98e5e26 (patch) | |
tree | 375788e3c03417e2585619c840bb01456e1d0956 /tools | |
parent | 75b75c89fc3b0f5e0c68c0c4a7ca188e9d2ee205 (diff) |
Add a workaround for gcov-based coverage with clang
- Allow overriding the gcov tool with the GCOV env variable in cc_configure
- Symlink the GCOV tool in collect-coverage.sh to a temporary location with
the name "gcov"
This allows the user to specify GCOV=llvm-cov in the environment of a bazel
build, which then leads to cc_configure picking up llvm-cov in the crosstool,
which the collect-coverage.sh script then uses as "gcov".
On linux distributions, the gcov tool does not generally work with clang
coverage output, so this provides at least a workaround for running coverage
with clang (by setting the GCOV env variable).
Closes #5040.
PiperOrigin-RevId: 193487773
Diffstat (limited to 'tools')
-rw-r--r-- | tools/cpp/cc_configure.bzl | 1 | ||||
-rw-r--r-- | tools/cpp/unix_cc_configure.bzl | 70 | ||||
-rwxr-xr-x | tools/test/collect_coverage.sh | 8 |
3 files changed, 47 insertions, 32 deletions
diff --git a/tools/cpp/cc_configure.bzl b/tools/cpp/cc_configure.bzl index 925ecbcf83..cf121260f4 100644 --- a/tools/cpp/cc_configure.bzl +++ b/tools/cpp/cc_configure.bzl @@ -61,6 +61,7 @@ cc_autoconf = repository_rule( "CPLUS_INCLUDE_PATH", "CUDA_COMPUTE_CAPABILITIES", "CUDA_PATH", + "GCOV", "HOMEBREW_RUBY_PATH", "NO_WHOLE_ARCHIVE_OPTION", "USE_DYNAMIC_CRT", diff --git a/tools/cpp/unix_cc_configure.bzl b/tools/cpp/unix_cc_configure.bzl index 14f4f1e0f7..a74edf80b0 100644 --- a/tools/cpp/unix_cc_configure.bzl +++ b/tools/cpp/unix_cc_configure.bzl @@ -85,24 +85,21 @@ def _find_tool(repository_ctx, tool, overriden_tools): return overriden_tools[tool] return which(repository_ctx, tool, "/usr/bin/" + tool) -def _get_tool_paths(repository_ctx, darwin, cc, overriden_tools): +def _get_tool_paths(repository_ctx, overriden_tools): """Compute the path to the various tools. Doesn't %-escape the result!""" return dict({k: _find_tool(repository_ctx, k, overriden_tools) for k in [ + "ar", "ld", "cpp", + "gcc", "dwp", "gcov", "nm", "objcopy", "objdump", "strip", - ]}.items() + { - "gcc": cc, - "ar": "/usr/bin/libtool" - if darwin else which(repository_ctx, "ar", "/usr/bin/ar") - }.items()) - + ]}.items()) def _escaped_cplus_include_paths(repository_ctx): """Use ${CPLUS_INCLUDE_PATH} to compute the %-escaped list of flags for cxxflag.""" @@ -384,38 +381,47 @@ def _coverage_feature(darwin): } """ -def find_cc(repository_ctx, overriden_tools): - """Find the C++ compiler. Doesn't %-escape the result.""" - - if "gcc" in overriden_tools: - return overriden_tools["gcc"] - - cc_name = "gcc" - cc_environ = repository_ctx.os.environ.get("CC") - cc_paren = "" - if cc_environ != None: - cc_environ = cc_environ.strip() - if cc_environ: - cc_name = cc_environ - cc_paren = " (%s)" % cc_environ - if cc_name.startswith("/"): +def _find_generic(repository_ctx, name, env_name, overriden_tools): + """Find a generic C++ toolchain tool. Doesn't %-escape the result.""" + + if name in overriden_tools: + return overriden_tools[name] + + result = name + env_value = repository_ctx.os.environ.get(env_name) + env_value_with_paren = "" + if env_value != None: + env_value = env_value.strip() + if env_value: + result = env_value + env_value_with_paren = " (%s)" % env_value + if result.startswith("/"): # Absolute path, maybe we should make this suported by our which function. - return cc_name - cc = repository_ctx.which(cc_name) - if cc == None: + return result + result = repository_ctx.which(result) + if result == None: fail( - ("Cannot find gcc or CC%s, either correct your path or set the CC" - + " environment variable") % cc_paren) - return cc + ("Cannot find %s or %s%s, either correct your path or set the %s" + + " environment variable") % (name, env_name, env_value_with_paren, env_name)) + return result + +def find_cc(repository_ctx, overriden_tools): + return _find_generic(repository_ctx, "gcc", "CC", overriden_tools) def configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools): """Configure C++ toolchain on Unix platforms.""" repository_ctx.file("tools/cpp/empty.cc", "int main() {}") darwin = cpu_value == "darwin" - cc = find_cc(repository_ctx, overriden_tools) - tool_paths = _get_tool_paths(repository_ctx, darwin, - "cc_wrapper.sh" if darwin else str(cc), - overriden_tools) + + cc = _find_generic(repository_ctx, "gcc", "CC", overriden_tools) + overriden_tools = dict(overriden_tools) + overriden_tools["gcc"] = cc + overriden_tools["gcov"] = _find_generic(repository_ctx, "gcov", "GCOV", overriden_tools) + if darwin: + overriden_tools["gcc"] = "cc_wrapper.sh" + overriden_tools["ar"] = "/usr/bin/libtool" + + tool_paths = _get_tool_paths(repository_ctx, overriden_tools) crosstool_content = _crosstool_content(repository_ctx, cc, cpu_value, darwin) opt_content = _opt_content(darwin) dbg_content = _dbg_content() diff --git a/tools/test/collect_coverage.sh b/tools/test/collect_coverage.sh index aba56c0ee1..b9579cac99 100755 --- a/tools/test/collect_coverage.sh +++ b/tools/test/collect_coverage.sh @@ -126,13 +126,21 @@ if [[ "$COVERAGE_LEGACY_MODE" ]]; then touch "${COVERAGE_DIR}/${path}" done + # Symlink the gcov tool such with a link called gcov. Clang comes with a tool + # called llvm-cov, which behaves like gcov if symlinked in this way (otherwise + # we would need to invoke it with "llvm-cov gcov"). + GCOV="${COVERAGE_DIR}/gcov" + ln -s "${COVERAGE_GCOV_PATH}" "${GCOV}" + # Run lcov over the .gcno and .gcda files to generate the lcov tracefile. # -c - Collect coverage data # --no-external - Do not collect coverage data for system files # --ignore-errors graph - Ignore missing .gcno files; Bazel only instruments some files + # --gcov-tool "${GCOV}" - Pass the local symlink to be uses as gcov by lcov # -d "${COVERAGE_DIR}" - Directory to search for .gcda files # -o "${COVERAGE_OUTPUT_FILE}" - Output file /usr/bin/lcov -c --no-external --ignore-errors graph \ + --gcov-tool "${GCOV}" \ -d "${COVERAGE_DIR}" -o "${COVERAGE_OUTPUT_FILE}" # The paths are all wrong, because they point to /tmp. Fix up the paths to |