2020-10-28 14:59:00 -04:00
|
|
|
load("@d2l_rules_csharp//csharp/private:actions/assembly.bzl", "AssemblyAction")
|
2022-11-22 18:07:20 -05:00
|
|
|
load("@d2l_rules_csharp//csharp/private:actions/misc.bzl", "write_runtimeconfig")
|
2020-10-28 14:59:00 -04:00
|
|
|
load(
|
|
|
|
|
"@d2l_rules_csharp//csharp/private:common.bzl",
|
|
|
|
|
"fill_in_missing_frameworks",
|
|
|
|
|
"is_core_framework",
|
|
|
|
|
"is_debug",
|
|
|
|
|
"is_standard_framework",
|
|
|
|
|
)
|
2023-09-26 00:48:29 +01:00
|
|
|
load("@d2l_rules_csharp//csharp/private:providers.bzl", "AnyTargetFrameworkInfo")
|
2020-11-12 10:40:01 -05:00
|
|
|
load("//dotnet/private:copy_files.bzl", "copy_files")
|
2020-10-28 14:59:00 -04:00
|
|
|
|
|
|
|
|
def _generate_execution_script_file(ctx, target):
|
|
|
|
|
tfm = target.actual_tfm
|
|
|
|
|
assembly_file_name = target.out.basename
|
|
|
|
|
shell_file_extension = "sh"
|
|
|
|
|
execution_line = "$( cd \"$(dirname \"$BASH_SOURCE[0]}\")\" >/dev/null 2>&1 && pwd -P )/" + assembly_file_name + " $@"
|
|
|
|
|
if ctx.attr.is_windows:
|
|
|
|
|
shell_file_extension = "bat"
|
|
|
|
|
execution_line = "%~dp0" + assembly_file_name + " %*"
|
2022-11-22 18:07:20 -05:00
|
|
|
if is_core_framework(tfm) or tfm == "net5.0" or tfm == "net6.0":
|
2020-10-28 14:59:00 -04:00
|
|
|
execution_line = "dotnet " + execution_line
|
|
|
|
|
else:
|
|
|
|
|
execution_line = "mono " + execution_line
|
|
|
|
|
|
|
|
|
|
toolchain = ctx.toolchains["@d2l_rules_csharp//csharp/private:toolchain_type"]
|
|
|
|
|
dotnet_sdk_location = toolchain.runtime.executable.dirname
|
|
|
|
|
environment = ""
|
|
|
|
|
if not ctx.attr.is_windows:
|
|
|
|
|
environment += "export DOTNET_CLI_HOME=%s\n" % dotnet_sdk_location
|
|
|
|
|
environment += "export APPDATA=%s\n" % dotnet_sdk_location
|
|
|
|
|
environment += "export PROGRAMFILES=%s\n" % dotnet_sdk_location
|
|
|
|
|
environment += "export USERPROFILE=%s\n" % dotnet_sdk_location
|
|
|
|
|
environment += "export DOTNET_CLI_TELEMETRY_OPTOUT=1\n"
|
2020-11-02 14:24:40 -05:00
|
|
|
else:
|
|
|
|
|
environment += "@echo off\n"
|
2020-10-28 14:59:00 -04:00
|
|
|
|
|
|
|
|
shell_content = environment + execution_line
|
|
|
|
|
|
|
|
|
|
shell_file_name = "bazelout/%s/%s.%s" % (tfm, assembly_file_name, shell_file_extension)
|
|
|
|
|
shell_file = ctx.actions.declare_file(shell_file_name)
|
|
|
|
|
ctx.actions.write(
|
|
|
|
|
output = shell_file,
|
|
|
|
|
content = shell_content,
|
|
|
|
|
is_executable = True,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return shell_file
|
|
|
|
|
|
|
|
|
|
def _copy_dependency_files(ctx, provider_value):
|
|
|
|
|
src_list = provider_value.transitive_runfiles.to_list()
|
|
|
|
|
target_dir = "bazelout/%s/" % (provider_value.actual_tfm)
|
2020-11-12 10:40:01 -05:00
|
|
|
file_list = []
|
|
|
|
|
for src_file in src_list:
|
|
|
|
|
file_list.append((src_file, src_file.basename))
|
2020-10-28 14:59:00 -04:00
|
|
|
|
2020-11-12 10:40:01 -05:00
|
|
|
return copy_files(ctx, file_list, target_dir, ctx.attr.is_windows)
|
2020-10-28 14:59:00 -04:00
|
|
|
|
|
|
|
|
def create_executable_assembly(ctx, extra_srcs, extra_deps):
|
|
|
|
|
stdrefs = [ctx.attr._stdrefs] if ctx.attr.include_stdrefs else []
|
|
|
|
|
|
|
|
|
|
providers = {}
|
|
|
|
|
for tfm in ctx.attr.target_frameworks:
|
|
|
|
|
if is_standard_framework(tfm):
|
|
|
|
|
fail("It doesn't make sense to build an executable for " + tfm)
|
|
|
|
|
|
|
|
|
|
providers[tfm] = AssemblyAction(
|
|
|
|
|
ctx.actions,
|
|
|
|
|
additionalfiles = ctx.files.additionalfiles,
|
|
|
|
|
analyzers = ctx.attr.analyzers,
|
|
|
|
|
debug = is_debug(ctx),
|
|
|
|
|
defines = ctx.attr.defines,
|
|
|
|
|
deps = ctx.attr.deps + extra_deps + stdrefs,
|
|
|
|
|
keyfile = ctx.file.keyfile,
|
2022-11-22 18:07:20 -05:00
|
|
|
internals_visible_to = None,
|
|
|
|
|
internals_visible_to_cs = None,
|
2020-10-28 14:59:00 -04:00
|
|
|
langversion = ctx.attr.langversion,
|
2025-03-05 12:20:15 -05:00
|
|
|
nullable = ctx.attr.nullable,
|
2020-10-28 14:59:00 -04:00
|
|
|
resources = ctx.files.resources,
|
|
|
|
|
srcs = ctx.files.srcs + extra_srcs,
|
|
|
|
|
out = ctx.attr.out,
|
|
|
|
|
target = "exe",
|
2022-11-22 18:07:20 -05:00
|
|
|
target_name = ctx.attr.name,
|
2020-10-28 14:59:00 -04:00
|
|
|
target_framework = tfm,
|
|
|
|
|
toolchain = ctx.toolchains["@d2l_rules_csharp//csharp/private:toolchain_type"],
|
|
|
|
|
)
|
|
|
|
|
|
2022-11-22 18:07:20 -05:00
|
|
|
fill_in_missing_frameworks(ctx.attr.out, providers)
|
2020-10-28 14:59:00 -04:00
|
|
|
|
|
|
|
|
result = providers.values()
|
|
|
|
|
dependency_files_list = _copy_dependency_files(ctx, result[0])
|
|
|
|
|
|
2020-12-04 10:55:19 -05:00
|
|
|
runtimeconfig = write_runtimeconfig(
|
|
|
|
|
ctx.actions,
|
|
|
|
|
ctx.file.runtimeconfig_template,
|
|
|
|
|
result[0].out.basename.replace("." + result[0].out.extension, ""),
|
2021-01-19 10:23:10 +00:00
|
|
|
result[0].actual_tfm,
|
|
|
|
|
)
|
2020-10-28 14:59:00 -04:00
|
|
|
|
|
|
|
|
data_runfiles = [] if ctx.attr.data == None else [d.files for d in ctx.attr.data]
|
|
|
|
|
|
|
|
|
|
shell_file = _generate_execution_script_file(ctx, result[0])
|
|
|
|
|
|
|
|
|
|
direct_runfiles = [result[0].out, result[0].pdb]
|
|
|
|
|
if runtimeconfig != None:
|
2021-04-24 22:07:28 +01:00
|
|
|
direct_runfiles.append(runtimeconfig)
|
2020-10-28 14:59:00 -04:00
|
|
|
|
|
|
|
|
result.append(DefaultInfo(
|
|
|
|
|
executable = shell_file,
|
|
|
|
|
runfiles = ctx.runfiles(
|
|
|
|
|
files = direct_runfiles,
|
|
|
|
|
transitive_files = depset(dependency_files_list, transitive = data_runfiles),
|
|
|
|
|
),
|
2022-11-22 18:07:20 -05:00
|
|
|
files = depset([result[0].out, result[0].prefout, result[0].pdb, shell_file]),
|
2020-10-28 14:59:00 -04:00
|
|
|
))
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
def _csharp_executable_impl(ctx):
|
|
|
|
|
extra_srcs = []
|
|
|
|
|
extra_deps = []
|
|
|
|
|
return create_executable_assembly(ctx, extra_srcs, extra_deps)
|
|
|
|
|
|
|
|
|
|
csharp_executable = rule(
|
|
|
|
|
_csharp_executable_impl,
|
|
|
|
|
doc = "Create an executable C# exe",
|
|
|
|
|
attrs = {
|
|
|
|
|
"srcs": attr.label_list(
|
|
|
|
|
doc = "C# source files.",
|
|
|
|
|
allow_files = [".cs"],
|
|
|
|
|
),
|
|
|
|
|
"additionalfiles": attr.label_list(
|
|
|
|
|
doc = "Extra files to configure analyzers.",
|
|
|
|
|
allow_files = True,
|
|
|
|
|
),
|
|
|
|
|
"analyzers": attr.label_list(
|
|
|
|
|
doc = "A list of analyzer references.",
|
|
|
|
|
providers = AnyTargetFrameworkInfo,
|
|
|
|
|
),
|
|
|
|
|
"keyfile": attr.label(
|
|
|
|
|
doc = "The key file used to sign the assembly with a strong name.",
|
|
|
|
|
allow_single_file = True,
|
|
|
|
|
),
|
|
|
|
|
"langversion": attr.string(
|
|
|
|
|
doc = "The version string for the C# language.",
|
|
|
|
|
),
|
2025-03-05 12:20:15 -05:00
|
|
|
"nullable": attr.string(
|
|
|
|
|
doc = "Enable nullable context, or nullable warnings.",
|
|
|
|
|
),
|
2020-10-28 14:59:00 -04:00
|
|
|
"resources": attr.label_list(
|
|
|
|
|
doc = "A list of files to embed in the DLL as resources.",
|
|
|
|
|
allow_files = True,
|
|
|
|
|
),
|
|
|
|
|
"out": attr.string(
|
|
|
|
|
doc = "File name, without extension, of the built assembly.",
|
|
|
|
|
),
|
|
|
|
|
"target_frameworks": attr.string_list(
|
|
|
|
|
doc = "A list of target framework monikers to build" +
|
|
|
|
|
"See https://docs.microsoft.com/en-us/dotnet/standard/frameworks",
|
|
|
|
|
allow_empty = False,
|
|
|
|
|
),
|
|
|
|
|
"defines": attr.string_list(
|
|
|
|
|
doc = "A list of preprocessor directive symbols to define.",
|
|
|
|
|
default = [],
|
|
|
|
|
allow_empty = True,
|
|
|
|
|
),
|
|
|
|
|
"include_stdrefs": attr.bool(
|
|
|
|
|
doc = "Whether to reference @net//:StandardReferences (the default set of references that MSBuild adds to every project).",
|
|
|
|
|
default = True,
|
|
|
|
|
),
|
|
|
|
|
"runtimeconfig_template": attr.label(
|
|
|
|
|
doc = "A template file to use for generating runtimeconfig.json",
|
|
|
|
|
default = "@d2l_rules_csharp//csharp/private:runtimeconfig.json.tpl",
|
|
|
|
|
allow_single_file = True,
|
|
|
|
|
),
|
|
|
|
|
"_stdrefs": attr.label(
|
|
|
|
|
doc = "The standard set of assemblies to reference.",
|
|
|
|
|
default = "@net//:StandardReferences",
|
|
|
|
|
),
|
|
|
|
|
"deps": attr.label_list(
|
|
|
|
|
doc = "Other C# libraries, binaries, or imported DLLs",
|
|
|
|
|
providers = AnyTargetFrameworkInfo,
|
|
|
|
|
),
|
|
|
|
|
"data": attr.label_list(
|
|
|
|
|
doc = "Additional data files or targets that are required to run the executable.",
|
|
|
|
|
allow_files = True,
|
|
|
|
|
),
|
|
|
|
|
"is_windows": attr.bool(default = False),
|
|
|
|
|
},
|
|
|
|
|
executable = True,
|
|
|
|
|
toolchains = ["@d2l_rules_csharp//csharp/private:toolchain_type"],
|
|
|
|
|
)
|