Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow multiple runtime packs #307

Merged
merged 1 commit into from
Sep 15, 2022
Merged
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
4 changes: 2 additions & 2 deletions dotnet/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -265,15 +265,15 @@ def fsharp_nunit_test(
**kwargs
)

def publish_binary(name, binary, target_framework, self_contained = False, runtime_pack = None, runtime_identifier = None, **kwargs):
def publish_binary(name, binary, target_framework, self_contained = False, runtime_packs = [], runtime_identifier = None, **kwargs):
runtime_identifier = _get_runtime_runtime_identifier(runtime_identifier)

_publish_binary(
name = "{}_wrapped".format(name),
binary = binary,
target_framework = target_framework,
self_contained = self_contained,
runtime_pack = runtime_pack,
runtime_packs = runtime_packs,
tags = ["manual"],
)

Expand Down
6 changes: 3 additions & 3 deletions dotnet/private/common.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ def generate_depsjson(
runtime_deps,
transitive_runtime_deps,
runtime_identifier,
runtime_pack_info = None):
runtime_pack_infos = []):
"""Generates a deps.json file.

Args:
Expand All @@ -443,7 +443,7 @@ def generate_depsjson(
runtime_deps: The runtime dependencies of the target.
transitive_runtime_deps: The transitive runtime dependencies of the target.
runtime_identifier: The runtime identifier of the target.
runtime_pack_info: The DotnetAssemblyInfo of the runtime pack that is used for a self contained publish.
runtime_pack_infos: The DotnetAssemblyInfo of the runtime packs that are used for a self contained publish.
Returns:
The deps.json file as a struct.
"""
Expand All @@ -465,7 +465,7 @@ def generate_depsjson(
base["targets"][runtime_target] = {}
base["libraries"] = {}

if runtime_pack_info:
for runtime_pack_info in runtime_pack_infos:
runtime_pack_name = "runtimepack.{}/{}".format(runtime_pack_info.name, runtime_pack_info.version)
base["libraries"][runtime_pack_name] = {
"type": "runtimepack",
Expand Down
2 changes: 1 addition & 1 deletion dotnet/private/providers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ DotnetBinaryInfo = provider(
DotnetPublishBinaryInfo = provider(
doc = "Information about a published .Net binary",
fields = {
"runtime_pack": "AssemblyInfo: Optional information about the used runtime pack. Used by self-contained publishing",
"runtime_packs": "list[AssemblyInfo]: Optional information about the used runtime packs. Used by self-contained publishing",
"target_framework": "string: The target framework of the published binary",
"self_contained": "bool: True if the binary is self-contained",
},
Expand Down
58 changes: 32 additions & 26 deletions dotnet/private/rules/publish_binary/publish_binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,21 @@ load("//dotnet/private/transitions:tfm_transition.bzl", "tfm_transition")
load("//dotnet/private:common.bzl", "generate_depsjson", "generate_runtimeconfig")

def _publish_binary_impl(ctx):
runtime_pack_info = None
runtime_pack_infos = []
if ctx.attr.self_contained == True:
if ctx.attr.runtime_pack == None or len(ctx.attr.runtime_pack) == 0:
if len(ctx.attr.runtime_packs) == 0:
fail("Can not publish self-contained binaries without a runtime pack")

runtime_pack_info = ctx.attr.runtime_pack[0][DotnetAssemblyInfo]
for runtime_pack in ctx.attr.runtime_packs:
runtime_pack_infos.append(runtime_pack[DotnetAssemblyInfo])
elif len(ctx.attr.runtime_packs) > 0:
fail("Can not do a framework dependent publish with a runtime pack")

return [
ctx.attr.binary[0][DotnetAssemblyInfo],
ctx.attr.binary[0][DotnetBinaryInfo],
DotnetPublishBinaryInfo(
runtime_pack = runtime_pack_info,
runtime_packs = runtime_pack_infos,
target_framework = ctx.attr.target_framework,
self_contained = ctx.attr.self_contained,
),
Expand All @@ -44,26 +47,28 @@ publish_binary = rule(
Whether the binary should be self-contained.

If true, the binary will be published as a self-contained but you need to provide
a runtime pack in the `runtime_pack` attribute. At some point the rules might
a runtime pack in the `runtime_packs` attribute. At some point the rules might
resolve the runtime pack automatically.

If false, the binary will be published as a non-self-contained. That means that to be
able to run the binary you need to have a .Net runtime installed on the host system.
""",
default = False,
),
"runtime_pack": attr.label(
"runtime_packs": attr.label_list(
doc = """
The runtime pack that should be used to publish the binary.
The runtime packs that should be used to publish the binary.
Should only be declared if `self_contained` is true.

The runtime pack is a NuGet package that contains the runtime that should be
used to run the binary.
A runtime pack is a NuGet package that contains the runtime that should be
used to run the binary. There can be multiple runtime packs for a given
publish e.g. when a AspNetCore application is published you need the base
runtime pack and the AspNetCore runtime pack.

Example runtime pack: https://www.nuget.org/packages/Microsoft.NETCore.App.Runtime.linux-x64/6.0.8
""",
providers = [DotnetAssemblyInfo],
default = None,
default = [],
cfg = tfm_transition,
),
# TODO:
Expand Down Expand Up @@ -155,18 +160,19 @@ def _copy_to_publish(ctx, runtime_identifier, publish_binary_info, binary_info,
# In case the publish is self-contained there needs to be a runtime pack available
# with the runtime dependencies that are required for the targeted runtime.
# The runtime pack contents should always be copied to the root of the publish folder
if publish_binary_info.runtime_pack:
runtime_pack_files = depset(
publish_binary_info.runtime_pack.libs +
publish_binary_info.runtime_pack.native +
publish_binary_info.runtime_pack.data,
transitive = [publish_binary_info.runtime_pack.transitive_libs, publish_binary_info.runtime_pack.transitive_native, publish_binary_info.runtime_pack.transitive_data],
)
for file in runtime_pack_files.to_list():
output = ctx.actions.declare_file(file.basename, sibling = app_host_copy)
outputs.append(output)
inputs.append(file)
_copy_file(script_body, file, output, is_windows = is_windows)
if len(publish_binary_info.runtime_packs) > 0:
for runtime_pack in publish_binary_info.runtime_packs:
runtime_pack_files = depset(
runtime_pack.libs +
runtime_pack.native +
runtime_pack.data,
transitive = [runtime_pack.transitive_libs, runtime_pack.transitive_native, runtime_pack.transitive_data],
)
for file in runtime_pack_files.to_list():
output = ctx.actions.declare_file(file.basename, sibling = app_host_copy)
outputs.append(output)
inputs.append(file)
_copy_file(script_body, file, output, is_windows = is_windows)

copy_script = ctx.actions.declare_file(ctx.label.name + ".copy.bat" if is_windows else ctx.label.name + ".copy.sh")
ctx.actions.write(
Expand Down Expand Up @@ -204,8 +210,8 @@ def _generate_depsjson(
runtime_deps,
transitive_runtime_deps,
runtime_identifier,
runtime_pack_info):
depsjson_struct = generate_depsjson(target_framework, is_self_contained, runtime_deps, transitive_runtime_deps, runtime_identifier, runtime_pack_info)
runtime_pack_infos):
depsjson_struct = generate_depsjson(target_framework, is_self_contained, runtime_deps, transitive_runtime_deps, runtime_identifier, runtime_pack_infos)

ctx.actions.write(
output = output,
Expand Down Expand Up @@ -251,7 +257,7 @@ def _publish_binary_wrapper_impl(ctx):
assembly_info.runtime_deps,
assembly_info.transitive_runtime_deps,
runtime_identifier,
publish_binary_info.runtime_pack,
publish_binary_info.runtime_packs,
)

return [
Expand All @@ -264,7 +270,7 @@ def _publish_binary_wrapper_impl(ctx):

# This wrapper is only needed so that we can turn the incoming transition in `publish_binary`
# into an outgoing transition in the wrapper. This allows us to select on the runtime_identifier
# and runtime_pack attributes. We also need to have all the file copying in the wrapper rule
# and runtime_packs attributes. We also need to have all the file copying in the wrapper rule
# because Bazel does not allow forwarding executable files as they have to be created by the wrapper rule.
publish_binary_wrapper = rule(
_publish_binary_wrapper_impl,
Expand Down
8 changes: 4 additions & 4 deletions dotnet/private/tests/publish/self_contained/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ load("@rules_pkg//pkg:tar.bzl", "pkg_tar")
publish_binary(
name = "self_contained",
binary = "//dotnet/private/tests/publish/app_to_publish",
runtime_pack = select({
"@rules_dotnet//dotnet:rid_linux-x64": "@rules_dotnet_dev_nuget_packages//microsoft.netcore.app.runtime.linux-x64",
"@rules_dotnet//dotnet:rid_osx-x64": "@rules_dotnet_dev_nuget_packages//microsoft.netcore.app.runtime.osx-x64",
"@rules_dotnet//dotnet:rid_win-x64": "@rules_dotnet_dev_nuget_packages//microsoft.netcore.app.runtime.win-x64",
runtime_packs = select({
"@rules_dotnet//dotnet:rid_linux-x64": ["@rules_dotnet_dev_nuget_packages//microsoft.netcore.app.runtime.linux-x64"],
"@rules_dotnet//dotnet:rid_osx-x64": ["@rules_dotnet_dev_nuget_packages//microsoft.netcore.app.runtime.osx-x64"],
"@rules_dotnet//dotnet:rid_win-x64": ["@rules_dotnet_dev_nuget_packages//microsoft.netcore.app.runtime.win-x64"],
}),
self_contained = True,
target_framework = "net6.0",
Expand Down
Empty file added examples/BUILD.bazel
Empty file.
Loading