Skip to content

Add support for C dependencies with alwayslink=1#1879

Closed
steeve wants to merge 1 commit intomasterfrom
unknown repository
Closed

Add support for C dependencies with alwayslink=1#1879
steeve wants to merge 1 commit intomasterfrom
unknown repository

Conversation

@steeve
Copy link
Copy Markdown
Contributor

@steeve steeve commented Jan 2, 2019

This is done via an aspect that walks the C deps graph and builds a
dict between files and alwayslink properties, which is then used when
building the link command line.

Also, the command line is OS dependant, so add support for that too.

This is done via an aspect that walks the C deps graph and builds a
dict between files and alwayslink properties, which is then used when
building the link command line.

Also, the command line is OS dependant, so add support for that too.

Signed-off-by: Steeve Morin <steeve@zen.ly>
_CgoInfo = provider()
_CcAlwaysLinkInfo = provider()

_WHOLE_ARCHIVE_FLAGS_BY_GOOS = {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think the {} + {} operator is supported anymore in Starlark. If it is, it's deprecated.

I think it would be simpler to just define a function that returns the args though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I just tested on Bazel 0.21 and it worked without warning. Where did you see that?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

gotcha, thank you

} + {
"darwin": ("-Wl,-all_load", ""),
"js": ("", ""),
"windows": ("", ""),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Out of curiosity, why aren't the flags needed on Windows? Might be good to have a comment explaining it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

They are needed, but I'm not sure what they are

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I meant depending on MSVC or MSYS

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

cgo doesn't support MSVC, so don't worry about that. I think MSYS should accept gcc flags, but I don't know if there's a slightly different variant on Windows. Maybe just take out the case for Windows, and I can fix it later if it's a problem.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

alright i'll add windows to the list, then

"windows": ("", ""),
}

def _always_link_aspect_impl(target, ctx):
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

An aspect will be too expensive for this. It gets applied not only to the cc_library we depend on through cdeps, but to everything it depends on, which could be a lot of things. Aspects consume a lot of time and memory, and I'd love to get rid of the ones we already have.

It's unfortunate that CcSkylarkApiProvider doesn't expose this information. Do you know if there's an open issue to add it? If not, maybe we can file one. It seems like a reasonable thing to add.

Until then, I think it would be reasonable to make -Wl,--whole-archive the default for all libraries. This would probably fix #1486 (looks like you've already seen that one).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Is there a way to measure this? We build a pretty complex codebase and we didn't feel it was slow?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've opened bazelbuild/bazel#7033

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You can build with --profile=file and then bazel analyze-profile file. It will tell you how much time Bazel spends in loading, analysis, execution, etc, but it won't say which lines of code cost the most. I don't think there's a way to do that yet.

cgo currently adds a huge amount of loading / analysis overhead because it declares cc_library rules for each configuration that could affect build files. That's separate from the cdeps libraries, but in any case, it's quite a bit slower than go build. An aspect would slow it further.

Copy link
Copy Markdown
Contributor Author

@steeve steeve Jan 3, 2019

Choose a reason for hiding this comment

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

I'm not sure using -Wl,--whole-archive would be the best way really, it may bloat the binaries significantly.

That said, if we could find a way to get the go.o file (generated prior to external linking), and use a normal cc_binary to link it against the rest (bypassing go link), we might get all the niceties for free.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

That may be possible, but it would interfere with tooling. bazel query would show your target as a cc_binary with a go_binary dependency. We have some hacks like this already (cgo), but Bazel API changes have made this less necessary.

Thanks for filing bazelbuild/bazel#7033. I think that's the right path forward. I'll comment there.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for being so reactive.
For now we'll keep using this patch until a better solution arises.

Also, it provides at least a solution for people who are stuck.

@jayconrod
Copy link
Copy Markdown
Collaborator

Just to recap, Bazel 0.23.0 will introduce a new Starlark provider that will contain an alwayslink field. It was submitted in 94e5016. The new provider is not documented yet, so I don't know exactly how it will work. When rules_go migrates to that API (which we'll need to do because the old one will be deprecated), we'll observe that field.

I'll leave this PR open for now, but I may close it after there's a more concrete plan.

@steeve
Copy link
Copy Markdown
Contributor Author

steeve commented Mar 27, 2019

Going back to this. Would you be open to bump the minimum bazel version to 0.23 ?

@steeve
Copy link
Copy Markdown
Contributor Author

steeve commented Mar 27, 2019

@jayconrod
Copy link
Copy Markdown
Collaborator

I'd rather not drop support for old Bazel versions, but I hope we won't have to anymore. rules_go now has a compatibility layer that can provide a consistent interface across Bazel API breaks. It's in go/private/compat. Maybe we can add something in there to retrieve this field on versions that support it.

At the moment, I'm working on moving a lot of logic into the execution layer. Which means almost a complete rewrite of cgo. So let's not change anything here just yet. I'll likely ask you to take a look at that branch when it's passing CI here. You have a more complicated use case than most folks, and I want to make sure you're not broken by that change.

@steeve
Copy link
Copy Markdown
Contributor Author

steeve commented Mar 27, 2019

So I take it you'll emit c artefacts from starlark and not via macro? That's great to hear!

@steeve
Copy link
Copy Markdown
Contributor Author

steeve commented Mar 27, 2019

I'll try to rebase that PR and make use of the new field so that we can remove the aspect.

That said, it won't work on earlier versions of bazel.

@jayconrod
Copy link
Copy Markdown
Collaborator

So I take it you'll emit c artefacts from starlark and not via macro? That's great to hear!

That's right, we'll build an entire package in one action, including cgo code generation, C compilation, assembly, packing, coverage, and Go compilation.

Big caveat though: it won't work for Objective C because Bazel doesn't expose the Objective C toolchain to Starlark rules. So we'll still follow the old path when objc = True.

@steeve
Copy link
Copy Markdown
Contributor Author

steeve commented Mar 28, 2019

That's amazing.

For objc I think we can get pretty far with using -x objc to a cc_binary and aggregating deps as their are both compatible with each other.

@steeve
Copy link
Copy Markdown
Contributor Author

steeve commented Apr 2, 2019

@jayconrod i just remembered there is https://docs.bazel.build/versions/master/skylark/lib/apple_common.html#new_objc_provider which could perhaps do the trick?

@jayconrod
Copy link
Copy Markdown
Collaborator

I think new_objc_provider would be used if an objc_library needs to depend on a go_library or go_binary. Is there a case where we need to do that?

@steeve
Copy link
Copy Markdown
Contributor Author

steeve commented Apr 2, 2019

I'm not sure, it sure looks to me it could be used to emit an objc_library from a rule?
Which could then be put as a dep to the Cgo cc_library?

@steeve
Copy link
Copy Markdown
Contributor Author

steeve commented Apr 25, 2019

(going back to this real quick)
Would it be an option to use the aspect on older Bazel versions but the real provider on newer ones ?

@steeve
Copy link
Copy Markdown
Contributor Author

steeve commented Apr 25, 2019

Also, obviously this PR will change massively related to the changes in GoCompilePkg, not sure how much yet.

@steeve
Copy link
Copy Markdown
Contributor Author

steeve commented Aug 9, 2019

Closing this, will reopen when the need arises.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants