Skip to content

Commit 2e5ed5e

Browse files
committed
Use runfiles wrapper
1 parent 057800a commit 2e5ed5e

File tree

2 files changed

+48
-9
lines changed

2 files changed

+48
-9
lines changed

sh/private/defs.bzl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,11 @@ def mk_template_variable_info(name, sh_binaries_info):
3131
},
3232
))
3333

34-
def mk_default_info_with_files_to_run(ctx, name, files, runfiles):
34+
def mk_default_info_with_files_to_run(ctx, executable, files, runfiles):
3535
# Create a dummy executable to trigger the generation of a FilesToRun
3636
# provider which can be used in custom rules depending on this bundle to
3737
# input the needed runfiles into build actions.
3838
# This is a workaround for https://github.com/bazelbuild/bazel/issues/15486
39-
executable = ctx.actions.declare_file(name)
4039
ctx.actions.write(executable, "", is_executable = True)
4140
return DefaultInfo(
4241
executable = executable,

sh/sh.bzl

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

102141
def _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

Comments
 (0)