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

crate_universe does not consolidate configurations that match the same set of platforms. #1417

Closed
pikajude opened this issue Jun 20, 2022 · 12 comments

Comments

@pikajude
Copy link

pikajude commented Jun 20, 2022

Here's the Cargo.toml for rustix-0.33.7: https://docs.rs/crate/rustix/0.33.7/source/Cargo.toml

The resulting generated file: https://gist.github.com/pikajude/4c6eec44aba219e58f5803a7efecf10b

The condition # cfg(all(windows, not(target_vendor = "uwp"))) duplicates the condition # cfg(windows). See lines 53 and 97. This results in the error:

ERROR: Traceback (most recent call last):
        File "/home/ubuntu/.cache/bazel/_bazel_ubuntu/76ed2d273358d4668b08d66cb9d677b9/external/crate_index__rustix-0.33.7/BUILD.bazel", line 101, column 10, in <toplevel>
                ): [
Error: dictionary expression has duplicate key: ("@rules_rust//rust/platform:i686-pc-windows-msvc", "@rules_rust//rust/platform:x86_64-pc-windows-msvc")
ERROR: /home/ubuntu/.cache/bazel/_bazel_ubuntu/76ed2d273358d4668b08d66cb9d677b9/external/crate_index__wasmtime-runtime-0.35.3/BUILD.bazel:33:13: no such target '@crate_index__rustix-0.33.7//:rustix': target 'rustix' not declared in package '' defined by /home/ubuntu/.cache/bazel/_bazel_ubuntu/76ed2d273358d4668b08d66cb9d677b9/external/crate_index__rustix-0.33.7/BUILD.bazel and referenced by '@crate_index__wasmtime-runtime-0.35.3//:wasmtime_runtime'

This is not a duplicate of #1236 as we aren't using supported_platform_triples in our workspace file.

@UebelAndre
Copy link
Collaborator

What rev of rules_rust are you using?

This seems to be caused by uwp not being represented in a unique windows platform but is still a unique configuration. The fix is to either define that as a platform and pass it to supported_platform_triples or to update crate_universe to flatten configurations that cannot be uniquely represented. I thought we did the latter already... I'll need to double check when I get a chance.

@pikajude
Copy link
Author

0.6.0. How recently did you make the change you mentioned?

dfinity-bot pushed a commit to dfinity/ic that referenced this issue Jun 23, 2022
Bazelize canister_sandbox

~~This is blocked on bazelbuild/rules_rust#1417

temporary workaround, see diff 

See merge request dfinity-lab/public/ic!5726
@UebelAndre
Copy link
Collaborator

Sorry for the delay here. This issue comes from the unique configurations not being consolidated when there aren't unique platforms (represented by Bazel) to match them (code here). This creates conflicting select cases and you get the error you see. I think the fix is probably just to write a wrapper for select_with_or that would do this consolidation (since I think the rust code is correct in representing configurations the way it currently is). I'd expect the implementation would result in something like the following diff:

diff --git a/BUILD.rustix-0.33.7.bazel b/BUILD.rustix-0.33.7.bazel
index 9c8ddade..fd6c0260 100644
--- a/BUILD.rustix-0.33.7.bazel
+++ b/BUILD.rustix-0.33.7.bazel
@@ -21,7 +21,7 @@ load(
 )

 # buildifier: disable=bzl-visibility
-load("@rules_rust//crate_universe/private:selects.bzl", "select_with_or")
+load("@rules_rust//crate_universe/private:selects.bzl", "consolidate", "select_with_or")

 package(default_visibility = ["//visibility:public"])

@@ -33,7 +33,7 @@ package(default_visibility = ["//visibility:public"])
 rust_library(
     name = "rustix",
     deps = [
-    ] + select_with_or({
+    ] + select_with_or(consolidate({
         # cfg(all(not(rustix_use_libc), not(miri), target_os = "linux", any(target_arch = "x86", all(target_arch = "x86_64", not(target_pointer_width = "32")), target_arch = "arm", target_arch = "aarch64", target_arch = "powerpc64", target_arch = "riscv64", target_arch = "mips", target_arch = "mips64")))
         (
             "@rules_rust//rust/platform:aarch64-unknown-linux-gnu",
@@ -112,7 +112,7 @@ rust_library(
             "@crate_index__io-lifetimes-0.5.3//:io_lifetimes",
             "@crate_index__rustix-0.33.7//:build_script_build",
         ],
-    }),
+    })),
     proc_macro_deps = [
     ] + select_with_or({
         "//conditions:default": [

Does that sound reasonable (wondering @illicitonion's thoughts too)? And is that something you'd (@pikajude) have bandwidth to work on? I'd be more than happy to review and collaborate on in a PR 😄

@UebelAndre UebelAndre added the bug label Jun 26, 2022
@UebelAndre UebelAndre changed the title crates_repository generates invalid BUILD.bazel for a crate with complicated dependencies crate_universe does not consolidate configurations that match the same set of platforms. Jun 26, 2022
@illicitonion
Copy link
Collaborator

I'm not sure consolidate can be written as described; it's still being passed a dict literal with multiple definitions of the same key? But I guess it could take a list of pairs or something...

I don't have strong thoughts on whether it makes sense to do this consolidation on the rust side or the starlark side, other than that in general rust is more expressive which can be useful :)

@sayrer
Copy link
Contributor

sayrer commented Jun 28, 2022

I just patched this in cargo-raze in Rust. I'm not sure my implementation is as brief as it could be (although, in raze, it's generic over features too). But, fwiw, I ended up having to do a list of pairs with some set operations at the end.

google/cargo-raze#512

@nathanosdev
Copy link

I just encountered this issue too, I can make an attempt at a PR @UebelAndre

@illicitonion
Copy link
Collaborator

I can make an attempt at a PR @UebelAndre

I would gladly review it! Thanks @nathanosdev!

@wmatthews-google
Copy link
Contributor

@nathanosdev - if you haven't had a chance to work on this, I can attempt a PR for this in the next few days.

@nathanosdev
Copy link

@wmatthews-google That would be awesome. If you change your mind or something else gets in the way, let me know and I can pick it back up again.

@wmatthews-google
Copy link
Contributor

Ok... I've got a draft PR out that works for everything I've thrown at it thus far (other than an issue with platforms and crate_features with wgpu-hal, but that's separate): #1647

@wmatthews-google
Copy link
Contributor

I think this is now fixed?

@UebelAndre
Copy link
Collaborator

I think this is now fixed?

Closing this out until someone says otherwise 😄

illicitonion pushed a commit that referenced this issue Jan 4, 2023
Context: see #1734.

This PR converts all of `crate_build_file.j2`, `partials/crate/*.j2` and `partials/starlark/*.j2` to serde_starlark.

### Remarks

- I kept the output of `bazel run //crate_universe/3rdparty:crates_vendor` out of this PR to keep GitHub's code review interface usable. You can find the output generated code in 44c264a.

- I tried to keep the conversion 1-to-1 to the largest extent possible. As an example, build_script.j2 duplicated most of the content of common_attrs.j2 even though it probably could have used that template via include, and I have mirrored the same here by not using `#[serde(flatten)] common: CommonAttrs` inside of `CargoBuildScript`. There is probably plenty of opportunity for cleaning up things in followup PRs.

- I came across several bugs in the existing code. Again, I mostly stayed away from these to keep the PR bounded in scope. For example the fact that `rustc_flags` is stored as a BTreeSet\<String\> is not correct; compiler flags are ordered and sorting them is not correct. For example `-C debuginfo=2`...

    https://github.com/bazelbuild/rules_rust/blob/532e60ff0ee3ac318333b3ae05392c220b17ce28/crate_universe/src/context/crate_context.rs#L178

- One bug that I fixed because in the new implementation it was easier to fix than to not fix, is that all existing uses of selectable_list.j2 and selectable_dict.j2 were broken because they all had the same failure mode as #1417. The generated code using `selects.with_or` could end up generating a map with duplicate keys if multiple distinct Cargo cfg expressions mapped to the same subset of supported platform triples. My implementation follows the same approach as #1647, but that PR only applied it to `deps` and `aliases`, not e.g. `rustc_env` and everything else.

- Anecdotally the new implementation has strong "if it compiles, it works" property. I mostly typed out the implementation of this PR top to bottom without running `crates_vendor`, and as soon as the whole thing was written and the compiler was okay with it, it was generating the output I wanted. I have not done much work in the templates in the past but I do not imagine they have this property.

### Remaining work

- `select_with_or` in private/selects.bzl is no longer used by the code generator's output. I had to keep it in this PR because all the generated BUILD files still include calls to it. It can be deleted after all those are regenerated.

- One of the tera templates still uses the old serialization of `SelectList` so the starlark serialization for it isn't a normal `Serialize` impl but instead an associated function. This causes there to be a bunch of `serialize_with = "SelectList::serialize_starlark"` attributes needed. This can be cleaned up after the last tera template is converted.

- ~~A lot of the contents of `crate::context` can be cleaned up after they're no longer used by tera. Tera needs those data structures to be serializable, whereas with serde_starlark we're not serializing anything from `crate::context`, only from `crate::utils::starlark`. For now I've just added a bunch of `serde(skip)` attributes in `crate::context` on all the parts tera is no longer using.~~ *Edit: apparently we still need to serialize all the fields in `Context` so that they end up in cargo-bazel-lock.json.*

- There are 2 remaining tera templates after this PR, module_bzl.j2 and vendor_module.j2.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants