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

Migrate rules_rust to the new Starlark C++ toolchain API #133

Merged
merged 12 commits into from
Oct 22, 2018

Conversation

hlopko
Copy link
Member

@hlopko hlopko commented Oct 19, 2018

This is needed for rules_rust to be forward compatible with Bazel 0.20.
Tracking issues for migration:

Fixes #131.

This is needed for rules_rust to be forward compatible with Bazel 0.20.
Tracking issues for migration:

* bazelbuild/bazel#6380
* bazelbuild/bazel#6434

Fixes #131.
@hlopko
Copy link
Member Author

hlopko commented Oct 19, 2018

Tests pass with Bazel 0.18, for some reason Bazel ci still tests with bazel 0.17 on windows and ubuntu.

@hlopko
Copy link
Member Author

hlopko commented Oct 19, 2018

Ah, I just discovered https://github.com/bazelbuild/bazel-skylib/blob/master/lib/versions.bzl. Let me rewrite the version checking logic with that

@hlopko
Copy link
Member Author

hlopko commented Oct 19, 2018

And 10 commits later, we're green. Please take a look now. Thank you!

Copy link
Collaborator

@acmcarther acmcarther left a comment

Choose a reason for hiding this comment

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

Thanks for implementing this!

I've got a couple of broad questions primarily around how the cpp toolchain is located since this may need to be tweaked to support cross compilation in the future.

