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

Runfiles libraries don't find runfiles in directories that are themselves runfiles when using manifest #14336

Closed
fmeum opened this issue Nov 26, 2021 · 1 comment
Labels
team-Rules-Server Issues for serverside rules included with Bazel untriaged

Comments

@fmeum
Copy link
Collaborator

fmeum commented Nov 26, 2021

Description of the problem / feature request:

In the way they are currently implemented, the Bazel runfiles libraries at @bazel_tools//tools/*/runfiles do not always find the identical set of runfiles when using a manifest compared to when using a runfiles directory.

Specificially, if a target has runfiles foo (a directory) and foo/a.txt (a file in that directory), then Runfiles#filterListForObscuringSymlinks will filter out foo/a.txt. As a result:

  1. when using a directory-based runfiles lookup, foo/a.txt will be found since the symlink foo resolves to the correct directory containing a.txt;
  2. when using a manifest-based runfiles lookup, foo/a.txt is not found since it is not listed in the manifest, only foo itself is.

Note that it is pretty easy to pick up both a directory and a file contained in that directory as runfiles through transitive dependencies and everything will work well on Linux/macOS, only to non-obviously break on Windows. I encountered this issue while working on a ruleset that would allow for compile-time checked rlocation lookups for C++ and Java, but found the current issue to block this effort.

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

#!/usr/bin/env bash
touch WORKSPACE

mkdir -p foo
touch foo/a.txt

cat <<EOF >main.cc
int main() {}
EOF

cat <<EOF >BUILD.bazel
cc_binary(
    name = "main",
    data = [
        "foo",
        "foo/a.txt",
    ],
    srcs = ["main.cc"],
)
EOF

bazel build //:main
cat bazel-bin/main.runfiles_manifest

correctly prints

__main__/foo /tmp/repro/foo
__main__/main /home/user/.cache/bazel/_bazel_user/.../execroot/__main__/bazel-out/k8-fastbuild/bin/main

When using @bazel_tools//tools/cpp/runfiles with the runfiles manifest, e.g. on Windows, then Rlocation("foo/a.txt") will return an empty string instead of the correct path for the declared runfile.

What operating system are you running Bazel on?

Any, but this mostly applies to Windows.

What's the output of bazel info release?

Any version is affected, including current master.

 Have you found anything relevant by searching the web?

No.

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

I prepared a PR (#14335) that extends the C++, Java, and Python runfiles libraries so that they also find runfiles within runfiles directories when using the runfiles manifest. I could also fix this for the bash implementation, but would like to wait for general feedback before I start working on this.

fmeum added a commit to fmeum/runfiles that referenced this issue Nov 26, 2021
When a target has a runfile that is contained in a directory that is
itself one of its runfiles, the runfile will be shadowed by the
SymlinkEntry for the directory. While this still allows to resolve the
file in the runfiles symlink tree, a manifest-based lookup will fail.

This PR extends the lookup logic to also find runfiles contained within
directories that are themselves runfiles. It does so by searching the
manifest not only for the exact provided rlocation path, but also for
all path prefixes. If a prefix is looked up successfully, the
corresponding suffix is resolved relative to the looked up path.

See bazelbuild/bazel#14336 for more context.
@sventiffe sventiffe added team-Rules-Server Issues for serverside rules included with Bazel untriaged labels Dec 8, 2021
fmeum added a commit to fmeum/runfiles that referenced this issue Dec 30, 2021
When a target has a runfile that is contained in a directory that is
itself one of its runfiles, the runfile will be shadowed by the
SymlinkEntry for the directory. While this still allows to resolve the
file in the runfiles symlink tree, a manifest-based lookup will fail.

This PR extends the lookup logic to also find runfiles contained within
directories that are themselves runfiles. It does so by searching the
manifest not only for the exact provided rlocation path, but also for
all path prefixes. If a prefix is looked up successfully, the
corresponding suffix is resolved relative to the looked up path.

See bazelbuild/bazel#14336 for more context.
fmeum added a commit to fmeum/runfiles that referenced this issue Feb 5, 2022
When a target has a runfile that is contained in a directory that is
itself one of its runfiles, the runfile will be shadowed by the
SymlinkEntry for the directory. While this still allows to resolve the
file in the runfiles symlink tree, a manifest-based lookup will fail.

This PR extends the lookup logic to also find runfiles contained within
directories that are themselves runfiles. It does so by searching the
manifest not only for the exact provided rlocation path, but also for
all path prefixes. If a prefix is looked up successfully, the
corresponding suffix is resolved relative to the looked up path.

See bazelbuild/bazel#14336 for more context.
fmeum added a commit to fmeum/runfiles that referenced this issue Feb 5, 2022
When a target has a runfile that is contained in a directory that is
itself one of its runfiles, the runfile will be shadowed by the
SymlinkEntry for the directory. While this still allows to resolve the
file in the runfiles symlink tree, a manifest-based lookup will fail.

This PR extends the lookup logic to also find runfiles contained within
directories that are themselves runfiles. It does so by searching the
manifest not only for the exact provided rlocation path, but also for
all path prefixes. If a prefix is looked up successfully, the
corresponding suffix is resolved relative to the looked up path.

See bazelbuild/bazel#14336 for more context.
@fmeum
Copy link
Collaborator Author

fmeum commented Feb 7, 2022

@bazel-io fork

fmeum added a commit to fmeum/bazel that referenced this issue Feb 7, 2022
When a target has a runfile that is contained in a directory that is itself one of its runfiles, the runfile will be shadowed by the `SymlinkEntry` for the directory. While this still allows to resolve the file in the runfiles symlink tree, a manifest-based lookup will fail. Since the manifest is used to create the symlink tree for which it is important that no path is a prefix of another, this can only be fixed in the runfiles libraries.

This PR extends the lookup logic of the Bash, C++, Java, and Python runfiles libraries to also find runfiles contained within directories that are themselves runfiles. It does so by searching the manifest not only for the exact provided rlocation path, but also for all path prefixes. If a prefix is looked up successfully, the corresponding suffix is resolved relative to the looked up path.

Fixes bazelbuild#14336.

Closes bazelbuild#14335.

PiperOrigin-RevId: 426894517
Wyverald pushed a commit that referenced this issue Feb 7, 2022
When a target has a runfile that is contained in a directory that is itself one of its runfiles, the runfile will be shadowed by the `SymlinkEntry` for the directory. While this still allows to resolve the file in the runfiles symlink tree, a manifest-based lookup will fail. Since the manifest is used to create the symlink tree for which it is important that no path is a prefix of another, this can only be fixed in the runfiles libraries.

This PR extends the lookup logic of the Bash, C++, Java, and Python runfiles libraries to also find runfiles contained within directories that are themselves runfiles. It does so by searching the manifest not only for the exact provided rlocation path, but also for all path prefixes. If a prefix is looked up successfully, the corresponding suffix is resolved relative to the looked up path.

Fixes #14336.

Closes #14335.

PiperOrigin-RevId: 426894517
fmeum added a commit to fmeum/runfiles that referenced this issue Mar 9, 2022
When a target has a runfile that is contained in a directory that is
itself one of its runfiles, the runfile will be shadowed by the
SymlinkEntry for the directory. While this still allows to resolve the
file in the runfiles symlink tree, a manifest-based lookup will fail.

This PR extends the lookup logic to also find runfiles contained within
directories that are themselves runfiles. It does so by searching the
manifest not only for the exact provided rlocation path, but also for
all path prefixes. If a prefix is looked up successfully, the
corresponding suffix is resolved relative to the looked up path.

See bazelbuild/bazel#14336 for more context.
fmeum added a commit to fmeum/runfiles that referenced this issue Mar 22, 2022
When a target has a runfile that is contained in a directory that is
itself one of its runfiles, the runfile will be shadowed by the
SymlinkEntry for the directory. While this still allows to resolve the
file in the runfiles symlink tree, a manifest-based lookup will fail.

This PR extends the lookup logic to also find runfiles contained within
directories that are themselves runfiles. It does so by searching the
manifest not only for the exact provided rlocation path, but also for
all path prefixes. If a prefix is looked up successfully, the
corresponding suffix is resolved relative to the looked up path.

See bazelbuild/bazel#14336 for more context.
fmeum added a commit to fmeum/runfiles that referenced this issue Mar 24, 2022
When a target has a runfile that is contained in a directory that is
itself one of its runfiles, the runfile will be shadowed by the
SymlinkEntry for the directory. While this still allows to resolve the
file in the runfiles symlink tree, a manifest-based lookup will fail.

This PR extends the lookup logic to also find runfiles contained within
directories that are themselves runfiles. It does so by searching the
manifest not only for the exact provided rlocation path, but also for
all path prefixes. If a prefix is looked up successfully, the
corresponding suffix is resolved relative to the looked up path.

See bazelbuild/bazel#14336 for more context.
phst added a commit to phst/rules_elisp that referenced this issue Apr 17, 2022
phst added a commit to phst/rules_elisp that referenced this issue Apr 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
team-Rules-Server Issues for serverside rules included with Bazel untriaged
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants