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

sh_binary's data dependencies are not triggered during the build #15043

Closed
linzhp opened this issue Mar 15, 2022 · 11 comments
Closed

sh_binary's data dependencies are not triggered during the build #15043

linzhp opened this issue Mar 15, 2022 · 11 comments
Labels
P3 We're not considering working on this, but happy to review a PR. (No assignee) team-Rules-Server Issues for serverside rules included with Bazel type: bug

Comments

@linzhp
Copy link
Contributor

linzhp commented Mar 15, 2022

Description of the problem / feature request:

When a sh_binary has a target in the data attribute, the target is not built automatically when the sh_binary target is built.

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

  • Check out rules_docker
  • bazel clean
  • bazel build //docs:update
  • ls bazel-bin/docs/container.md_
    Although bazel-bin/docs/container.md_ is the output of //docs:container_doc, which is depended by //docs:update, it is not built.

What operating system are you running Bazel on?

macOS

What's the output of bazel info release?

release 5.0.0-homebrew

@fmeum
Copy link
Collaborator

fmeum commented Mar 15, 2022

I think that the root cause is a more fundamental inconsistency between how Starlark and native rules collect and declare data dependencies:

As per the Starlark rules guidelines, Starlark rules should handle targets in data-like attributes by merging in both the files produced by these targets as well as their default runfiles. As a result, Starlark rules often return some files in their DefaultInfo's files attribute that are not also contained in its runfiles.

However, native rules only collect transitive runfiles and not the output files from rule targets (see addTargetIncludingFileTargets, which only adds output files for file targets).

@linzhp Could you check whether #15052 fixes the issue? It adapts the native logic to collect runfiles in the same way as is recommended for Starlark rules, but of course that may very well regress performance for native rules in general. I do not know whether changing this behavior that is so fundamental to Bazel's native rules is realistically possible. But if it doesn't fail too many tests, maybe there is a way to restrict it to Starlark rule targets or otherwise limit its impact on native rule targets.

@oquenchil oquenchil added type: bug P3 We're not considering working on this, but happy to review a PR. (No assignee) team-Rules-Server Issues for serverside rules included with Bazel labels Mar 16, 2022
@linzhp
Copy link
Contributor Author

linzhp commented Mar 19, 2022

Sorry for the delay. I pull from #15052, and built //src:bazel-dev. But when I used the built binary to build //docs:update of rules_docker, I got:

DEBUG: /private/var/tmp/_bazel_zplin/d6323f9e3146540840037c805ccd73ff/external/bazel_toolchains/rules/rbe_repo/version_check.bzl:59:14: 
Current running Bazel is not a release version and one was not defined explicitly in rbe_autoconfig target. Falling back to '4.0.0'
ERROR: /private/var/tmp/_bazel_zplin/d6323f9e3146540840037c805ccd73ff/external/bazel_tools/src/tools/launcher/BUILD:9:14: While resolving toolchains for target @bazel_tools//src/tools/launcher:launcher: No matching toolchains found for types @bazel_tools//tools/cpp:toolchain_type. Maybe --incompatible_use_cc_configure_from_rules_cc has been flipped and there is no default C++ toolchain added in the WORKSPACE file? See https://github.com/bazelbuild/bazel/issues/10134 for details and migration instructions.
ERROR: Analysis of target '//docs:update' failed; build aborted: 
INFO: Elapsed time: 6.538s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (50 packages loaded, 309 targets configured)

@fmeum
Copy link
Collaborator

fmeum commented Mar 19, 2022

@linzhp The build succeeds for me following the instructions from your initial post. Are you on Linux and does bazel build //... succeed for you on the repo on the commit prior to mine? The change may cause building new transitive dependencies for //docs:update, but if those weren't broken before, they shouldn't be now. The result of rerunning the command with --toolchain_resolution_debug='.*' would also be useful to figure out what broke.

@linzhp
Copy link
Contributor Author

linzhp commented Mar 19, 2022

Switched to macOS for Intel and tried your fix again. It worked. Thanks!

I was on macOS for Apple Silicon before. The commit before yours fails too, but Bazel 5.0.0 works. I saw:

INFO: ToolchainResolution:     Type @bazel_tools//tools/cpp:toolchain_type: target platform @local_config_platform//:host: Rejected toolchain @local_config_cc//:cc-compiler-darwin_arm64; mismatching values: arm64

@fmeum
Copy link
Collaborator

fmeum commented Mar 20, 2022

That looks more like an unrelated regression. Could you create a separate issue and perhaps rerun the test with 5.1.0rc2? 5.1.0 will be released soon.

fmeum added a commit to fmeum/bazel-skylib that referenced this issue Apr 14, 2022
copy_file and write_file currently include the created file in their
runfiles even if it is not executable, which makes every rule depending
on it have the file as a runfile (e.g. a `cc_library` depending on a
copied header file via the hdrs attribute).

In an ideal world, according to
https://docs.bazel.build/versions/main/skylark/rules.html#runfiles-features-to-avoid,
copy_file would not need to specify any runfiles in the `DefaultInfo` it
returns. However, due to the existence of rules with legacy behavior,
this would break compatibility (actually, already with `sh_test` in
skylib's unit tests), see
bazelbuild/bazel#15043.

As a compromise that preserves compatibility with legacy rules but
nevertheless cleans up the runfiles tree of depending rules, use the
`data_runfiles` attribute of `DefaultInfo` if the copied file is not
executable.
@jonathan-enf
Copy link

Is this bug a dup (though more clearly restating the issue) of #12348 ?

@fmeum
Copy link
Collaborator

fmeum commented Jul 6, 2022

Is this bug a dup (though more clearly restating the issue) of #12348 ?

Pretty sure it is.

fmeum added a commit to fmeum/rules_jvm_external that referenced this issue Oct 19, 2022
Due to bazelbuild/bazel#15043, Bazel's native
rule such as `sh_test` do not pick up `files` in `DefaultInfo` for a
target in `data`. This can lead to the unexplicable absence of the jar
generated by `maven_project_jar` and hence `java_export` from runfiles.

Until the upstream bug has been fixed, this is worked around by adding
the files to `data_runfiles`.
fmeum added a commit to fmeum/rules_jvm_external that referenced this issue Oct 19, 2022
Due to bazelbuild/bazel#15043, Bazel's native
rule such as `sh_test` do not pick up `files` in `DefaultInfo` for a
target in `data`. This can lead to the unexplicable absence of the jar
generated by `maven_project_jar` and hence `java_export` from runfiles.

Until the upstream bug has been fixed, this is worked around by adding
the files to `data_runfiles`.
shs96c pushed a commit to bazel-contrib/rules_jvm_external that referenced this issue Oct 19, 2022
Due to bazelbuild/bazel#15043, Bazel's native
rule such as `sh_test` do not pick up `files` in `DefaultInfo` for a
target in `data`. This can lead to the unexplicable absence of the jar
generated by `maven_project_jar` and hence `java_export` from runfiles.

Until the upstream bug has been fixed, this is worked around by adding
the files to `data_runfiles`.
@brandjon
Copy link
Member

brandjon commented Nov 4, 2022

Dupping against #12348.

@brandjon
Copy link
Member

brandjon commented Nov 4, 2022

Sorry, I missed that #15052 is being actively developed, so I'll keep this issue alive as the author's preferred tracking bug.

@brandjon brandjon reopened this Nov 4, 2022
philsc added a commit to philsc/rules_python that referenced this issue Nov 5, 2022
Right now the command errors out on fresh clones or after a `bazel
clean`.

    $ bazel run //docs:update
    cp: cannot stat 'bazel-bin/docs/packaging.md_': No such file or directory
    cp: cannot stat 'bazel-bin/docs/pip.md_': No such file or directory
    cp: cannot stat 'bazel-bin/docs/pip_repository.md_': No such file or directory
    cp: cannot stat 'bazel-bin/docs/python.md_': No such file or directory

I submitted bazelbuild/stardoc#139 to fix this. @brandjon pointed out
that this should just work as-is, but doesn't because of
bazelbuild/bazel#15043. Until the bazel bug is addressed, we can make
`//docs:update` work by pulling in the latest stardoc version.

One side effect of this patch is that the generated documentation
itself changed a decent amount.

Now the tool works again without errors even after a fresh clone or a
`bazel clean`

    $ bazel run //docs:update
    'bazel-bin/docs/packaging.md_' -> 'docs/packaging.md'
    'bazel-bin/docs/pip.md_' -> 'docs/pip.md'
    'bazel-bin/docs/pip_repository.md_' -> 'docs/pip_repository.md'
    'bazel-bin/docs/python.md_' -> 'docs/python.md'
fmeum added a commit to fmeum/bazel that referenced this issue Nov 7, 2022
Guidelines for Starlark rules suggest that `data`-like attributes on
rules should always merge the default outputs of rule targets into the
transitive runfiles. See:
https://docs.bazel.build/versions/main/skylark/rules.html#runfiles-features-to-avoid

As a result, Starlark rules generally don't (and shouldn't) explicitly
include their default outputs into their runfiles. Before this commit,
native rules did not merge these outputs in the same way as idiomatic
Starlark rules, which led to unexpectedly absent runfiles.

Fixes bazelbuild#15043

Closes bazelbuild#15052.

PiperOrigin-RevId: 486663801
Change-Id: I4a30b8b8a4dfc84bf4de27fd7894dd48e795c081
fmeum added a commit to fmeum/bazel that referenced this issue Nov 7, 2022
Guidelines for Starlark rules suggest that `data`-like attributes on
rules should always merge the default outputs of rule targets into the
transitive runfiles. See:
https://docs.bazel.build/versions/main/skylark/rules.html#runfiles-features-to-avoid

As a result, Starlark rules generally don't (and shouldn't) explicitly
include their default outputs into their runfiles. Before this commit,
native rules did not merge these outputs in the same way as idiomatic
Starlark rules, which led to unexpectedly absent runfiles.

Fixes bazelbuild#15043

Closes bazelbuild#15052.

PiperOrigin-RevId: 486663801
Change-Id: I4a30b8b8a4dfc84bf4de27fd7894dd48e795c081
fmeum added a commit to fmeum/bazel that referenced this issue Nov 7, 2022
Guidelines for Starlark rules suggest that `data`-like attributes on
rules should always merge the default outputs of rule targets into the
transitive runfiles. See:
https://docs.bazel.build/versions/main/skylark/rules.html#runfiles-features-to-avoid

As a result, Starlark rules generally don't (and shouldn't) explicitly
include their default outputs into their runfiles. Before this commit,
native rules did not merge these outputs in the same way as idiomatic
Starlark rules, which led to unexpectedly absent runfiles.

Fixes bazelbuild#15043

Closes bazelbuild#15052.

PiperOrigin-RevId: 486663801
Change-Id: I4a30b8b8a4dfc84bf4de27fd7894dd48e795c081
fmeum added a commit to fmeum/bazel that referenced this issue Nov 7, 2022
Guidelines for Starlark rules suggest that `data`-like attributes on
rules should always merge the default outputs of rule targets into the
transitive runfiles. See:
https://docs.bazel.build/versions/main/skylark/rules.html#runfiles-features-to-avoid

As a result, Starlark rules generally don't (and shouldn't) explicitly
include their default outputs into their runfiles. Before this commit,
native rules did not merge these outputs in the same way as idiomatic
Starlark rules, which led to unexpectedly absent runfiles.

Fixes bazelbuild#15043

Closes bazelbuild#15052.

PiperOrigin-RevId: 486663801
Change-Id: I4a30b8b8a4dfc84bf4de27fd7894dd48e795c081
@rickeylev
Copy link
Contributor

As an FYI, there may be some dependencies on this behavior between the Python rules and some other Google-internal rules. i.e. enabling the flag introduced by this will likely show failures in the Google global regression tests (TGP). See the large comment block in blaze/python/common.bzl#collect_runfiles for more details. The gist, though, is some Google-internal rules have different default outputs vs data/default runfiles, and have come to rely on this so that otherwise unused outputs (some of which can be very large) don't get included in the runfiles.

@fmeum
Copy link
Collaborator

fmeum commented Nov 8, 2022

@rickeylev Thanks for mentioning this. I added a workaround to the migration guide at #16654. Could that even work for Google?

ShreeM01 pushed a commit that referenced this issue Nov 8, 2022
Guidelines for Starlark rules suggest that `data`-like attributes on
rules should always merge the default outputs of rule targets into the
transitive runfiles. See:
https://docs.bazel.build/versions/main/skylark/rules.html#runfiles-features-to-avoid

As a result, Starlark rules generally don't (and shouldn't) explicitly
include their default outputs into their runfiles. Before this commit,
native rules did not merge these outputs in the same way as idiomatic
Starlark rules, which led to unexpectedly absent runfiles.

Fixes #15043

Closes #15052.

PiperOrigin-RevId: 486663801
Change-Id: I4a30b8b8a4dfc84bf4de27fd7894dd48e795c081
rickeylev pushed a commit to bazelbuild/rules_python that referenced this issue Nov 19, 2022
Fix //docs:update

Also regenerates docs with the new stardoc version.

Right now the command errors out on fresh clones or after a `bazel
clean`.

    $ bazel run //docs:update
    cp: cannot stat 'bazel-bin/docs/packaging.md_': No such file or directory
    cp: cannot stat 'bazel-bin/docs/pip.md_': No such file or directory
    cp: cannot stat 'bazel-bin/docs/pip_repository.md_': No such file or directory
    cp: cannot stat 'bazel-bin/docs/python.md_': No such file or directory

I submitted bazelbuild/stardoc#139 to fix this. @brandjon pointed out
that this should just work as-is, but doesn't because of
bazelbuild/bazel#15043. Until the bazel bug is addressed, we can make
`//docs:update` work by pulling in the latest stardoc version.

One side effect of this patch is that the generated documentation
itself changed a decent amount.

Now the tool works again without errors even after a fresh clone or a
`bazel clean`

    $ bazel run //docs:update
    'bazel-bin/docs/packaging.md_' -> 'docs/packaging.md'
    'bazel-bin/docs/pip.md_' -> 'docs/pip.md'
    'bazel-bin/docs/pip_repository.md_' -> 'docs/pip_repository.md'
    'bazel-bin/docs/python.md_' -> 'docs/python.md'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P3 We're not considering working on this, but happy to review a PR. (No assignee) team-Rules-Server Issues for serverside rules included with Bazel type: bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants