Skip to content

feat(toolchain): wrap exec interpreter in launcher script for build actions - #4154

Draft
rickeylev wants to merge 6 commits into
bazel-contrib:mainfrom
rickeylev:implement_interpreter_launcher_script
Draft

feat(toolchain): wrap exec interpreter in launcher script for build actions#4154
rickeylev wants to merge 6 commits into
bazel-contrib:mainfrom
rickeylev:implement_interpreter_launcher_script

Conversation

@rickeylev

@rickeylev rickeylev commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Build actions that invoke the toolchain's execution-platform Python
interpreter directly fail under sandboxing or remote execution because
bare binaries and raw symlinks lack the necessary runfiles tree and
PYTHONHOME environment to locate standard library modules hermetically.

Wrap the interpreter in platform-specific launcher scripts for POSIX
and Windows that resolve the underlying interpreter through standard
Bazel runfiles lookup mechanisms and set PYTHONHOME to point to the
runfiles root. Wire these launchers into current_interpreter_executable
and interpreter_binary, and run them through actions_run and
py_console_script_gen.

Fixes #2703

…ctions

Build actions invoking the execution-platform Python interpreter directly
on bare binaries or raw symlinks fail under sandbox and remote execution
environments because standard library modules (like encodings) cannot be
found without a proper runfiles environment and PYTHONHOME.

Wrap the interpreter in a launcher script:
* Expand platform-specific launcher scripts (interpreter_tmpl.sh for
  POSIX sh and interpreter_tmpl.bat for Windows) in
  current_interpreter_executable.
* Hermetically resolve the underlying interpreter through standard Bazel
  runfiles mechanisms (RUNFILES_DIR, RUNFILES_MANIFEST_FILE, and
  $0.runfiles).
* Determine and export PYTHONHOME to ensure standard library modules are
  located within the runfiles tree.
* Execute exec_tools.exec_interpreter[DefaultInfo].files_to_run in
  actions_run and py_console_script_gen.
* Add analysis and action execution tests verifying sys.executable and
  stdlib modules reside in runfiles.
NixOS systems do not place sh in /bin/sh. Use /usr/bin/env sh so the
launcher script can be executed on NixOS and other systems with
non-standard /bin directories.
Rename template files from _tmpl to _template and encapsulate them
within the exec_interpreter_template filegroup.

* Rename interpreter_tmpl.sh to interpreter_template.sh and
  interpreter_tmpl.bat to interpreter_template.bat.
* Remove the template files from exports_files in python/private/BUILD.bazel.
* Point _template in interpreter_binary to
  //python/private:exec_interpreter_template.
* Add comments explaining why PYTHONHOME points to the runfiles directory.
Note that RBE compatibility must still be verified in CI with the launcher script wrapper before removing the warning.
cmd.exe failed to parse interpreter_template.bat because of invalid
stderr redirection and an unquoted parenthesis inside an if block.

* Use 1>&2 for stderr redirection.
* Replace literal parentheses with brackets in error message.
…e endings

cmd.exe lacks Win32 long path awareness and fails with STATUS_NAME_TOO_LONG
when resolving runfiles paths exceeding MAX_PATH in nested builds.
Additionally, diff_test on Windows performs binary comparison (fc.exe /B),
which failed when test_action.py wrote CRLF instead of LF.

* Guard candidate runfiles paths in interpreter_template.bat to under 250
  characters, falling back to the manifest when paths are too long.
* Add current-directory fallback for relative manifest targets.
* Use write_bytes with UTF-8 in test_action.py to ensure exact LF newlines
  across platforms.
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.

exec tools exec_interpreter broken on RBE

1 participant