-
Notifications
You must be signed in to change notification settings - Fork 4.2k
bzlmod: with 6.3.0 generated lockfile it changes when running projects on different platforms if using requirements_darwin
and requirements_windows
parameters
#19154
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
Comments
requirements_darwin
and requirements_windows
parameters`requirements_darwin
and requirements_windows
parameters
/sub. also cc @meteorcloudy @SalmaSamy |
This is not necessarily something rules_python can solve. But then again, this is not necessarily something we can solve at all. @aherrmann will remember the lengthy discussion we had on conditional dependencies and how that might interact with lockfiles. If users need to produce different repos on different platforms, they will necessarily get different lockfiles; one way to deal with that might be to manually multiplex between different lockfiles themselves. We may also need to provide a flag to choose the lockfile path (so the user might say |
Yeah, combining with --enable_platform_specific_config, this could be a workaround for major platforms. |
@Wyverald, @meteorcloudy, right now I don't see a way to switch the platform config per |
--enable_platform_specific_config doesn't work for different arches, we need to come up with a better solution for the lockfile to work with multiple platforms. |
I transferred this issue from rules_python to bazel, since it's a general problem with Bzlmod lockfile. |
I think that this issue warrants taking a step back and trying to understand why module extensions may have host-dependent results. The major use cases I am aware of:
From a purely conceptual point of view, I think that the way to achieve host-agnostic resolution results for 1. and 2. is to fully embrace toolchain resolution and configurable dependencies. Put harshly, every inspection of host properties in such extensions will result in incorrect cross-platform builds and is thus wrong. Instead, extensions should strive to resolve dependencies and register SDKs for all reasonable target/exec platforms (possibly within a configurable set) and let toolchain resolution and Since the explicit purpose of extensions as in 3. is to inspect the host and encode the result in repo rule instantiations, I don't see how multiplexing could solve this general case without duplicating the entire detection logic outside Bazel, which would defeat the purpose of having the extensions in the first place. |
As @Wyverald points out, there were lengthy discussions about this on the external dependencies overhaul proposal. Unfortunately, I don't seem to have access to the comment threads anymore. @Wyverald do they still exist?
In principle, I agree with this. In practice this can be very difficult to achieve. I believe the concrete examples that were discussed on the proposal mentioned above would all fall under category 2.
|
@aherrmann Do you know how large multi-platform Rust projects deal with this problem? Given that dependencies can combine platform and feature constraints in essentially arbitrary ways, the lockfile problem doesn't seem to be any easier to solve for them than it is for us. Given these complexities, it may help to consider the different purposes served by typical package manager lockfiles in isolation:
Of these, 1. is apparently highly platform-dependent, whereas 2. can potentially be fulfilled by a It may just not be possible to solve 1. with the Bzlmod lockfile for general extensions without pushing the full multiplexing complexity onto the user. Maybe there is a way to ensure that 2. is still addressed by it even for such extensions, perhaps by splitting the file? |
We are working on adding new attributes to the module extension |
Will be followed by using these two attributes in the lockfile to store platform dependent extensions related issue: #19154 PiperOrigin-RevId: 559392081 Change-Id: Ib0cfa2df648effe785068fa4d03da02c39d1fdd8
I like that this kind of detection is built-in and doesn't require manual multiplexing. We probably still have to support the case of a module extension that inspects the system more deeply than just os name and arch and thus necessarily needs to opt out of the lockfile. I wonder whether a custom Starlark function could allow this and also be a bit more flexible than fixed For example, we could have The use case of foo = module_extension(
...,
lockfile_key = lambda os: os.name + "_" + os.arch,
) Crucially, if we see a need to extend this scheme in the feature, we can just pass in new optional keyword parameters. @SalmaSamy @Wyverald Curious to hear your thoughts about this. |
I think the
|
Another problem with the lambda approach is that we can't serialize lambdas, which means we can't know whether the foo = module_extension(..., lockfile_key = lambda os: os.name)
# run Bazel on blahOS and arm64, `foo` is locked with "lockfile key" of "blahOS"
# author changes definition of `foo` to
foo = module_extension(..., lockfile_key = lambda os: os.arch)
# run Bazel on Windows, but on a weird architecture called "blahOS"
# we reuse the existing entry even though we shouldn't |
We could use the pattern that Ivo suggested for a redo of rule implementation functions: Pass in
Yeah, that's a good point. We could accept returning a list or tuple.
That's also a good point. I kind of read this as "no key means nothing to store this under", but I can see why others wouldn't. My main gripe with the current approach is the fact that, with |
Convinced ;-) (although I guess we could hash the Starlark files containing the function and store the hash in the lockfile, but let's not go there) |
The actual data to be modeled here is something like: data Factor = Os | Arch -- with more to be added if needed
data WhenToLock = Never | DependentOnFactors (Set Factor) or in Java terms... enum Factor { OS, ARCH }
Optional<Set<Factor>> whenToLock; // `empty()` means "never lock" Accordingly, a Starlark API that keeps extensibility in mind could look like: when_to_lock = None, # means never lock; or
when_to_lock = ["os", "arch"], # a list of strings; duplicates forbidden; possible values include "os", "arch", etc But that's a little overkill IMO, especially since the "Factor" enum is unlikely to grow. Compared to this "principled" design, I'd rather go with the somewhat-dirty-but-simple "use_os + use_arch + local but local=True overrides everything else" option :) |
I agree that the enum solution feels clunky in Starlark, especially since There are a few aspects of the
|
…ts use_os and use_arch to true - Created new key for module extensions in lockfile containing the extenionId, os, and arch - Store the key information in the extension event - Update the adapter for the key related issue: #19154 PiperOrigin-RevId: 559432346 Change-Id: Ib48d7590e6d35397471a4ff46c58226eecf339c2
@bazel-io fork 6.4.0 |
… and arch Updated the logic to save and fetch module extensions from the lockfile depending on their os and arch dependency. fixes #19154 PiperOrigin-RevId: 564707355 Change-Id: Ib48d7590e6d35397471a4ff46c58226eecf339c2 # Conflicts: # scripts/bootstrap/compile.sh # src/test/py/bazel/bzlmod/bazel_lockfile_test.py # src/test/shell/bazel/bazel_determinism_test.sh
Will be followed by using these two attributes in the lockfile to store platform dependent extensions related issue: #19154 PiperOrigin-RevId: 559392081 Change-Id: Ib0cfa2df648effe785068fa4d03da02c39d1fdd8 # Conflicts: # src/main/java/com/google/devtools/build/lib/starlarkbuildapi/repository/RepositoryModuleApi.java # src/main/java/com/google/devtools/build/skydoc/fakebuildapi/repository/FakeRepositoryModule.java # src/test/java/com/google/devtools/build/lib/bazel/bzlmod/StarlarkBazelModuleTest.java
Will be followed by using these two attributes in the lockfile to store platform dependent extensions related issue: #19154 PiperOrigin-RevId: 559392081 Change-Id: Ib0cfa2df648effe785068fa4d03da02c39d1fdd8
… and arch Updated the logic to save and fetch module extensions from the lockfile depending on their os and arch dependency. fixes #19154 PiperOrigin-RevId: 564707355 Change-Id: Ib48d7590e6d35397471a4ff46c58226eecf339c2 # Conflicts: # scripts/bootstrap/compile.sh # src/test/py/bazel/bzlmod/bazel_lockfile_test.py # src/test/shell/bazel/bazel_determinism_test.sh
Store different extensions in the lockfile if they depend on os and arch Includes: - Old refactor commits for StarlarkRepositoryModule & RepositoryModuleApi from - Adding os and arch attributes to module extension - Updating the logic to save and fetch module extensions from the lockfile depending on their os and arch dependency. fixes #19154 PiperOrigin-RevId: 564707355 Change-Id: Ib48d7590e6d35397471a4ff46c58226eecf339c2 --------- Co-authored-by: Googler <[email protected]> Co-authored-by: Yun Peng <[email protected]>
A fix for this issue has been included in Bazel 6.4.0 RC1. Please test out the release candidate and report any issues as soon as possible. Thanks! |
This ensures that under bzlmod with `--lockfile-mode=update` we would generate an entry per os/arch, which is needed because the hermetic toolchain interpreter path is os/arch dependent. Summary: - add bazel_features dep - mark the pip extension as arch/os dependent Related: bazelbuild/bazel#19154 --------- Co-authored-by: Richard Levasseur <[email protected]>
Uh oh!
There was an error while loading. Please reload this page.
🐞 bug report
Affected Rule
bzlmod
pip.parse
extension.Is this a regression?
No, this is not a regression.
Description
rules_python
repository rules result in a different dependency closure depending on which platform the rules are being run on. This means that the users may be unable to add theMODULE.bazel.lock
to their version control if multiple platforms are being used.Why this happens is because we at runtime select either the default or a platform specific
requirements.txt
file to be parsed by thebzlmod
extension to create a hub repo for it. It will be different for different platforms and hence the differences in the lock file.🔬 Minimal Reproduction
Then creating a lock with
bazel 6.3.0
on Linux and a different platform will yield to changes in the lock file.🔥 Exception or Error
The lock file differs on Linux and Mac.
🌍 Your Environment
Output of
bazel version
:6.3.0
Rules_python version:
0.24.0
The text was updated successfully, but these errors were encountered: