Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dotnet/private/launcher.bat.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,4 @@ if defined args (
set args=!args:\=\\\\!
set args=!args:"=\"!
)
"!dotnet_executable!" exec "!run_script!" !args!
"!dotnet_executable!" exec --additionalprobingpath "%RUNFILES_DIR%" "!run_script!" !args!
2 changes: 1 addition & 1 deletion dotnet/private/launcher.sh.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ export DOTNET_NOLOGO="1"
export DOTNET_CLI_TELEMETRY_OPTOUT="1"
export DOTNET_ROOT="$(dirname $(rlocation TEMPLATED_dotnet))"

exec $(rlocation TEMPLATED_dotnet) exec $(rlocation TEMPLATED_executable) "$@"
exec $(rlocation TEMPLATED_dotnet) exec --additionalprobingpath "${RUNFILES_DIR}" $(rlocation TEMPLATED_executable) "$@"
5 changes: 3 additions & 2 deletions dotnet/private/rules/common/binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ def _collect_native_dlls(assembly_runtime_info, deps):
return result

def _create_launcher(ctx, runfiles, executable):
runtime = get_toolchain(ctx).runtime
toolchain = get_toolchain(ctx)
runtime = toolchain.target_runtime
windows_constraint = ctx.attr._windows_constraint[platform_common.ConstraintValueInfo]

launcher = ctx.actions.declare_file("{}.{}".format(executable.basename, "bat" if ctx.target_platform_has_constraint(windows_constraint) else "sh"), sibling = executable)
Expand All @@ -70,7 +71,7 @@ def _create_launcher(ctx, runfiles, executable):
is_executable = True,
)

runfiles.extend(get_toolchain(ctx).dotnetinfo.runtime_files)
runfiles.extend(toolchain.dotnetinfo.target_runtime_files)

return launcher

Expand Down
64 changes: 64 additions & 0 deletions dotnet/private/tests/target_runtime/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
load("//dotnet:toolchain.bzl", "dotnet_toolchain")
load(":target_runtime_test.bzl", "fake_executable", "resolved_target_runtime_test", "target_runtime_test")

platform(
name = "windows_x64",
constraint_values = [
"@platforms//os:windows",
"@platforms//cpu:x86_64",
],
)

config_setting(
name = "target_windows",
constraint_values = [
"@platforms//os:windows",
"@platforms//cpu:x86_64",
],
)

fake_executable(
name = "runtime_host",
)

fake_executable(
name = "runtime_windows",
)

filegroup(
name = "host_model",
srcs = ["host_model.dll"],
)

dotnet_toolchain(
name = "fake_dotnet_toolchain",
runtime = ":runtime_host",
target_runtime = select({
":target_windows": ":runtime_windows",
"//conditions:default": ":runtime_host",
}),
csharp_compiler = ":runtime_host",
fsharp_compiler = ":runtime_host",
host_model = ":host_model",
sdk_version = "0.0.0",
runtime_version = "0.0.0",
runtime_tfm = "net0.0",
csharp_default_version = "0.0",
fsharp_default_version = "0.0",
)

toolchain(
name = "fake_registered_toolchain",
toolchain = ":fake_dotnet_toolchain",
toolchain_type = "//dotnet:toolchain_type",
)

target_runtime_test(
name = "target_runtime_uses_target_platform",
toolchain_under_test = ":fake_dotnet_toolchain",
)

resolved_target_runtime_test(
name = "resolved_target_runtime_uses_target_platform",
tags = ["manual"],
)
1 change: 1 addition & 0 deletions dotnet/private/tests/target_runtime/host_model.dll
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

72 changes: 72 additions & 0 deletions dotnet/private/tests/target_runtime/target_runtime_test.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
def _fake_executable_impl(ctx):
out = ctx.actions.declare_file(ctx.label.name + ".sh")
ctx.actions.write(
output = out,
content = "#!/usr/bin/env bash\nexit 0\n",
is_executable = True,
)
return [DefaultInfo(executable = out, files = depset([out]))]

fake_executable = rule(
implementation = _fake_executable_impl,
executable = True,
)

def _windows_platform_transition_impl(_settings, _attr):
return {
"//command_line_option:platforms": "//dotnet/private/tests/target_runtime:windows_x64",
}

_windows_platform_transition = transition(
implementation = _windows_platform_transition_impl,
inputs = [],
outputs = ["//command_line_option:platforms"],
)

def _target_runtime_test_impl(ctx):
toolchain_under_test = ctx.attr.toolchain_under_test
if type(toolchain_under_test) == "list":
toolchain_under_test = toolchain_under_test[0]
toolchain = toolchain_under_test[platform_common.ToolchainInfo]
return _assert_windows_runtime(ctx, toolchain)

def _resolved_target_runtime_test_impl(ctx):
toolchain = ctx.toolchains["//dotnet:toolchain_type"]
return _assert_windows_runtime(ctx, toolchain)

def _assert_windows_runtime(ctx, toolchain):
target_runtime_files = [
file.basename
for file in toolchain.dotnetinfo.target_runtime_files
]

if "runtime_windows.sh" not in target_runtime_files:
fail("Expected target runtime files to contain runtime_windows.sh, got: {}".format(target_runtime_files))

out = ctx.actions.declare_file(ctx.label.name + ".sh")
ctx.actions.write(
output = out,
content = "#!/usr/bin/env bash\nexit 0\n",
is_executable = True,
)
return [DefaultInfo(executable = out)]

target_runtime_test = rule(
implementation = _target_runtime_test_impl,
attrs = {
"toolchain_under_test": attr.label(
cfg = _windows_platform_transition,
providers = [platform_common.ToolchainInfo],
),
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
},
test = True,
)

resolved_target_runtime_test = rule(
implementation = _resolved_target_runtime_test_impl,
test = True,
toolchains = ["//dotnet:toolchain_type"],
)
7 changes: 7 additions & 0 deletions dotnet/private/tests/use_as_tool/fsharp/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ assert_contains(
expected = "Hello World!",
)

sh_test(
name = "relocated_runfiles_test",
srcs = ["relocated_runfiles_test.sh"],
args = ["$(rootpath :main)"],
data = [":main"],
)

# Also test that self contained binaries are also usable as tools in custom rules
publish_binary(
name = "publish_self_contained",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -euo pipefail

launcher="$(find "$TEST_SRCDIR" -path "*/$1" -print -quit)"
if [[ -z "$launcher" ]]; then
echo "Could not find launcher matching $1 under $TEST_SRCDIR" >&2
exit 1
fi
tmp="${TEST_TMPDIR}/relocated"
mkdir -p "$tmp"

cp "$launcher" "$tmp/app"
cp -R "$TEST_SRCDIR" "$tmp/app.runfiles"

"$tmp/app" "$tmp/output"
grep -F "Hello World!" "$tmp/output"
32 changes: 32 additions & 0 deletions dotnet/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,33 @@ _DOC = "Fetch external tools needed for dotnet toolchain"
_ATTRS = {
"dotnet_version": attr.string(mandatory = True, values = TOOL_VERSIONS.keys()),
"platform": attr.string(mandatory = True, values = PLATFORMS.keys()),
"user_repository_name": attr.string(),
}

def _dotnet_repo_impl(repository_ctx):
url = TOOL_VERSIONS[repository_ctx.attr.dotnet_version][repository_ctx.attr.platform]["url"]
user_repository_name = repository_ctx.attr.user_repository_name
if user_repository_name == "":
current_repo_suffix = "_" + repository_ctx.attr.platform
if not repository_ctx.name.endswith(current_repo_suffix):
fail("Expected repository name {} to end with {}".format(repository_ctx.name, current_repo_suffix))
user_repository_name = repository_ctx.name[:-len(current_repo_suffix)]

platform_config_settings = ""
target_runtime_select_entries = []
for platform, meta in PLATFORMS.items():
config_setting_name = "target_" + platform
platform_config_settings += """
config_setting(
name = "{config_setting_name}",
constraint_values = {compatible_with},
)
""".format(
config_setting_name = config_setting_name,
compatible_with = meta.compatible_with,
)
target_runtime_select_entries.append("\":{}\": \"@{}_{}//:runtime\"".format(config_setting_name, user_repository_name, platform))

repository_ctx.download_and_extract(
url = url,
integrity = TOOL_VERSIONS[repository_ctx.attr.dotnet_version][repository_ctx.attr.platform]["hash"],
Expand All @@ -24,6 +47,8 @@ def _dotnet_repo_impl(repository_ctx):
load("@rules_dotnet//dotnet:toolchain.bzl", "dotnet_toolchain")
load("@rules_dotnet//dotnet:defs.bzl", "import_dll")

{platform_config_settings}

filegroup(
name = "csc_binary",
srcs = [
Expand Down Expand Up @@ -80,6 +105,10 @@ filegroup(
dotnet_toolchain(
name = "dotnet_toolchain",
runtime = ":runtime",
target_runtime = select({{
{target_runtime_select},
"//conditions:default": ":runtime",
}}),
csharp_compiler = ":csc_binary",
fsharp_compiler = ":fsc_binary",
host_model = ":host_model",
Expand All @@ -91,6 +120,8 @@ dotnet_toolchain(
visibility = ["//visibility:public"],
)
""".format(
platform_config_settings = platform_config_settings,
target_runtime_select = ",\n ".join(target_runtime_select_entries),
sdk_version = repository_ctx.attr.dotnet_version,
runtime_version = TOOL_VERSIONS[repository_ctx.attr.dotnet_version]["runtimeVersion"],
runtime_tfm = TOOL_VERSIONS[repository_ctx.attr.dotnet_version]["runtimeTfm"],
Expand Down Expand Up @@ -129,6 +160,7 @@ def dotnet_register_toolchains(name, dotnet_version, register = True, **kwargs):
name = name + "_" + platform,
platform = platform,
dotnet_version = dotnet_version,
user_repository_name = name,
**kwargs
)
if register:
Expand Down
28 changes: 28 additions & 0 deletions dotnet/toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ DotnetInfo = provider(
"runtime_files": """Files required in runfiles to make the dotnet executable available.

May be empty if the runtime_path points to a locally installed tool binary.""",
"target_runtime_path": "Path to the dotnet executable for target binaries",
"target_runtime_files": """Files required in runfiles to make the target dotnet executable available.

May be empty if target_runtime_path points to a locally installed tool binary.""",
"csharp_compiler_path": "Path to the C# compiler executable",
"csharp_compiler_files": """Files required in runfiles to make the C# compiler executable available.

Expand Down Expand Up @@ -41,6 +45,8 @@ def _dotnet_toolchain_impl(ctx):
fail("Can only set one of runtime or runtime_path but both were set.")
if not ctx.attr.runtime and not ctx.attr.runtime_path:
fail("Must set one of runtime or runtime_path.")
if ctx.attr.target_runtime and ctx.attr.target_runtime_path:
fail("Can only set one of target_runtime or target_runtime_path but both were set.")

if ctx.attr.csharp_compiler and ctx.attr.csharp_compiler_path:
fail("Can only set one of csharp_compiler or csharp_compiler_path but both were set.")
Expand All @@ -54,6 +60,8 @@ def _dotnet_toolchain_impl(ctx):

runtime_files = []
runtime_path = ctx.attr.runtime_path
target_runtime_files = []
target_runtime_path = ctx.attr.target_runtime_path

csharp_compiler_files = []
csharp_compiler_path = ctx.attr.csharp_compiler_path
Expand All @@ -65,6 +73,13 @@ def _dotnet_toolchain_impl(ctx):
runtime_files = ctx.attr.runtime.files.to_list() + ctx.attr.runtime.default_runfiles.files.to_list()
runtime_path = _to_manifest_path(ctx, runtime_files[0])

if ctx.attr.target_runtime:
target_runtime_files = ctx.attr.target_runtime.files.to_list() + ctx.attr.target_runtime.default_runfiles.files.to_list()
target_runtime_path = _to_manifest_path(ctx, target_runtime_files[0])
else:
target_runtime_files = runtime_files
target_runtime_path = runtime_path

if ctx.attr.csharp_compiler:
csharp_compiler_files = ctx.attr.csharp_compiler.files.to_list() + ctx.attr.csharp_compiler.default_runfiles.files.to_list()
csharp_compiler_path = _to_manifest_path(ctx, csharp_compiler_files[0])
Expand Down Expand Up @@ -92,6 +107,8 @@ def _dotnet_toolchain_impl(ctx):
dotnetinfo = DotnetInfo(
runtime_path = runtime_path,
runtime_files = runtime_files,
target_runtime_path = target_runtime_path,
target_runtime_files = target_runtime_files,
csharp_compiler_path = csharp_compiler_path,
csharp_compiler_files = csharp_compiler_files,
fsharp_compiler_path = fsharp_compiler_path,
Expand All @@ -110,6 +127,7 @@ def _dotnet_toolchain_impl(ctx):
dotnetinfo = dotnetinfo,
template_variables = template_variables,
runtime = ctx.attr.runtime,
target_runtime = ctx.attr.target_runtime or ctx.attr.runtime,
csharp_compiler = ctx.attr.csharp_compiler,
fsharp_compiler = ctx.attr.fsharp_compiler,
host_model = ctx.attr.host_model,
Expand All @@ -134,6 +152,16 @@ dotnet_toolchain = rule(
doc = "Path to the dotnet CLI. Do not set if `runtime` is set",
mandatory = False,
),
"target_runtime": attr.label(
doc = "The dotnet CLI used by target binaries. Defaults to runtime.",
mandatory = False,
executable = True,
cfg = "target",
),
"target_runtime_path": attr.string(
doc = "Path to the dotnet CLI used by target binaries. Defaults to runtime_path.",
mandatory = False,
),
"csharp_compiler": attr.label(
doc = "The C# compiler binary",
mandatory = False,
Expand Down