-
Notifications
You must be signed in to change notification settings - Fork 402
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
Use Bazel's COMPILATION_MODE var to determine opt-level and debuginfo… #97
Conversation
… codegen options This change looks at Bazel's `COMPILATION_MODE` var, surfaced on the CLI as `-c [dbg|fastbuild|opt]`, and adjusts the `opt-level` and `debuginfo` codegen options passed to `rustc`. I tried to mirror what `cargo` does in its `dev` and `release` build profiles. If there's a better way (I'm fairly new to `bazel` and `bazel rust`), I'm all ears.
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed (or fixed any issues), please reply here (e.g. What to do if you already signed the CLAIndividual signers
Corporate signers
|
lgtm (sans cla), any thoughts @acmcarther? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This generally looks fine to me, one comment.
rust/toolchain.bzl
Outdated
|
||
# TODO consider handling 'fastbuild' | ||
# opt_level and debug_info combination roughly matches Cargo's "dev" and "release" profiles | ||
(opt_level, debug_info) = (0, 2) if ctx.var["COMPILATION_MODE"] == "dbg" else (3, 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have an aversion to adding support for fastbuild
in this PR? Best way to do that is probably to pull this into a separate function, with the function returning a struct containing opt_level
and debug_info
. (0, 0) is probably most appropriate for fastbuild
.
With that change, it would probably be appropriate to drop the "@todo" from the opt-level line as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@acmcarther, the problem with (0,0)
for fastbuild
is that fastbuild
is the default mode. This means we'll get a rather useless binary/lib: no debug info and no optimizations. This is essentially why I punted on "truly" supporting fastbuild
- I think it requires some thought, unless you think it being the default isn't really an issue and users should explicitly opt in for opt
builds when they want performance or dbg
if they want full debug info.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For convenience, here is the description of the 3 modes in bazel's user manual. debuginfo=0, opt-level=0
is in the spirit of fastbuild
, but my main concern is a change of behavior for existing users that aren't explicitly specifying this option, which admittedly, seems quite C/C++ oriented (as its description even mentions). That's also the reason I wasn't sure using -c
was appropriate for non-C/C++ builds, even if they can mirror the debug info/opt level settings.
For my uses, I'm fine with explicitly specifying -c opt
or -c dbg
. In cargo
land, fastbuild
is also somewhat close to cargo check
, which is essentially "run everything up to LLMV codegen". It doesn't produce an artifact, however, but is super quick :). Although we likely can't use that for fastbuild
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my main concern is a change of behavior for existing users that aren't explicitly specifying this option, which admittedly, seems quite C/C++ oriented (as its description even mentions).
To be honest, I'm personally not overly concerned about changing the default optimization level. There have been some discussions about correctly supporting -c (opt|dbg|fastbuild) elsewhere, and I think the expectation is that they should work as they do in C++. If a user wants to have a different optimization level per compilation target, they can do so via rustc_flags. By default, I do specify an optimization level in cargo-raze
, so I expect that this will be a no-op for many build targets.
In cargo land, fastbuild is also somewhat close to cargo check, which is essentially "run everything up to LLMV codegen". It doesn't produce an artifact, however, but is super quick :). Although we likely can't use that for fastbuild.
I don't particularly care for cargo check
as a basis to work forward from as far as rust_library itself is concerned but if people are interested in this functionality, I think that Bazel Aspects are a good fit. They can traverse the build tree and convert rust_library invocations into those no-output-y check-like invocations
All that said, take those perspectives with a grain of salt. I'm the resident Cargo/"existing rust practice" antagonist though, so /cc @mfarrugi and @damienmg for more well developed opinions about changing the default optimization level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tend to default to dbg mode in my setup. I think fastbuild is not correct but is kept because in Google, binary tend to be very big so fastbuild is a better compromise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also to be consistent I would just do the fastbuild do a fast build and expect people to have -c dbg on their workstation. Also probably having fastbuild on a CI is a good thing
Our build would need #86 to revert a change to the default behavior,
because we control this in a bazelrc that is building with fastbuild and
--copts.
From that perspective, I don't mind the half measure.
(No thoughts on cargo check yet)
…On Tue, Jun 12, 2018, 12:18 Alex McArther ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In rust/toolchain.bzl
<#97 (comment)>:
> @@ -52,6 +52,10 @@ def build_rustc_command(ctx, toolchain, crate_name, crate_type, src, output_dir,
extra_filename = ""
if output_hash:
extra_filename = "-%s" % output_hash
+
+ # TODO consider handling 'fastbuild'
+ # opt_level and debug_info combination roughly matches Cargo's "dev" and "release" profiles
+ (opt_level, debug_info) = (0, 2) if ctx.var["COMPILATION_MODE"] == "dbg" else (3, 0)
my main concern is a change of behavior for existing users that aren't
explicitly specifying this option, which admittedly, seems quite C/C++
oriented (as its description even mentions).
To be honest, I'm personally not overly concerned about changing the
default optimization level. There have been some discussions about
correctly supporting -c (opt|dbg|fastbuild) elsewhere, and I think the
expectation is that they should work as they do in C++. If a user wants to
have a different optimization level per compilation target, they can do so
via rustc_flags. By default, I do specify an optimization level in
cargo-raze, so I expect that this will be a no-op for many build targets.
In cargo land, fastbuild is also somewhat close to cargo check, which is
essentially "run everything up to LLMV codegen". It doesn't produce an
artifact, however, but is super quick :). Although we likely can't use that
for fastbuild.
I don't particularly care for cargo check as a basis to work forward from
as far as rust_library itself is concerned but if people are interested in
this functionality, I think that Bazel Aspects
<https://docs.bazel.build/versions/master/skylark/aspects.html> are a
good fit. They can traverse the build tree and convert rust_library
invocations into those no-output-y check-like invocations
------------------------------
All that said, take those perspectives with a grain of salt. I'm the
resident Cargo/"existing rust practice" antagonist though, so /cc
@mfarrugi <https://github.com/mfarrugi> and @damienmg
<https://github.com/damienmg> for more well developed opinions about
changing the default optimization level.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#97 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACLjeKEeCC2kxgGE_r16pn7E1zUrj9zZks5t7-nEgaJpZM4Ujbq6>
.
|
I've signed the CLA in the meantime. |
@acmcarther, I've made the suggested changes. |
@acmcarther / @mfarrugi, do you think this is good to go? |
Ci is unhappy and I don't think I can fix either check. @acmcarther? |
I just unblocked the CI and it passed, sans CLA. @vitalyd: I'm not sure what the CLA bot uses to trigger a CLA re-evaluation, can you say Also check https://cla.developers.google.com/clas to double check that status. |
I signed it! |
@acmcarther, I looked at that cla link and it all seems good. I tried a verbatim reply above - let's see if that nudges it. The instructions above said:
It wasn't clear whether it had to be that text verbatim or that was just an example (and hence the "e.g."). But I guess we'll find out soon enough 😄 |
@acmcarther you can check people's CLA on signcla/ |
Also about the content: |
@damienmg, thanks for the pointer! I'm (embarrassingly) late to the github game, and I indeed only signed the agreement with my corp account. I've now signed it with my personal account. |
CLAs look good, thanks! |
@damienmg, so I'm quite new to Bazel. Are you suggesting that C++'s CROSSTOOL configuration is the model to follow or that it's "legacy" and should not be followed? I like your suggestion of making it a toolchain configuration, though - is there an example I can look at if it's not the C++ toolchain? Want to see how this is defined and then wired up at bazel build time. Thanks |
rust/toolchain.bzl
Outdated
@@ -68,7 +91,8 @@ def build_rustc_command(ctx, toolchain, crate_name, crate_type, src, output_dir, | |||
src.path, | |||
"--crate-name %s" % crate_name, | |||
"--crate-type %s" % crate_type, | |||
"--codegen opt-level=3", # @TODO Might not want to do -o3 on tests | |||
"--codegen opt-level=%s" % codegen_opts.opt_level, # @TODO Might not want to do -o3 on tests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: remove todo
The CROSSTOOL file is the legacy version of the toolchain rules and basically toolchain where develop with the C++ CROSSTOOL example in mind. Which means that if C++ where to use the toolchain rules, they would store the configuration that depends on the compilation mode a toolchain attribute :) I don't think such example exists, rules_go hard-code the flags in their code. Anyway that could looks like (with my PR to add the target triplet in it) : def _get_comp_mode_codegen_opts(ctx, toolchain):
mode = ctx.var["COMPILATION_MODE"]
if not mode in toolchain.compilation_mode_opts:
fail("Unrecognized compilation mode %s for toolchain for triplet %s, available modes are %s" % (mode, toolchain.triplet, compilation_mode_opts.keys()))
return toolchains.compilation_mode_opts[mode]
...
codegen_opts = _get_comp_mode_codegen_opts(ctx, toolchain)
...
def _rust_toolchain_impl(ctx):
compilation_mode_opts = {}
for k, v in ctx.attr.opt_level.items():
if not k in ctx.attr.debug_info:
fail("Compilation mode %s is not defined in debug_info but is defined opt_level" % k)
compilation_mode_opts[k] = struct(opt_level = v, debug_info = ctx.attr.debug_info[k])
for k, v in ctx.attr.debug_info.items():
if not k in ctx.attr.opt_level:
fail("Compilation mode %s is not defined in opt_level but is defined debug_info" % k)
toolchain = platform_common.ToolchainInfo(
...
compilation_mode_opts = compilation_mode_opts,
...
crosstool_files = ctx.files._crosstool)
return [toolchain]
rust_toolchain = rule(
_rust_toolchain_impl,
attrs = {
...
opt_level = attr.string_dict(default = {"opt": "3", "dbg": "0", "fastbuild": "0"}),
debug_info = attr.string_dict(default = {"opt": "0", "dbg": "2", "fastbuild": "0"}),
... |
def _get_comp_mode_codegen_opts(ctx, toolchain): | ||
comp_mode = ctx.var["COMPILATION_MODE"] | ||
if not comp_mode in toolchain.compilation_mode_opts: | ||
fail("Unrecognized compilation mode %s for toolchain." % comp_mode) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@damienmg, I didn't see your target triple changes in so leaving that out of the message (for now).
@damienmg, I applied your suggestion of making the two settings toolchain options. Tangentially, do you know how to query bazel to see what it would set |
I don't know any way to do that because you want the action manifest. cquery can tell you which toolchain is selected |
That's too bad, but ok. So, are we good on this change or is there anything else I should do? cc @acmcarther |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really feel strongly about these suggestions, and I know you're getting ping ponged between my comments and @damienmg's suggestion.
I'm OK with what we have if you'd just like to get it submitted.
@@ -221,6 +241,8 @@ rust_toolchain = rule( | |||
"_crosstool": attr.label( | |||
default = Label("//tools/defaults:crosstool"), | |||
), | |||
"opt_level": attr.string_dict(default = {"opt": "3", "dbg": "0", "fastbuild": "0"}), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional Nit:
I find the interchanging use of rust's opt and dbg and bazel's "opt" and "db" to be very confusing here.
Are you open to making this more verbose: "compilation_mode_to_opt_level" and "compilation_mode_to_debug_info_level"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about naming the attributes rust_opt_level
and rust_debug_info
, respectively? I'm not opposed to the verbose names you suggest, but I'm also not bothered by the current scheme either :).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I come from a Java context, so I don't feel sufficiently spoon fed when rust_opt_level
contains something that isn't a string
or num
. The map implies some kind of relationship or nuance that is hidden from the attr name.
It seems marginally better to my eyes though, so if status quo is the way to go, then rust_
SGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO, unless someone presents a slam dunk option, I’m inclined to leave this as-is and save the bikeshedding for a future iteration, perhaps when we expand the list of codegen options we support.
Otherwise, we’re iterating on names none of which seem significantly better than the others.
@@ -197,6 +207,15 @@ def _out_dir_setup_cmd(out_dir_tar): | |||
# The rust_toolchain rule definition and implementation. | |||
|
|||
def _rust_toolchain_impl(ctx): | |||
compilation_mode_opts = {} | |||
for k, v in ctx.attr.opt_level.items(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional Nit:
I think I personally prefer just using the known variants of COMPILATION_MODE, rather than letting this be freeform. That is to say, just iterate over ["opt", "dbg", "fastbuild"], and disregard other values.
That is to say, I think that the toolchain parameters probably have too much flexibility.
@acmcarther / @damienmg, as mentioned, I'm inclined to push the latest set of changes in this PR. Unless you guys have something that you insist on changing, I don't think we're making any forward progress with the name changes. Let me know what you think. |
Looks like we've been at a mergeable spot for a while, can address any remaining bikeshedding separately. It's worth noting that these variable names are part of the public API though, and at some point they may be painful to change. |
… codegen options
This change looks at Bazel's
COMPILATION_MODE
var, surfaced on the CLI as-c [dbg|fastbuild|opt]
, and adjusts theopt-level
anddebuginfo
codegen options passed torustc
. I tried to mirror whatcargo
does in itsdev
andrelease
build profiles.If there's a better way (I'm fairly new to
bazel
andbazel rust
), I'm all ears.