@@ -79,12 +79,21 @@ ExplicitSymlink = provider(
7979A runfile that should be created as a symlink pointing to a specific location.
8080
8181This is only needed on Windows, where Bazel doesn't preserve declare_symlink
82- with relative paths.
82+ with relative paths. This is basically manually captures what using
83+ declare_symlink(), symlink() and runfiles like so would capture:
84+
85+ ```
86+ link = declare_symlink(...)
87+ link_to_path = relative_path(from=link, to=target)
88+ symlink(output=link, target_path=link_to_path)
89+ runfiles.add([link, target])
90+ ```
8391""" ,
8492 fields = {
85- "link_to" : "Path the symlink should point to" ,
86- "rf_path" : "runfile-root-relative path for the link" ,
87- "venv_rel_path" : "venv-root-relative path for the link" ,
93+ "link_to_path" : "Path the symlink should point to" ,
94+ "runfiles_path" : "runfiles-root-relative path for the symlink" ,
95+ "venv_path" : "venv-root-relative path for the symlink" ,
96+ "files" : "depset[File] of files that should be included if this symlink is used" ,
8897 },
8998)
9099
@@ -736,7 +745,7 @@ def _create_venv_unixy(ctx, *, venv_ctx_rel_root, runtime, interpreter_actual_pa
736745
737746def _create_venv_windows (ctx , * , venv_ctx_rel_root , runtime , interpreter_actual_path ):
738747 interpreter_runfiles = builders .RunfilesBuilder ()
739- interpreter_symlinks = []
748+ interpreter_symlinks = builders . DepsetBuilder ()
740749
741750 # Some wrappers around the interpreter (e.g. pyenv) use the program
742751 # name to decide what to do, so preserve the name.
@@ -751,17 +760,15 @@ def _create_venv_windows(ctx, *, venv_ctx_rel_root, runtime, interpreter_actual_
751760 ctx .actions .symlink (output = interpreter , target_file = runtime .interpreter )
752761
753762 rf_path = runfiles_root_path (ctx , interpreter .short_path )
754- interpreter_symlinks .append (ExplicitSymlink (
755- rf_path = rf_path ,
756- venv_rel_path = venv_rel_path ,
757- link_to = relative_path (
758- # dirname is necessary because a relative symlink is relative to
759- # the directory the symlink resides within.
760- from_ = paths .dirname (rf_path ),
761- to = interpreter_actual_path ,
762- ),
763+ interpreter_symlinks .add (ExplicitSymlink (
764+ runfiles_path = rf_path ,
765+ venv_path = venv_rel_path ,
766+ link_to_path = interpreter_actual_path ,
767+ files = depset ([runtime .interpreter ]),
763768 ))
764769 else :
770+ # It's OK to use declare_symlink here because an absolute path
771+ # will be written to it, so Bazel won't mangle it.
765772 interpreter = ctx .actions .declare_symlink ("{}/{}" .format (venv_bin_ctx_rel_path , py_exe_basename ))
766773 interpreter_runfiles .add (interpreter )
767774 ctx .actions .symlink (output = interpreter , target_path = runtime .interpreter_path )
@@ -771,19 +778,18 @@ def _create_venv_windows(ctx, *, venv_ctx_rel_root, runtime, interpreter_actual_
771778 for f in runtime .venv_bin_files :
772779 venv_rel_path = paths .join (venv_bin_rel_path , f .basename )
773780 venv_ctx_rel_path = paths .join (venv_ctx_rel_root , venv_rel_path )
781+
774782 venv_file = ctx .actions .declare_file (venv_ctx_rel_path )
775783 ctx .actions .symlink (output = venv_file , target_file = f )
784+
776785 interpreter_runfiles .add (venv_file )
786+
777787 rf_path = runfiles_root_path (ctx , venv_file .short_path )
778- interpreter_symlinks .append (ExplicitSymlink (
779- rf_path = rf_path ,
780- venv_rel_path = venv_rel_path ,
781- link_to = relative_path (
782- # dirname is necessary because a relative symlink is relative to
783- # the directory the symlink resides within.
784- from_ = paths .dirname (rf_path ),
785- to = runfiles_root_path (ctx , f .short_path ),
786- ),
788+ interpreter_symlinks .add (ExplicitSymlink (
789+ runfiles_path = rf_path ,
790+ venv_path = venv_rel_path ,
791+ link_to_path = runfiles_root_path (ctx , f .short_path ),
792+ files = depset ([f ])
787793 ))
788794
789795 # See site.py logic: Windows uses a version/build agnostic site-packages path
@@ -796,7 +802,7 @@ def _create_venv_windows(ctx, *, venv_ctx_rel_root, runtime, interpreter_actual_
796802 bin_dir = venv_bin_ctx_rel_path ,
797803 recreate_venv_at_runtime = True ,
798804 interpreter_runfiles = interpreter_runfiles .build (ctx ),
799- interpreter_symlinks = depset ( interpreter_symlinks ),
805+ interpreter_symlinks = interpreter_symlinks . build ( ),
800806 )
801807
802808def _venv_details (
@@ -972,7 +978,7 @@ def _create_stage1_bootstrap(
972978 )
973979
974980def _map_runtime_venv_symlink (entry ):
975- return entry .venv_rel_path + "|" + entry .link_to
981+ return entry .venv_path + "|" + entry .link_to_path
976982
977983def _create_zip_file (ctx , * , output , zip_main , runfiles ):
978984 """Create a Python zipapp (zip with __main__.py entry point)."""
0 commit comments