@@ -17,7 +17,33 @@ ShBinariesInfo = provider(
1717
1818_WINDOWS_EXE_EXTENSIONS = [".exe" , ".cmd" , ".bat" , ".ps1" ]
1919
20- def _sh_binaries_from_srcs (ctx , srcs , is_windows ):
20+ _POSIX_WRAPPER_TEMPLATE = """\
21+ #!/bin/sh
22+ if [[ -f "{main_executable}.runfiles_manifest" ]]; then
23+ export RUNFILES_MANIFEST_FILE="{main_executable}.runfiles_manifest"
24+ elif [[ -d "{main_executable}.runfiles" ]]; then
25+ export RUNFILES_DIR="{main_executable}.runfiles"
26+ else
27+ echo "ERROR: Runfiles not found for bundle {main_executable}" >&2
28+ exit 1
29+ fi
30+ exec "{original_executable}" "$@"
31+ """
32+
33+ _WINDOWS_WRAPPER_TEMPLATE = """\
34+ @echo off
35+ if exist "{main_executable}.runfiles_manifest" (
36+ set RUNFILES_MANIFEST_FILE={main_executable}.runfiles_manifest
37+ ) else if exist "{main_executable}.runfiles" (
38+ set RUNFILES_DIR={main_executable}.runfiles
39+ ) else (
40+ echo ERROR: Runfiles not found for bundle {main_executable} >&2
41+ exit /b 1
42+ )
43+ "{original_executable}" %*
44+ """
45+
46+ def _sh_binaries_from_srcs (ctx , srcs , is_windows , main_executable ):
2147 executable_files = []
2248 runfiles = ctx .runfiles ()
2349 executables_dict = dict ()
@@ -27,10 +53,10 @@ def _sh_binaries_from_srcs(ctx, srcs, is_windows):
2753 if src [DefaultInfo ].files_to_run == None or src [DefaultInfo ].files_to_run .executable == None :
2854 fail ("srcs must be executable, but '{}' is not." .format (src .label ))
2955
30- executable = src [DefaultInfo ].files_to_run .executable
31- name = executable .basename
56+ original_executable = src [DefaultInfo ].files_to_run .executable
57+ name = original_executable .basename
3258 if is_windows :
33- (noext , ext ) = paths .split_extension (executable .basename )
59+ (noext , ext ) = paths .split_extension (original_executable .basename )
3460 if ext in _WINDOWS_EXE_EXTENSIONS :
3561 name = noext
3662
@@ -41,8 +67,21 @@ def _sh_binaries_from_srcs(ctx, srcs, is_windows):
4167 src .label ,
4268 ))
4369
70+ if src [DefaultInfo ].default_runfiles :
71+ executable = ctx .actions .declare_file (ctx .label .name + ".path/" + (name + ".bat" if is_windows else name ))
72+ ctx .actions .write (
73+ executable ,
74+ (_WINDOWS_WRAPPER_TEMPLATE if is_windows else _POSIX_WRAPPER_TEMPLATE ).format (
75+ main_executable = main_executable .path ,
76+ original_executable = original_executable .path ,
77+ ),
78+ is_executable = True ,
79+ )
80+ executable_files .append (original_executable )
81+ runfiles = runfiles .merge (src [DefaultInfo ].default_runfiles )
82+ else :
83+ executable = original_executable
4484 executable_files .append (executable )
45- runfiles = runfiles .merge (src [DefaultInfo ].default_runfiles )
4685 executables_dict [name ] = executable
4786 executable_paths .append (executable .dirname )
4887
@@ -101,15 +140,16 @@ def _mk_sh_binaries_info(direct, transitive):
101140
102141def _sh_binaries_impl (ctx ):
103142 is_windows = ctx .attr ._is_windows [ConstantInfo ].value
104- direct = _sh_binaries_from_srcs (ctx , ctx .attr .srcs , is_windows )
143+ executable = ctx .actions .declare_file (ctx .label .name )
144+ direct = _sh_binaries_from_srcs (ctx , ctx .attr .srcs , is_windows , executable )
105145 transitive = _sh_binaries_from_deps (ctx , ctx .attr .deps )
106146 data_runfiles = _runfiles_from_data (ctx , ctx .attr .data )
107147
108148 sh_binaries_info = _mk_sh_binaries_info (direct , transitive )
109149 template_variable_info = mk_template_variable_info (ctx .label .name , sh_binaries_info )
110150 default_info = mk_default_info_with_files_to_run (
111151 ctx ,
112- ctx . label . name ,
152+ executable ,
113153 depset (direct = direct .executable_files , transitive = transitive .executable_files ),
114154 direct .runfiles .merge (transitive .runfiles ).merge (data_runfiles ),
115155 )
0 commit comments