Skip to content

Make pkg_install work without "runfiles" (Windows default)#984

Merged
tonyaiuto merged 1 commit intobazelbuild:mainfrom
rdesgroppes:make-pkg-install-work-when-runfiles-disabled
Nov 13, 2025
Merged

Make pkg_install work without "runfiles" (Windows default)#984
tonyaiuto merged 1 commit intobazelbuild:mainfrom
rdesgroppes:make-pkg-install-work-when-runfiles-disabled

Conversation

@rdesgroppes
Copy link
Copy Markdown
Contributor

@rdesgroppes rdesgroppes commented Nov 7, 2025

On Windows, pkg_install wouldn't work out of the box without passing --enable_runfiles to Bazel:

windows> bazel run [redacted]//:install -- --destdir=d:\est
[...]
INFO: Running command line: [redacted]/install.exe <args omitted>
Traceback (most recent call last):
  File "[redacted]\install_install_script.py", line 307, in <module>
    sys.exit(main(sys.argv))
             ^^^^^^^^^^^^^^
  File "[redacted]\install_install_script.py", line 299, in main
    installer.include_manifest_path(f)
  File "[redacted]\install_install_script.py", line 182, in include_manifest_path
    with open(path, 'r') as fh:
         ^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '../[redacted]/install_install_script-install-manifest.json'

In order to accomodate the various use cases (build, test and run actions; enabled and disabled runfiles), the present change proposes to leverage rules_python's "runfiles" lookup library: https://rules-python.readthedocs.io/en/latest/api/py/runfiles/runfiles.runfiles.html

For good measure, the change also enables bazel test //tests/install/... in CI for Windows.

This might close #387.

@rdesgroppes rdesgroppes force-pushed the make-pkg-install-work-when-runfiles-disabled branch 2 times, most recently from 424ea34 to a8e9790 Compare November 7, 2025 01:26
On Windows, `pkg_install` wouldn't work out of the box without passing
`--enable_runfiles` to Bazel:
```
windows> bazel run [redacted]//:install -- --destdir=d:\est
[...]
INFO: Running command line: [redacted]/install.exe <args omitted>
Traceback (most recent call last):
  File "[redacted]\install_install_script.py", line 307, in <module>
    sys.exit(main(sys.argv))
             ^^^^^^^^^^^^^^
  File "[redacted]\install_install_script.py", line 299, in main
    installer.include_manifest_path(f)
  File "[redacted]\install_install_script.py", line 182, in include_manifest_path
    with open(path, 'r') as fh:
         ^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '../[redacted]/install_install_script-install-manifest.json'
```

In order to accomodate the various use cases (`build`, `test` and `run`
actions; enabled and disabled runfiles), the present change proposes to
leverage `rules_python`'s "runfiles" lookup library:
https://rules-python.readthedocs.io/en/latest/api/py/runfiles/runfiles.runfiles.html

For good measure, the change also enables
`bazel test //tests/install/...` in CI for Windows.

This might close bazelbuild#387.
@rdesgroppes rdesgroppes force-pushed the make-pkg-install-work-when-runfiles-disabled branch from a8e9790 to 57f4b7d Compare November 7, 2025 10:04
@rdesgroppes rdesgroppes changed the title Make pkg_install work without runfiles (Windows default) Make pkg_install work without "runfiles" (Windows default) Nov 7, 2025
Copy link
Copy Markdown
Collaborator

@cgrindel cgrindel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable to me. I will wait to merge so that @tonyaiuto can take a look.

@tonyaiuto tonyaiuto merged commit 38f29af into bazelbuild:main Nov 13, 2025
3 checks passed
@rdesgroppes rdesgroppes deleted the make-pkg-install-work-when-runfiles-disabled branch January 16, 2026 12:04
rdesgroppes added a commit to rdesgroppes/rules_pkg that referenced this pull request Feb 5, 2026
When a `pkg_install` rule in an external repository references files
from another repository, the installer would fail at runtime by
attempting to resolve all files relative to its repository rather than
each file's source repository.

Example failure (`extrepo`: external repository installing file from
main repository):
```
bazel run @extrepo//:install -- --destdir=/tmp/test
[...]
FileNotFoundError: [Errno 2] No such file or directory:
  '.../runfiles/+_repo_rules+extrepo/some-path/extrepo/file-in-main'
```

The file should be resolved against the main repository (`_main`) but
is incorrectly looked up from the installer's repository runfiles
(`+_repo_rules+extrepo`).

The solution proposed here consists in extending the manifest to track
each file's source repository and use this information during
installation to resolve files against the correct repository.

It adds a `repository` field to manifest entries using:
- `Label.repo_name`
  ([canonical](https://bazel.build/rules/lib/builtins/Label#repo_name))
  when available for the source file,
- otherwise `ctx.workspace_name` when no
  [owner](https://bazel.build/rules/lib/builtins/File#owner)
  or `Label.repo_name` is
  [empty](https://rules-python.readthedocs.io/en/latest/api/py/runfiles/runfiles.runfiles.html#runfiles.runfiles.Runfiles.CurrentRepository).

Testing:
- `//tests/install:install_test` includes new `CrossRepoInstallTest`,
- real-world validation: `bazel run @extrepo//:install` successfully,
- verified both on Ubuntu Linux and Windows as well.

tl;dr: this change builds on bazelbuild#984 which introduced the `locate()` helper
and the `runfiles` infrastructure. That PR fixed Windows compatibility
by enabling runfiles-less operation; this change extends it to support
files from external repositories.
rdesgroppes added a commit to rdesgroppes/rules_pkg that referenced this pull request Feb 5, 2026
When a `pkg_install` rule in an external repository references files
from another repository, the installer would fail at runtime by
attempting to resolve all files relative to its repository rather than
each file's own repository.

Example failure (`extrepo`: external repository installing file from
main repository):
```
bazel run @extrepo//:install -- --destdir=/tmp/test
[...]
FileNotFoundError: [Errno 2] No such file or directory:
  '.../runfiles/+_repo_rules+extrepo/some-path/extrepo/file-in-main'
```

The file should be resolved against the main repository (`_main`) but
is incorrectly looked up from the installer's repository runfiles
(`+_repo_rules+extrepo`).

The solution proposed here consists in extending the manifest to track
each file's source repository and use this information during
installation to resolve files against the correct repository.

It adds a `repository` field to manifest entries using:
- `Label.repo_name`
  ([canonical](https://bazel.build/rules/lib/builtins/Label#repo_name))
  when available for the source file,
- otherwise `ctx.workspace_name` when no
  [owner](https://bazel.build/rules/lib/builtins/File#owner)
  or `Label.repo_name` is
  [empty](https://rules-python.readthedocs.io/en/latest/api/py/runfiles/runfiles.runfiles.html#runfiles.runfiles.Runfiles.CurrentRepository).

Testing:
- `//tests/install:install_test` includes new `CrossRepoInstallTest`,
- real-world validation: `bazel run @extrepo//:install` successfully,
- verified both on Ubuntu Linux and Windows as well.

tl;dr: this change builds on bazelbuild#984 which introduced the `locate()` helper
and the `runfiles` infrastructure. That PR fixed Windows compatibility
by enabling runfiles-less operation; this change extends it to support
files from external repositories.
rdesgroppes added a commit to rdesgroppes/rules_pkg that referenced this pull request Feb 5, 2026
When a `pkg_install` rule in an external repository references files
from another repository, the installer would fail at runtime by
attempting to resolve all files relative to its repository rather than
each file's own repository.

Example failure (`extrepo`: external repository installing file from
main repository):
```
bazel run @extrepo//:install -- --destdir=/tmp/test
[...]
FileNotFoundError: [Errno 2] No such file or directory:
  '.../runfiles/+_repo_rules+extrepo/some-path/extrepo/file-in-main'
```

The file should be resolved against the main repository (`_main`) but
is incorrectly looked up from the installer's repository runfiles
(`+_repo_rules+extrepo`).

The solution proposed here consists in extending the manifest to track
each file's own repository and use this information during installation
to resolve files against the correct repository.

It adds a `repository` field to manifest entries using:
- `Label.repo_name`
  ([canonical](https://bazel.build/rules/lib/builtins/Label#repo_name))
  when available for the source file,
- otherwise `ctx.workspace_name` when no
  [owner](https://bazel.build/rules/lib/builtins/File#owner)
  or `Label.repo_name` is
  [empty](https://rules-python.readthedocs.io/en/latest/api/py/runfiles/runfiles.runfiles.html#runfiles.runfiles.Runfiles.CurrentRepository).

Testing:
- `//tests/install:install_test` includes new `CrossRepoInstallTest`,
- real-world validation: `bazel run @extrepo//:install` successfully,
- verified both on Ubuntu Linux and Windows as well.

tl;dr: this change builds on bazelbuild#984 which introduced the `locate()` helper
and the `runfiles` infrastructure. That PR fixed Windows compatibility
by enabling runfiles-less operation; this change extends it to support
files from external repositories.
rdesgroppes added a commit to rdesgroppes/rules_pkg that referenced this pull request Feb 6, 2026
tl;dr: this change builds on bazelbuild#984 which introduced the `locate()` helper
and the `runfiles` infrastructure. That PR fixed Windows compatibility
by enabling runfiles-less operation; this change extends it to support
files from cross-repository runfiles.

When a `pkg_install` rule in an external repository references files
from another repository, the installer would fail at runtime by
attempting to resolve all files relative to its repository rather than
each file's own repository.

Example failure (`extrepo`: external repository installing file from
main repository):
```
bazel run @extrepo//:install -- --destdir=/tmp/test
[...]
FileNotFoundError: [Errno 2] No such file or directory:
  '.../runfiles/+_repo_rules+extrepo/some-path/extrepo/file-in-main-repo'
```

The file should be resolved against the main repository (`_main`) but
is incorrectly looked up from the installer's repository runfiles
(`+_repo_rules+extrepo`).

The solution proposed here consists in extending the manifest to track
each file's own repository and use this information during installation
to resolve files against the correct repository runfiles.

It adds a `repository` field to manifest entries using:
- `Label.repo_name`
  ([canonical](https://bazel.build/rules/lib/builtins/Label#repo_name))
  when explicitly valued for the source file,
- otherwise `ctx.workspace_name` when no
  [owner](https://bazel.build/rules/lib/builtins/File#owner)
  or `Label.repo_name` is
  [empty](https://rules-python.readthedocs.io/en/latest/api/py/runfiles/runfiles.runfiles.html#runfiles.runfiles.Runfiles.CurrentRepository),
  denoting the main repository ("_main", as before).

Testing:
- `//tests/install:install_test` includes new `CrossRepoInstallTest`,
- `bazel run @extrepo//:install -- --destdir=/tmp/test` succeeds,
- verified the above on Ubuntu Linux and Windows as well.
rdesgroppes added a commit to rdesgroppes/rules_pkg that referenced this pull request Feb 6, 2026
tl;dr: this change builds on bazelbuild#984 which introduced the `locate()` helper
and the `runfiles` infrastructure. That PR fixed Windows compatibility
by enabling runfiles-less operation; this change extends it to support
cross-repository files.

When a `pkg_install` rule in an external repository references files
from another repository, the installer would fail at runtime by
attempting to resolve all files relative to its repository rather than
each file's own repository.

Example failure (`extrepo`: external repository installing file from
main repository):
```
bazel run @extrepo//:install -- --destdir=/tmp/test
[...]
FileNotFoundError: [Errno 2] No such file or directory:
  '.../runfiles/+_repo_rules+extrepo/some-path/extrepo/file-in-main-repo'
```

The file should be resolved against the main repository (`_main`) but
is incorrectly looked up from the installer's repository
(`+_repo_rules+extrepo`).

The solution proposed here consists in extending the manifest to track
each file's own repository and use this information during installation
to resolve files against the correct repository.

It adds a `repository` field to manifest entries using:
- `Label.repo_name`
  ([canonical](https://bazel.build/rules/lib/builtins/Label#repo_name))
  when explicitly valued for the source file,
- otherwise `ctx.workspace_name` when no
  [owner](https://bazel.build/rules/lib/builtins/File#owner)
  or `Label.repo_name` is
  [empty](https://rules-python.readthedocs.io/en/latest/api/py/runfiles/runfiles.runfiles.html#runfiles.runfiles.Runfiles.CurrentRepository),
  denoting the main repository ("_main", as before).

Testing:
- `//tests/install:install_test` includes new `CrossRepoInstallTest`,
- `bazel run @extrepo//:install -- --destdir=/tmp/test` would succeed,
- verified the above on Ubuntu Linux and Windows as well.
rdesgroppes added a commit to rdesgroppes/rules_pkg that referenced this pull request Feb 6, 2026
tl;dr: this change builds on bazelbuild#984 which introduced the `locate()` helper
and the `runfiles` infrastructure. That PR fixed Windows compatibility
by enabling runfiles-less operation; this change extends it to support
cross-repository files.

When a `pkg_install` rule in an external repository references files
from another repository, the installer would fail at runtime by
attempting to resolve all files relative to its repository rather than
each file's own repository.

Example failure (`extrepo`: external repository installing file from
main repository):
```
bazel run @extrepo//:install -- --destdir=/tmp/test
[...]
FileNotFoundError: [Errno 2] No such file or directory:
  '.../runfiles/+_repo_rules+extrepo/some-path/extrepo/file-in-main-repo'
```

The file should be resolved against the main repository (`_main`) but
is incorrectly looked up from the installer's repository
(`+_repo_rules+extrepo`).

The solution proposed here consists in extending the manifest to track
each file's own repository and use this information during installation
to resolve files against the correct repository.

It adds a `repository` field to manifest entries using:
- `Label.repo_name`
  ([canonical](https://bazel.build/rules/lib/builtins/Label#repo_name))
  when explicitly valued for the source file,
- otherwise `ctx.workspace_name` when no
  [owner](https://bazel.build/rules/lib/builtins/File#owner)
  or `Label.repo_name` is
  [empty](https://rules-python.readthedocs.io/en/latest/api/py/runfiles/runfiles.runfiles.html#runfiles.runfiles.Runfiles.CurrentRepository),
  denoting the main repository (`_main`, as before).

Testing:
- `//tests/install:install_test` includes new `CrossRepoInstallTest`,
- `bazel run @extrepo//:install -- --destdir=/tmp/test` case works,
- verified the above on Ubuntu Linux and Windows as well.
rdesgroppes added a commit to rdesgroppes/rules_pkg that referenced this pull request Feb 8, 2026
tl;dr: this change builds on bazelbuild#984 which introduced the `locate()` helper
and the `runfiles` infrastructure. That PR fixed Windows compatibility
by enabling runfiles-less operation; this change extends it to support
cross-repository files.

When a `pkg_install` rule in an external repository references files
from another repository, the installer would fail at runtime by
attempting to resolve all files relative to its repository rather than
each file's own repository.

Example failure (`extrepo`: external repository installing file from
main repository):
```
bazel run @extrepo//:install -- --destdir=/tmp/test
[...]
FileNotFoundError: [Errno 2] No such file or directory:
  '.../runfiles/+_repo_rules+extrepo/some-path/extrepo/file-in-main-repo'
```

The file should be resolved against the main repository (`_main`) but
is incorrectly looked up from the installer's repository
(`+_repo_rules+extrepo`).

The solution proposed here consists in extending the manifest to track
each file's own repository and use this information during installation
to resolve files against the correct repository.

It adds a `repository` field to manifest entries using:
- `Label.repo_name`
  ([canonical](https://bazel.build/rules/lib/builtins/Label#repo_name))
  when explicitly valued for the source file,
- otherwise `ctx.workspace_name` when no
  [owner](https://bazel.build/rules/lib/builtins/File#owner)
  or `Label.repo_name` is
  [empty](https://rules-python.readthedocs.io/en/latest/api/py/runfiles/runfiles.runfiles.html#runfiles.runfiles.Runfiles.CurrentRepository),
  denoting the main repository (`_main`, as before).

Testing:
- `//tests/install:install_test` includes new `CrossRepoInstallTest`,
- `bazel run @extrepo//:install -- --destdir=/tmp/test` case works,
- verified the above on Ubuntu Linux and Windows as well.
aiuto pushed a commit that referenced this pull request Feb 10, 2026
tl;dr: this change builds on #984 which introduced the `locate()` helper
and the `runfiles` infrastructure. That PR fixed Windows compatibility
by enabling runfiles-less operation; this change extends it to support
cross-repository files.

When a `pkg_install` rule in an external repository references files
from another repository, the installer would fail at runtime by
attempting to resolve all files relative to its repository rather than
each file's own repository.

Example failure (`extrepo`: external repository installing file from
main repository):
```
bazel run @extrepo//:install -- --destdir=/tmp/test
[...]
FileNotFoundError: [Errno 2] No such file or directory:
  '.../runfiles/+_repo_rules+extrepo/some-path/extrepo/file-in-main-repo'
```

The file should be resolved against the main repository (`_main`) but
is incorrectly looked up from the installer's repository
(`+_repo_rules+extrepo`).

The solution proposed here consists in extending the manifest to track
each file's own repository and use this information during installation
to resolve files against the correct repository.

It adds a `repository` field to manifest entries using:
- `Label.repo_name`
  ([canonical](https://bazel.build/rules/lib/builtins/Label#repo_name))
  when explicitly valued for the source file,
- otherwise `ctx.workspace_name` when no
  [owner](https://bazel.build/rules/lib/builtins/File#owner)
  or `Label.repo_name` is
  [empty](https://rules-python.readthedocs.io/en/latest/api/py/runfiles/runfiles.runfiles.html#runfiles.runfiles.Runfiles.CurrentRepository),
  denoting the main repository (`_main`, as before).

Testing:
- `//tests/install:install_test` includes new `CrossRepoInstallTest`,
- `bazel run @extrepo//:install -- --destdir=/tmp/test` case works,
- verified the above on Ubuntu Linux and Windows as well.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pkg_install should work in Windows

3 participants