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

bazel fetch does not fetch all deps #13847

Closed
devjgm opened this issue Aug 13, 2021 · 14 comments
Closed

bazel fetch does not fetch all deps #13847

devjgm opened this issue Aug 13, 2021 · 14 comments
Assignees
Labels
P2 We'll consider working on this in future. (Assignee optional) team-ExternalDeps External dependency handling, remote repositiories, WORKSPACE file. type: bug

Comments

@devjgm
Copy link

devjgm commented Aug 13, 2021

Description of the problem / feature request:

bazel fetch ... does not fetch all the deps needed to build ... with --nofetch. In order for bazel build --nofetch ... to work, I must explicitly list a number of rules that appear to be implementation details about bazel, like bazel fetch ... @local_config_platform//... @local_config_sh//... @local_config_cc_toolchains//... @rules_java//...

Feature requests: what underlying problem are you trying to solve with this feature?

bazel fetch ... should fetch everything necessary to run bazel build --nofetch ...

Bugs: what's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

Here's a simple repro:

$ ls -l
total 8
-rw-r----- 1 jgm primarygroup 54 Aug 13 14:37 BUILD
-rw-r----- 1 jgm primarygroup 14 Aug 13 14:36 test.cc
-rw-r----- 1 jgm primarygroup  0 Aug 13 14:36 WORKSPACE
$ cat -n BUILD
     1  cc_binary(
     2      name="test",
     3      srcs = [ "test.cc" ])
$ cat -n test.cc
     1  int main() {}
$ bazel fetch ...
Starting local Bazel server and connecting to it...
INFO: All external dependencies fetched successfully.
Loading: 8 packages loaded
$ bazel build --nofetch ...
ERROR: While resolving toolchains for target //:test: com.google.devtools.build.lib.packages.RepositoryFetchException: no such package '@local_config_platform//': to fix, run
        bazel fetch //...
External repository @local_config_platform not found and fetching repositories is disabled.
ERROR: Analysis of target '//:test' failed; build aborted: com.google.devtools.build.lib.packages.RepositoryFetchException: no such package '@local_config_platform//': to fix, run
        bazel fetch //...
External repository @local_config_platform not found and fetching repositories is disabled.
INFO: Elapsed time: 0.276s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (0 packages loaded, 1 target configured)

What operating system are you running Bazel on?

Debian GNU/Linux rodete

What's the output of bazel info release?

release 4.1.0

If bazel info release returns "development version" or "(@non-git)", tell us how you built Bazel.

NA

What's the output of git remote get-url origin ; git rev-parse master ; git rev-parse HEAD ?

NA

Have you found anything relevant by searching the web?

Nope

Any other information, logs, or outputs that you want to share?

Nope

@oquenchil oquenchil added team-OSS Issues for the Bazel OSS team: installation, release processBazel packaging, website type: bug untriaged labels Aug 20, 2021
@philwo
Copy link
Member

philwo commented Aug 31, 2021

@meteorcloudy @Wyverald Could you please triage this?

@philwo philwo added the team-ExternalDeps External dependency handling, remote repositiories, WORKSPACE file. label Aug 31, 2021
@meteorcloudy meteorcloudy added P2 We'll consider working on this in future. (Assignee optional) and removed untriaged labels Aug 31, 2021
@meteorcloudy
Copy link
Member

Thanks for reporting!

I can even reproduce the issue without using ...

pcloudy@pcloudy-macbookpro2:~/workspace/my_tests/simple_cpp_test
$ bazel fetch //:bin
Starting local Bazel server and connecting to it...
INFO: All external dependencies fetched successfully.
Loading: 9 packages loaded
pcloudy@pcloudy-macbookpro2:~/workspace/my_tests/simple_cpp_test
$ bazel build --nofetch //:bin
INFO: Invocation ID: a0965f05-fcc4-4e2f-bbb8-0307a2212ef9
INFO: Reading 'startup' options from /Users/pcloudy/.bazelrc: --host_jvm_args=-Djava.net.preferIPv6Addresses=true
INFO: Options provided by the client:
  Inherited 'common' options: --isatty=1 --terminal_columns=191
INFO: Reading rc options for 'build' from /Users/pcloudy/.bazelrc:
  'build' options: --verbose_failures --announce_rc --disk_cache=/tmp/bazel_disk_cache --repository_cache=/tmp/bazel_repository_cache
ERROR: While resolving toolchains for target //:bin: com.google.devtools.build.lib.packages.RepositoryFetchException: no such package '@local_config_platform//': to fix, run
	bazel fetch //...
External repository @local_config_platform not found and fetching repositories is disabled.
ERROR: Analysis of target '//:bin' failed; build aborted: com.google.devtools.build.lib.packages.RepositoryFetchException: no such package '@local_config_platform//': to fix, run
	bazel fetch //...
External repository @local_config_platform not found and fetching repositories is disabled.
INFO: Elapsed time: 0.187s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (0 packages loaded, 1 target configured)

It looks like fetch command failed to figure out the full dependencies of the target.

Also, I found bazel query "deps(//:bin)" doesn't report local_config_platform as a dependency. Maybe it's related.

/cc @katre @oquenchil Do you know how the cc toolchain depends on local_config_platform?

@katre
Copy link
Member

katre commented Aug 31, 2021

Everything depends on @local_config_platform: the default values of both --platforms and --host_platform are @local_config_platform//:host.

The repository is defined by the LocalConfigPlatformFunction repository rule, and added to the WORKSPACE suffix via local_config_platform.WORKSPACE (in BazelRuleClassProvider).

I am surprised that the fetch command isn't seeing it, is it somehow skipping WORKSPACE evaluation or the workspace suffix?

@meteorcloudy
Copy link
Member

https://cs.opensource.google/bazel/bazel/+/master:src/main/java/com/google/devtools/build/lib/bazel/commands/FetchCommand.java;l=101

Ah, the fetch command does depend on the bazel query logic to calculate the dependencies. So the problem is why bazel query misses local_config_platform as a dependency.

@katre
Copy link
Member

katre commented Aug 31, 2021

I am guessing that query doesn't evaluate the maybe call used to define local_config_platform (since aaf6457, in mid-2019).

Try reverting the definition just for local_config_platform to not use maybe and see if that fixes it.

@meteorcloudy
Copy link
Member

Try reverting the definition just for local_config_platform to not use maybe and see if that fixes it.

Nope, it doesn't work.

@katre
Copy link
Member

katre commented Aug 31, 2021

Okay, I'm not sure what the difference is. You can do bazel query @local_config_platform//:all, so I don't think query is the actual issue.

It looks from the error (the "External repository @local_config_platform not found and fetching repositories is disabled" message) that the local_config_platform repository rule isn't being executed. Possibly it is incorrectly categorized as a remote and not local repo?

@meteorcloudy
Copy link
Member

Possibly it is incorrectly categorized as a remote and not local repo?

I don't think this is the case, because the repository function for this repo was never triggered.

You can do bazel query @local_config_platform//:all

This will actually fetch the local_config_platform repo. But if do bazel query 'deps(//:bin)'", the local_config_platform` repo won't be fetched.

How does the cc toolchain depends on local_config_platform in the code?

@katre
Copy link
Member

katre commented Aug 31, 2021

The error is coming during toolchain resolution, which runs for any rule that uses toolchains (not only cc rules). Toolchain resolution needs to read the target platform and all available execution platforms. The default target platform (and the default execution platform) is @local_config_platform//:host, and so this needs to be loaded and configured.

Essentially any configured target depends on @local_config_platform. I am guessing we've never tested with --nofetch recently, because nothing has changed here in several years.

Something is going wrong with executing the repository function for @local_config_platform when --nofetch is passed, but I don't know what.

@philwo philwo removed the team-OSS Issues for the Bazel OSS team: installation, release processBazel packaging, website label Nov 29, 2021
@ljessendk
Copy link

I'm struggling with the same issue but found a workaround that works for me, instead of bazel fetch ... I use bazel aquery "deps(...)":
bazel --output_base=..some_empty_directory.. aquery "deps(...)" --repository_cache=..place_to_store_downloaded_artifacts_for_offline_builds...

@hzeller
Copy link

hzeller commented Apr 12, 2023

Ping - I just hit the same snag while attempting to use bazel in a packaging context (where it is typically not allowed to connect to the network). While the work-around with bazel aquery "deps(...)" seems to work (thanks @ljessendk !), it would require less workaround-wizardry if bazel fetch would work correctly.

@layus
Copy link
Contributor

layus commented Oct 5, 2023

Still an issue. Happened to me while building bazel itself. You cannot bazel fetch because some repositories fail due to broken config.

I wonder is fetch has the right semantics, or any valid semantics. I see two main ways to use fetch

  1. To get all the dependencies of a configured target, which is useful when you want to build offline a target in a known future configuration, and
  2. To get all the potential dependencies of a target, to be able to build it later in any possible configuration.

The aquery trick above only works for case 1 (which is the one I need 🙏), but this bug remains valid for the intended use case of fetch, which is 2. You can tell that because fetch does not take any configuration flags for example.
And it seems that in this case the fetch/query logic misses some dependencies that are only pulled at configuration time, (and not needed for query apparently), but are still needed for offline builds. The issue that led me here is that fetch also pulls invalid/ill-defined repos because it lacks any configuration. I have opened another issue for that #19736.

Maybe it is impossible to have a generic fetch, as some external dependencies may not even be available in some circumstances, like MacOS stuff being available only on their machines, or debian stuff only on debian machines. In that case, does it make sense to have fetch ? Or should we add --keep_going to fetch and move on ?

See also googleapis/google-cloud-cpp#6140,

@SalmaSamy
Copy link
Contributor

Hello,

We've re-implemented this feature with bzlmod, and the fetch --all functionality should now operate as intended, with the option to force-fetch if necessary. This update has already been incorporated into the latest Bazel version (head) and will be included in our upcoming release, version 7.0.0.

For additional information, you can refer to our GitHub issue.

We encourage you to give it a try and, should you encounter any issues, please don't hesitate to report them.

Best regards

SalmaSamy added a commit that referenced this issue Feb 29, 2024
Context:
- Traditional query relies on the initial loading phase of the build, this lacks the context of build configurations (flags, select() logic), leading to potentially inaccurate or over-inclusive dependency listings.

- cquery executes after the analysis phase, where Bazel has resolved configurations and determined how options influence target definitions. This allows cquery to provide the dependencies truly needed for a build under the current settings.

Considering these differences, I'm updating fetch target logic to rely on cquery instead. This ensures that all necessary repositories are fetched for an offline build while avoiding potential over-fetching

PiperOrigin-RevId: 611455579
Change-Id: I2a954476c06182fd9eb78ad86def7bd72f04074a

# Conflicts:
#	src/main/java/com/google/devtools/build/lib/query2/cquery/ConfiguredTargetQueryEnvironment.java
meteorcloudy pushed a commit to meteorcloudy/bazel that referenced this issue Mar 5, 2024
Context:
- Traditional query relies on the initial loading phase of the build, this lacks the context of build configurations (flags, select() logic), leading to potentially inaccurate or over-inclusive dependency listings.

- cquery executes after the analysis phase, where Bazel has resolved configurations and determined how options influence target definitions. This allows cquery to provide the dependencies truly needed for a build under the current settings.

Considering these differences, I'm updating fetch target logic to rely on cquery instead. This ensures that all necessary repositories are fetched for an offline build while avoiding potential over-fetching

PiperOrigin-RevId: 611455579
Change-Id: I2a954476c06182fd9eb78ad86def7bd72f04074a
meteorcloudy pushed a commit to meteorcloudy/bazel that referenced this issue Mar 5, 2024
Context:
- Traditional query relies on the initial loading phase of the build, this lacks the context of build configurations (flags, select() logic), leading to potentially inaccurate or over-inclusive dependency listings.

- cquery executes after the analysis phase, where Bazel has resolved configurations and determined how options influence target definitions. This allows cquery to provide the dependencies truly needed for a build under the current settings.

Considering these differences, I'm updating fetch target logic to rely on cquery instead. This ensures that all necessary repositories are fetched for an offline build while avoiding potential over-fetching

PiperOrigin-RevId: 611455579
Change-Id: I2a954476c06182fd9eb78ad86def7bd72f04074a
meteorcloudy pushed a commit to meteorcloudy/bazel that referenced this issue Mar 5, 2024
Context:
- Traditional query relies on the initial loading phase of the build, this lacks the context of build configurations (flags, select() logic), leading to potentially inaccurate or over-inclusive dependency listings.

- cquery executes after the analysis phase, where Bazel has resolved configurations and determined how options influence target definitions. This allows cquery to provide the dependencies truly needed for a build under the current settings.

Considering these differences, I'm updating fetch target logic to rely on cquery instead. This ensures that all necessary repositories are fetched for an offline build while avoiding potential over-fetching

PiperOrigin-RevId: 611455579
Change-Id: I2a954476c06182fd9eb78ad86def7bd72f04074a
@iancha1992
Copy link
Member

A fix for this issue has been included in Bazel 7.1.0 RC2. Please test out the release candidate and report any issues as soon as possible.
If you're using Bazelisk, you can point to the latest RC by setting USE_BAZEL_VERSION=7.1.0rc2. Thanks!

SalmaSamy added a commit that referenced this issue Mar 28, 2024
Context:
- Traditional query relies on the initial loading phase of the build, this lacks the context of build configurations (flags, select() logic), leading to potentially inaccurate or over-inclusive dependency listings.

- cquery executes after the analysis phase, where Bazel has resolved configurations and determined how options influence target definitions. This allows cquery to provide the dependencies truly needed for a build under the current settings.

Considering these differences, I'm updating fetch target logic to rely on cquery instead. This ensures that all necessary repositories are fetched for an offline build while avoiding potential over-fetching

PiperOrigin-RevId: 611455579
Change-Id: I2a954476c06182fd9eb78ad86def7bd72f04074a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P2 We'll consider working on this in future. (Assignee optional) team-ExternalDeps External dependency handling, remote repositiories, WORKSPACE file. type: bug
Projects
None yet
Development

No branches or pull requests

10 participants