cc = cpp_fragment.compiler_executable
ar = cpp_fragment.ar_executable
cc_toolchain = find_cpp_toolchain(ctx)
feature_configuration = cc_common.configure_features(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Where is cc_common defined and how does it tie into cc_toolchain?

Copy link
Member Author

Choose a reason for hiding this comment

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

cc_common is currently builtin, the list of all of the builtins is here: https://docs.bazel.build/versions/master/skylark/lib/skylark-overview.html.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, I'm confused by github review, didn't I answer this already? :) cc_common is a builtin Starlark module, the list of all is here: https://docs.bazel.build/versions/master/skylark/lib/skylark-overview.html

requested_features = ctx.features,
unsupported_features = ctx.disabled_features,
)
ld = cc_common.get_tool_for_action(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Tangentially related to this PR:

Its not clear to me how the linker gets selected. Is the target platform the same as the one specified (indirectly) in find_cpp_toolchain?

Copy link
Member Author

Choose a reason for hiding this comment

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

C++ rules don't currently use platforms, they have their own thing controlled by --crosstool_top, --cpu, and --compiler (and their corresponding host variants, such as --host_crosstool_top. Here in the rule we are getting target C++ toolchain, when we're in the target configuration, and host toolchain when in host configuration (so if somebody just tells Bazel to build //foo, we build foo in target configuration. If somebody writes a genrule that has foo as a tool, Bazel will build it in host configuration). Did I answer your question?

Copy link
Member Author

Choose a reason for hiding this comment

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

C++ rules don't currently use platforms, they have their own thing controlled by --crosstool_top, --cpu, and --compiler (and their corresponding host variants, such as --host_crosstool_top. Here in the rule we are getting target C++ toolchain, when we're in the target configuration, and host toolchain when in host configuration (so if somebody just tells Bazel to build //foo, we build foo in target configuration. If somebody writes a genrule that has foo as a tool, Bazel will build it in host configuration). Did I answer your question?

@@ -191,8 +235,6 @@ def rustc_compile_action(
if ar_str.find("libtool", 0) != -1:
ar = "/usr/bin/ar"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this old ar finding logic obsolete with your changes?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like this can be removed

>> rustc --version
rustc 1.26.1 (827013a31 2018-05-25)

>> rustc -C help
...
    -C                ar=val -- this option is deprecated and does nothing

Copy link
Member Author

Choose a reason for hiding this comment

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

Removed. We will have to force ar and other tools to rustc when we want to be fully host-independent. Which we will have to be to support remote execution.

Copy link
Member Author

Choose a reason for hiding this comment

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

To be clear, it can (and will) happen that C++ toolchain will suggest to use libtool on darwin.

Copy link
Collaborator

@mfarrugi mfarrugi left a comment

Choose a reason for hiding this comment

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

LGTM, some questions on the linker toolchain api.

Are "fragments" going to be replaced as well, or is that a separate concept to toolchains?

link_variables = cc_common.create_link_variables(
feature_configuration = feature_configuration,
cc_toolchain = cc_toolchain,
is_linking_dynamic_library = False,
Copy link
Collaborator

Choose a reason for hiding this comment

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

A couple of crate types will produce dynamic libraries, should this account for that?

if crate_type in ("dylib", "cdylib", "proc-macro"):
extension = toolchain.dylib_ext

Copy link
Member Author

@hlopko hlopko Oct 21, 2018

Choose a reason for hiding this comment

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

Ideally we would ask C++ toolchain for options twice, once for executable, once for dynamic library. In practice, they usually only differ in dynamic library having --shared, which rustc might be initiative enough to add on its own. But I don't know tbh.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ideally we would ask C++ toolchain for options twice, once for executable, once for dynamic library. In practice, they usually only differ in dynamic library having --shared, which rustc might be initiative enough to add on its own. But I don't know tbh.

Copy link
Collaborator

Choose a reason for hiding this comment

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

If we have rust_library(..., crate_type = "cdylib") should this be set to True?
When would we be asking the toolchain for options twice?

return [
"$ORIGIN/" + relative_path(output_dir, lib_dir)
return depset([
relative_path(output_dir, lib_dir)
for lib_dir in _get_dir_names(depinfo.transitive_dylibs)
Copy link
Collaborator

Choose a reason for hiding this comment

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

If the toolchain handles $ORIGIN prefixes, might it handle relativizing the paths? I feel like it must

Copy link
Member Author

Choose a reason for hiding this comment

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

Nope, it doesn't, it just takes the strings passed and puts them into templates that are configured in the CROSSTOOL file (https://docs.bazel.build/versions/master/crosstool-reference.html for docs). The C++ toolchain API is really low-level, it pretty much only deals with creating the correct command line.

rust/private/rustc.bzl Show resolved Hide resolved
rust/private/rustc.bzl Show resolved Hide resolved
rust/private/rustc.bzl Outdated Show resolved Hide resolved
rust/private/rust.bzl Show resolved Hide resolved
Copy link
Member Author

@hlopko hlopko left a comment

Choose a reason for hiding this comment

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

Are "fragments" going to be replaced as well, or is that a separate concept to toolchains?

Fragments are staying, they will keep serving information that is passed on the Bazel command line (such as copts and linkopts). But fragments will specifically no longer contain anything that requires reading BUILD files (up until now they could).

rust/private/rust.bzl Show resolved Hide resolved
rust/private/rustc.bzl Outdated Show resolved Hide resolved
rust/private/rustc.bzl Show resolved Hide resolved
cc = cpp_fragment.compiler_executable
ar = cpp_fragment.ar_executable
cc_toolchain = find_cpp_toolchain(ctx)
feature_configuration = cc_common.configure_features(
Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, I'm confused by github review, didn't I answer this already? :) cc_common is a builtin Starlark module, the list of all is here: https://docs.bazel.build/versions/master/skylark/lib/skylark-overview.html

requested_features = ctx.features,
unsupported_features = ctx.disabled_features,
)
ld = cc_common.get_tool_for_action(
Copy link
Member Author

Choose a reason for hiding this comment

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

C++ rules don't currently use platforms, they have their own thing controlled by --crosstool_top, --cpu, and --compiler (and their corresponding host variants, such as --host_crosstool_top. Here in the rule we are getting target C++ toolchain, when we're in the target configuration, and host toolchain when in host configuration (so if somebody just tells Bazel to build //foo, we build foo in target configuration. If somebody writes a genrule that has foo as a tool, Bazel will build it in host configuration). Did I answer your question?

link_variables = cc_common.create_link_variables(
feature_configuration = feature_configuration,
cc_toolchain = cc_toolchain,
is_linking_dynamic_library = False,
Copy link
Member Author

Choose a reason for hiding this comment

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

Ideally we would ask C++ toolchain for options twice, once for executable, once for dynamic library. In practice, they usually only differ in dynamic library having --shared, which rustc might be initiative enough to add on its own. But I don't know tbh.

@@ -191,8 +235,6 @@ def rustc_compile_action(
if ar_str.find("libtool", 0) != -1:
ar = "/usr/bin/ar"
Copy link
Member Author

Choose a reason for hiding this comment

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

Removed. We will have to force ar and other tools to rustc when we want to be fully host-independent. Which we will have to be to support remote execution.

@@ -191,8 +235,6 @@ def rustc_compile_action(
if ar_str.find("libtool", 0) != -1:
ar = "/usr/bin/ar"
Copy link
Member Author

Choose a reason for hiding this comment

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

To be clear, it can (and will) happen that C++ toolchain will suggest to use libtool on darwin.

rust/private/rustc.bzl Show resolved Hide resolved
@hlopko
Copy link
Member Author

hlopko commented Oct 22, 2018

I'll submit now, feel free to continue discussing, I'll gladly answer or upload more fixed in a separate PR. I want to get this one in quickly so we can enable rules_rust on Bazel CI. Thanks for understanding.

@hlopko hlopko merged commit 271d790 into master Oct 22, 2018
hlopko added a commit to bazelbuild/continuous-integration that referenced this pull request Oct 22, 2018
mfarrugi added a commit that referenced this pull request Oct 22, 2018
follow up from #133, want to see green on ci
@laurentlb
Copy link
Contributor

I think the commit means that all users of rules_rust need to add this in their WORKSPACE file:

    http_archive(
        name = "bazel_skylib",
        url = "https://github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz",
        sha256 = "b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f",
        strip_prefix = "bazel-skylib-0.5.0",
    )

    load("@io_bazel_rules_rust//:workspace.bzl", "bazel_version")
    bazel_version(name = "bazel_version")

joeleba pushed a commit to joeleba/continuous-integration that referenced this pull request Jun 17, 2019
@mfarrugi mfarrugi deleted the migrate_cc_toolchain_api branch October 8, 2020 03:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants