Skip to content

aspects cannot traverse through the stripped output of cc_binary but cquery can #27409

@BarrettStephen

Description

@BarrettStephen

Description of the bug:

For various reasons my code base has an aspect the crawls dependencies on a final target for reporting purposes. However I noticed that it won't make it "through" a .stripped target made from a cc_binary rule. I tried with cquery and it does just fine.

I created a reproduction here with some small snippets of code

Which category does this issue belong to?

C++ Rules

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

In a directory named bug create these files:

bug/BUILD.bazel

load(":defs.bzl", "printed_deps_via_aspect")

cc_binary(
    name = "foo",
    srcs = ["foo.cc"],
)

# Sees the deps of foo just fine.
printed_deps_via_aspect(
    name = "foo_deps",
    label = ":foo",
)

# BUG: Sees zero deps.
printed_deps_via_aspect(
    name = "foo_stripped_deps",
    label = ":foo.stripped",
)

filegroup(
    name = "foo_stripped_filegroup",
    srcs = [":foo.stripped"],
)

# BUG: Sees zero deps past the stripped file.
printed_deps_via_aspect(
    name = "foo_stripped_filegroup_deps",
    label = ":foo_stripped_filegroup",
)

bug/defs.bzl

def attr_targets(attr):
    """
    Given an attr, return a list of Target type entries in that attr.

    Args:
      attr: Attribute to search for targets.

    Returns:
      Targets in the attr.
    """

    # Potentially a label_list
    if type(attr) in ["list"]:
        iterable = attr
    elif type(attr) == "dict":
        # string_keyed_label_dict
        if type(attr.keys()[0]) == "string":
            iterable = [attr.values()]
        else:
            iterable = attr

        # Potentially a label
    else:
        iterable = [attr]

    return [item for item in iterable if type(item) == "Target"]

def _print_aspect_impl(target, ctx):
    # Go through all the attributes and find the labels.
    attr_data = {key: getattr(ctx.rule.attr, key)
                 for key in dir(ctx.rule.attr)
                 if key != "to_json" and key != "to_proto"}
    for key, data in attr_data.items():
        if not data:
            continue
        for target in attr_targets(data):
            print("{}: {}".format(key, target))
    return []

_print_aspect = aspect(
    attr_aspects = ["*"],
    implementation = _print_aspect_impl,
)

def _printed_deps_via_aspect(ctx):
    return

printed_deps_via_aspect = rule(
    implementation = _printed_deps_via_aspect,
    attrs = {
        "label": attr.label(
            aspects = [_print_aspect],
            allow_files = True,
        ),
    },
)

bug/foo.cc

bug/foo.cc

Then use these commands

* you see the deps! it works!: bazel build //bug:foo_deps
* you see the deps! it works!: bazel cquery 'deps(//bug:foo.stripped, 1)'
* doesnt show any deps! bug!: bazel build //bug:foo_stripped_deps
* doesnt show any deps! bug!: bazel build //bug:foo_stripped_filegroup_deps

Which operating system are you running Bazel on?

Cent OS 9 Stream

What is the output of bazel info release?

release 7.6.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 HEAD ?


If this is a regression, please try to identify the Bazel commit where the bug was introduced with bazelisk --bisect.

No response

Have you found anything relevant by searching the web?

No unfortunately

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

Note that the output of the aspect (the prints) may be cached so you might have to edit the bzl file when you run

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions