Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add aspect hints to cc_shared_library #17725

Closed

Conversation

oquenchil
Copy link
Contributor

@oquenchil oquenchil commented Mar 10, 2023

One reason why cc_shared_library wasn't working for upb_proto_library was because indirect cc_shared_library.deps (i.e. linker_inputs not provided by the immediate dependency) were being dropped, that was fixed in f9008f6.

A second reason why it wasn't working was because until now cc_shared_library has relied on transitive deps providing CcInfo or ProtoInfo while the upb_proto_library aspect provides a custom wrapped CcInfo. This change fixes that via aspect hints. (It would still require a change in the upb rule implementation).

A third reason why it didn't work for upb was because to avoid a collision with the other aspects applied on proto_libraries, the upb_proto_library implementation added a suffix to the name when calling cc_common.create_linking_context(). This in turn caused the owner used in the linker_inputs to not match the labels of the targets seen by the cc_shared_library. To fix this, the hints provider accepts a list of owners.

Apart from those features, the hints provider also allows specifying a list of attributes for the cases where we don't want the result of every dependency to be used (this hasn't come up yet and it doesn't affect upb).

This idea was more or less described here.

Note: I am using the words "aspect hints" because conceptually they are. However, none of this is using the aspect_hints mechanism supported by Bazel rules. Here we are simply using providers.

Fixes #17676.

@oquenchil oquenchil self-assigned this Mar 10, 2023
@oquenchil oquenchil added the team-Rules-CPP Issues for C++ rules label Mar 10, 2023
@oquenchil
Copy link
Contributor Author

@fmeum Could you please take a look?

@brentleyjones
Copy link
Contributor

brentleyjones commented Mar 10, 2023

Is there a concern aspect hints aren't enabled by default? #14327

@oquenchil
Copy link
Contributor Author

Nope, I am calling this aspect hint because conceptually it is, but it doesn't need the aspect hints mechanism supported by Bazel. It's just a regular provider.

else:
targets_to_be_linked_statically_map[node_label] = node.linkable_more_than_once
must_add_children = False
# The seen count is used to track a programmatic error and fail if it
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Add _ to match the variable name, this is more consistent with the rest of the comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

targets_to_be_linked_statically_map[owner_str] = node.linkable_more_than_once
must_add_children = True

if seen_count and not_seen_count:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not_seen_count will always be more than 0 if node.owners is not empty. Basically you can get rid of not_seen_count variable and rewrite this if as:

if len(node.owners) > 0 and seen_count:
  # Do something

I do not think having not_seen_count as a separate variable makes sense since it is just a proxy check if node.owners is empty or not.

Also seen_count and not_seen_count(if you decide to keep it) can be boolean instead of int.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can change it to booleans but must keep the two variables (discussed offline).

attributes = dir(ctx.rule.attr)
owners = [ctx.label]
if CcSharedLibraryHintInfo in target:
if hasattr(target[CcSharedLibraryHintInfo], "attributes"):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These can be simplified via:

attributes = getattr(target[CcSharedLibraryHintInfo], "attributes", dir(ctx.rule.attr))
owners = getattr(target[CcSharedLibraryHintInfo], "owners", [ctx.label])

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thanks.

"For these cases, since the cc_shared_library cannot guess, the rule author should "+
"provide a hint with the owners of the linker inputs. If the value of owners is not set, then " +
"ctx.label will be used. If the rule author passes a list and they want ctx.label plus some other " +
"label then they will have to add ctx.label explicitly. Always make sure that as much as possible of " +
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "as much as possible" part is a bit vague. Is it possible to explain more precisely which parts are relevant (repo name, package, prefix of name, ...)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made it a bit more explicit.

seen_count = 0
not_seen_count = 0
for owner in node.owners:
owner_str = str(owner)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Label is Starlark-hashable, so you should be able to key the dictionaries by owner rather than str(owner). While the dictionaries aren't retained, you would potentially save a bunch of garbage string allocations.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. I added a TODO for this. That change would be a bit intrusive for this PR since the dictionaries passed/return by this method are used in many places.

fweikert pushed a commit to fweikert/bazel that referenced this pull request May 25, 2023
One reason why cc_shared_library wasn't working for upb_proto_library was because indirect cc_shared_library.deps (i.e.  linker_inputs not provided by the immediate dependency) were being dropped, that was fixed in bazelbuild@f9008f6.

A second reason why it wasn't working was because until now cc_shared_library has relied on transitive deps providing CcInfo or ProtoInfo while the upb_proto_library aspect provides a custom wrapped CcInfo.  This change fixes that via aspect hints. (It would still require a change in the upb rule implementation).

A third reason why it didn't work for upb was because to avoid a collision with the other aspects applied on proto_libraries, the upb_proto_library implementation added a suffix to the name when calling cc_common.create_linking_context(). This in turn caused the `owner` used in the `linker_inputs` to not match the labels of the targets seen by the cc_shared_library. To fix this, the hints provider accepts a list of owners.

Apart from those features, the hints provider also allows specifying a list of attributes for the cases where we don't want the result of every dependency to be used (this hasn't come up yet and it doesn't affect upb).

This idea was more or less described [here](bazelbuild#16296 (comment)).

Note: I am using the words "aspect hints" because conceptually they are. However, none of this is using the aspect_hints mechanism supported by Bazel rules. Here we are simply using providers.

Fixes bazelbuild#17676.

Closes bazelbuild#17725.

PiperOrigin-RevId: 516488095
Change-Id: I603ed8df90fef0636525d60707692930cd23fa5a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
team-Rules-CPP Issues for C++ rules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

cc_shared_library not considering linker_inputs from rules/aspects that didn't create them
4 participants