bazelbuild / bazel

a fast, scalable, multi-language and extensible build system
https://bazel.build
Apache License 2.0
22.97k stars 4.03k forks source link

Faulty tool path handling for "gcov" tool #15411

Open UlrichEckhardt opened 2 years ago

UlrichEckhardt commented 2 years ago

Description of the bug:

The handling of tool paths in C++ toolchains is inconsistent, it works as expected for tools like gcc, ld and ar, but not for gcov. In the end, gcov is not found and no coverage is generated. The error you find in the test.log file is

GCov does not exist at the given path: 'toolchains/mingw/toolchains/mingw/gcov.sh'

Note here the duplication of toolchains/mingw in the path.

What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

I haven't fully extracted a minimal reproducible example yet, but here is the rough layout of it:

toolchain/cc_toolchain_config.bzl

def _impl(ctx):
    return cc_common.create_cc_toolchain_config_info(
        ctx = ctx,
        tool_paths = [
            tool_path(name = "gcc", path = ctx.file.gcc_executable.path),
            tool_path(name = "gcov", path = ctx.file.gcov_executable.path),
        ],
    )

cc_toolchain_config = rule(
    implementation = _impl,
    attrs = {
        "gcc_executable": attr.label(executable = True, allow_single_file = True, cfg = "exec"),
        "gcov_executable": attr.label(executable = True, allow_single_file = True, cfg = "exec"),
    },
    provides = [CcToolchainConfigInfo],
)

toolchain/gcc.sh

#!/bin/sh
# simple wrapper script 
echo gcc "$@"
exec gcc "$@"

toolchain/gcov.sh

#!/bin/sh
# simple wrapper script 
echo gcov "$@"
exec gcov "$@"

toolchain/BUILD

load(":cc_toolchain_config.bzl", "cc_toolchain_config")

package(default_visibility = ["//visibility:public"])

toolchain(
    name = "my_toolchain",
    toolchain = ":my_cc_toolchain",
    toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)

cc_toolchain(
    name = "my_cc_toolchain",
    toolchain_config = ":my_cc_toolchain_config",
)

cc_toolchain_config(
    name = "my_cc_toolchain_config",
    gcc_executable = ":gcc.sh",
    gcov_executable = ":gcov.sh",
)

Which operating system are you running Bazel on?

Ubuntu

What is the output of bazel info release?

release 5.1.1

If bazel info release returns development version or (@non-git), tell us how you built Bazel.

No response

What's the output of git remote get-url origin; git rev-parse master; git rev-parse HEAD ?

No response

Have you found anything relevant by searching the web?

No response

Any other information, logs, or outputs that you want to share?

comius commented 2 years ago

@c-mita can you triage?

ceyxiang commented 2 years ago

Hi @UlrichEckhardt, I encountered this issue when I was setting up a hermetic gcc toolchain. I managed to resolve it by,

  1. adding both the wrapper script and gcov to a filegroup,
    filegroup(
    name = "coverage_files",
    srcs = [
        "@repo1//:gcov_wrapper_script",
        "@repo2//:gcov",
    ],
    )
  2. Adding that filegroup to the srcs of my gcc_all_files filegroup
    filegroup(
    name = "gcc_all_files",
    srcs = [
        ":some_files",
        ":gcc_coverage_files",
    ],
    )
  3. Then in the cc_toolchain, all_files = ":gcc_all_files",. So in your case
    cc_toolchain(
    name = "my_cc_toolchain",
    all_files = ":gcc_all_files",
    toolchain_config = ":my_cc_toolchain_config",
    )

Hopefully this helps!

charlesoconor commented 1 year ago

This was failing for me as well. Fixed it by installing llvm-cov since the script seems to find that executable.

github-actions[bot] commented 3 weeks ago

Thank you for contributing to the Bazel repository! This issue has been marked as stale since it has not had any activity in the last 1+ years. It will be closed in the next 90 days unless any other activity occurs. If you think this issue is still relevant and should stay open, please post any comment here and the issue will no longer be marked as stale.

hauserx commented 2 weeks ago

The tool_path accepts either toolchain relative paths or absolute paths, so it's pretty hard to reference gcov binary from external dep. Workaround seems to be using COVERAGE_GCOV_PATH env variable, like: --test_env=COVERAGE_GCOV_PATH=external/my-gcc/bin/gcov but it stopped working in bazel 7.2: https://github.com/bazelbuild/bazel/issues/23247. The bug metions also some possible solutions, including using action_configs instead of tool_paths, which seems to be right approach here.