Refactored framework to avoid polymorphism complexity (#612)
* Refactored framework to be less complex * Deleted default commands (aka 'stale linux commands') * Restored toolchain name
This commit is contained in:
parent
98c88de5e0
commit
1bd2a8c547
|
@ -405,8 +405,7 @@ Information about the native tool
|
|||
<pre>
|
||||
rules_foreign_cc_dependencies(<a href="#rules_foreign_cc_dependencies-native_tools_toolchains">native_tools_toolchains</a>, <a href="#rules_foreign_cc_dependencies-register_default_tools">register_default_tools</a>, <a href="#rules_foreign_cc_dependencies-cmake_version">cmake_version</a>,
|
||||
<a href="#rules_foreign_cc_dependencies-make_version">make_version</a>, <a href="#rules_foreign_cc_dependencies-ninja_version">ninja_version</a>, <a href="#rules_foreign_cc_dependencies-register_preinstalled_tools">register_preinstalled_tools</a>,
|
||||
<a href="#rules_foreign_cc_dependencies-register_built_tools">register_built_tools</a>, <a href="#rules_foreign_cc_dependencies-additional_shell_toolchain_mappings">additional_shell_toolchain_mappings</a>,
|
||||
<a href="#rules_foreign_cc_dependencies-additional_shell_toolchain_package">additional_shell_toolchain_package</a>)
|
||||
<a href="#rules_foreign_cc_dependencies-register_built_tools">register_built_tools</a>)
|
||||
</pre>
|
||||
|
||||
Call this function from the WORKSPACE file to initialize rules_foreign_cc dependencies and let neccesary code generation happen (Code generation is needed to support different variants of the C++ Starlark API.).
|
||||
|
@ -423,7 +422,5 @@ Call this function from the WORKSPACE file to initialize rules_foreign_cc de
|
|||
| <a id="rules_foreign_cc_dependencies-ninja_version"></a>ninja_version | The target version of the ninja toolchain if <code>register_default_tools</code> or <code>register_built_tools</code> is set to <code>True</code>. | <code>"1.10.2"</code> |
|
||||
| <a id="rules_foreign_cc_dependencies-register_preinstalled_tools"></a>register_preinstalled_tools | If true, toolchains will be registered for the native built tools installed on the exec host | <code>True</code> |
|
||||
| <a id="rules_foreign_cc_dependencies-register_built_tools"></a>register_built_tools | If true, toolchains that build the tools from source are registered | <code>True</code> |
|
||||
| <a id="rules_foreign_cc_dependencies-additional_shell_toolchain_mappings"></a>additional_shell_toolchain_mappings | Mappings of the shell toolchain functions to execution and target platforms constraints. Similar to what defined in @rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains:toolchain_mappings.bzl in the TOOLCHAIN_MAPPINGS list. Please refer to example in @rules_foreign_cc//toolchain_examples. | <code>[]</code> |
|
||||
| <a id="rules_foreign_cc_dependencies-additional_shell_toolchain_package"></a>additional_shell_toolchain_package | A package under which additional toolchains, referencing the generated data for the passed additonal_shell_toolchain_mappings, will be defined. This value is needed since register_toolchains() is called for these toolchains. Please refer to example in @rules_foreign_cc//toolchain_examples. | <code>None</code> |
|
||||
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ boost_build = rule(
|
|||
output_to_genfiles = True,
|
||||
implementation = _boost_build_impl,
|
||||
toolchains = [
|
||||
"@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains:shell_commands",
|
||||
"@rules_foreign_cc//foreign_cc/private/framework:shell_toolchain",
|
||||
"@bazel_tools//tools/cpp:toolchain_type",
|
||||
],
|
||||
# TODO: Remove once https://github.com/bazelbuild/bazel/issues/11584 is closed and the min supported
|
||||
|
|
|
@ -29,7 +29,7 @@ cmake_tool = rule(
|
|||
output_to_genfiles = True,
|
||||
implementation = _cmake_tool_impl,
|
||||
toolchains = [
|
||||
str(Label("//foreign_cc/private/shell_toolchain/toolchains:shell_commands")),
|
||||
str(Label("//foreign_cc/private/framework:shell_toolchain")),
|
||||
"@bazel_tools//tools/cpp:toolchain_type",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -6,7 +6,7 @@ load(
|
|||
"FOREIGN_CC_BUILT_TOOLS_HOST_FRAGMENTS",
|
||||
"built_tool_rule_impl",
|
||||
)
|
||||
load("//foreign_cc/private:shell_script_helper.bzl", "os_name")
|
||||
load("//foreign_cc/private/framework:helpers.bzl", "os_name")
|
||||
|
||||
def _make_tool_impl(ctx):
|
||||
script = [
|
||||
|
@ -37,7 +37,7 @@ make_tool = rule(
|
|||
output_to_genfiles = True,
|
||||
implementation = _make_tool_impl,
|
||||
toolchains = [
|
||||
str(Label("//foreign_cc/private/shell_toolchain/toolchains:shell_commands")),
|
||||
str(Label("//foreign_cc/private/framework:shell_toolchain")),
|
||||
"@bazel_tools//tools/cpp:toolchain_type",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -6,7 +6,7 @@ load(
|
|||
"FOREIGN_CC_BUILT_TOOLS_HOST_FRAGMENTS",
|
||||
"built_tool_rule_impl",
|
||||
)
|
||||
load("//foreign_cc/private:shell_script_helper.bzl", "os_name")
|
||||
load("//foreign_cc/private/framework:helpers.bzl", "os_name")
|
||||
|
||||
def _ninja_tool_impl(ctx):
|
||||
script = [
|
||||
|
@ -31,7 +31,7 @@ ninja_tool = rule(
|
|||
output_to_genfiles = True,
|
||||
implementation = _ninja_tool_impl,
|
||||
toolchains = [
|
||||
str(Label("//foreign_cc/private/shell_toolchain/toolchains:shell_commands")),
|
||||
str(Label("//foreign_cc/private/framework:shell_toolchain")),
|
||||
"@bazel_tools//tools/cpp:toolchain_type",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
|
||||
load("//foreign_cc/private:detect_root.bzl", "detect_root")
|
||||
load("//foreign_cc/private:framework.bzl", "wrap_outputs")
|
||||
load("//foreign_cc/private:shell_script_helper.bzl", "convert_shell_script")
|
||||
load("//foreign_cc/private/framework:helpers.bzl", "convert_shell_script")
|
||||
|
||||
# Common attributes for all built_tool rules
|
||||
FOREIGN_CC_BUILT_TOOLS_ATTRS = {
|
||||
|
|
|
@ -16,10 +16,7 @@ load(
|
|||
"cc_external_rule_impl",
|
||||
"create_attrs",
|
||||
)
|
||||
load(
|
||||
"//foreign_cc/private:shell_script_helper.bzl",
|
||||
"os_name",
|
||||
)
|
||||
load("//foreign_cc/private/framework:helpers.bzl", "os_name")
|
||||
load(
|
||||
"//toolchains/native_tools:tool_access.bzl",
|
||||
"get_cmake_data",
|
||||
|
@ -279,7 +276,7 @@ cmake = rule(
|
|||
"@rules_foreign_cc//toolchains:cmake_toolchain",
|
||||
"@rules_foreign_cc//toolchains:ninja_toolchain",
|
||||
"@rules_foreign_cc//toolchains:make_toolchain",
|
||||
"@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains:shell_commands",
|
||||
"@rules_foreign_cc//foreign_cc/private/framework:shell_toolchain",
|
||||
"@bazel_tools//tools/cpp:toolchain_type",
|
||||
],
|
||||
# TODO: Remove once https://github.com/bazelbuild/bazel/issues/11584 is closed and the min supported
|
||||
|
|
|
@ -14,7 +14,7 @@ load(
|
|||
"cc_external_rule_impl",
|
||||
"create_attrs",
|
||||
)
|
||||
load("//foreign_cc/private:shell_script_helper.bzl", "os_name")
|
||||
load("//foreign_cc/private/framework:helpers.bzl", "os_name")
|
||||
load("//toolchains/native_tools:tool_access.bzl", "get_make_data")
|
||||
|
||||
def _configure_make(ctx):
|
||||
|
@ -211,7 +211,7 @@ configure_make = rule(
|
|||
implementation = _configure_make,
|
||||
toolchains = [
|
||||
"@rules_foreign_cc//toolchains:make_toolchain",
|
||||
"@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains:shell_commands",
|
||||
"@rules_foreign_cc//foreign_cc/private/framework:shell_toolchain",
|
||||
"@bazel_tools//tools/cpp:toolchain_type",
|
||||
],
|
||||
# TODO: Remove once https://github.com/bazelbuild/bazel/issues/11584 is closed and the min supported
|
||||
|
|
|
@ -96,7 +96,7 @@ make = rule(
|
|||
implementation = _make,
|
||||
toolchains = [
|
||||
"@rules_foreign_cc//toolchains:make_toolchain",
|
||||
"@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains:shell_commands",
|
||||
"@rules_foreign_cc//foreign_cc/private/framework:shell_toolchain",
|
||||
"@bazel_tools//tools/cpp:toolchain_type",
|
||||
],
|
||||
# TODO: Remove once https://github.com/bazelbuild/bazel/issues/11584 is closed and the min supported
|
||||
|
|
|
@ -113,7 +113,7 @@ ninja = rule(
|
|||
implementation = _ninja_impl,
|
||||
toolchains = [
|
||||
"@rules_foreign_cc//toolchains:ninja_toolchain",
|
||||
"@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains:shell_commands",
|
||||
"@rules_foreign_cc//foreign_cc/private/framework:shell_toolchain",
|
||||
"@bazel_tools//tools/cpp:toolchain_type",
|
||||
],
|
||||
# TODO: Remove once https://github.com/bazelbuild/bazel/issues/11584 is closed and the min supported
|
||||
|
|
|
@ -5,7 +5,6 @@ bzl_library(
|
|||
srcs = glob(["**/*.bzl"]),
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//foreign_cc/private/shell_toolchain/polymorphism:bzl_srcs",
|
||||
"//foreign_cc/private/shell_toolchain/toolchains:bzl_srcs",
|
||||
"//foreign_cc/private/framework:bzl_srcs",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -6,6 +6,12 @@ load("@bazel_skylib//lib:collections.bzl", "collections")
|
|||
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
|
||||
load("//foreign_cc:providers.bzl", "ForeignCcArtifact", "ForeignCcDeps")
|
||||
load("//foreign_cc/private:detect_root.bzl", "detect_root", "filter_containing_dirs_from_inputs")
|
||||
load(
|
||||
"//foreign_cc/private/framework:helpers.bzl",
|
||||
"convert_shell_script",
|
||||
"create_function",
|
||||
"os_name",
|
||||
)
|
||||
load(
|
||||
"//toolchains/native_tools:tool_access.bzl",
|
||||
"get_make_data",
|
||||
|
@ -23,12 +29,6 @@ load(
|
|||
"copy_directory",
|
||||
"fictive_file_in_genroot",
|
||||
)
|
||||
load(
|
||||
":shell_script_helper.bzl",
|
||||
"convert_shell_script",
|
||||
"create_function",
|
||||
"os_name",
|
||||
)
|
||||
|
||||
# Dict with definitions of the context attributes, that customize cc_external_rule_impl function.
|
||||
# Many of the attributes have default values.
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
|
||||
|
||||
toolchain_type(
|
||||
name = "shell_toolchain",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
bzl_library(
|
||||
name = "bzl_srcs",
|
||||
srcs = glob(["**/*.bzl"]),
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = ["//foreign_cc/private/framework/toolchains:bzl_srcs"],
|
||||
)
|
|
@ -31,8 +31,8 @@ Since function definitions can call other functions, we perform the fictive tran
|
|||
of the function bodies to populate the "prelude" part of the script.
|
||||
"""
|
||||
|
||||
load("//foreign_cc/private/shell_toolchain/toolchains:access.bzl", "call_shell", "create_context")
|
||||
load("//foreign_cc/private/shell_toolchain/toolchains:commands.bzl", "PLATFORM_COMMANDS")
|
||||
load("//foreign_cc/private/framework/toolchains:access.bzl", "call_shell", "create_context")
|
||||
load("//foreign_cc/private/framework/toolchains:commands.bzl", "PLATFORM_COMMANDS")
|
||||
|
||||
def os_name(ctx):
|
||||
return call_shell(create_context(ctx), "os_name")
|
|
@ -0,0 +1,106 @@
|
|||
"""A module containing the implementation of the foreign_cc framework's toolchains"""
|
||||
|
||||
load("//foreign_cc/private/framework/toolchains:commands.bzl", "PLATFORM_COMMANDS")
|
||||
load("//foreign_cc/private/framework/toolchains:mappings.bzl", "TOOLCHAIN_MAPPINGS")
|
||||
|
||||
_BUILD_FILE_CONTENT = """\
|
||||
load("//:defs.bzl", "foreign_cc_framework_toolchain")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
exports_files(["defs.bzl"])
|
||||
|
||||
foreign_cc_framework_toolchain(
|
||||
name = "commands"
|
||||
)
|
||||
|
||||
toolchain(
|
||||
name = "toolchain",
|
||||
toolchain_type = "@rules_foreign_cc//foreign_cc/private/framework:shell_toolchain",
|
||||
toolchain = "//:commands",
|
||||
exec_compatible_with = {exec_compat},
|
||||
target_compatible_with = {target_compat},
|
||||
)
|
||||
"""
|
||||
|
||||
_DEFS_BZL_CONTENT = """\
|
||||
load(
|
||||
"{commands_src}",
|
||||
{symbols}
|
||||
)
|
||||
|
||||
commands = struct(
|
||||
{commands}
|
||||
)
|
||||
|
||||
def _foreign_cc_framework_toolchain_impl(ctx):
|
||||
return platform_common.ToolchainInfo(
|
||||
commands = commands,
|
||||
)
|
||||
|
||||
foreign_cc_framework_toolchain = rule(
|
||||
doc = "A toolchain contianing foreign_cc commands",
|
||||
implementation = _foreign_cc_framework_toolchain_impl,
|
||||
)
|
||||
"""
|
||||
|
||||
def _framework_toolchain_repository_impl(repository_ctx):
|
||||
"""The implementation of `framework_toolchain_repository`
|
||||
|
||||
Args:
|
||||
repository_ctx (repository_ctx): The rule's context object
|
||||
"""
|
||||
|
||||
# Ensure we always have an absolute label. This may not be the case
|
||||
# when building within the `@rules_foreign_cc` workspace.
|
||||
absolute_label = str(repository_ctx.attr.commands_src)
|
||||
if not absolute_label.startswith("@"):
|
||||
absolute_label = "@rules_foreign_cc" + absolute_label
|
||||
|
||||
repository_ctx.file("defs.bzl", _DEFS_BZL_CONTENT.format(
|
||||
commands_src = absolute_label,
|
||||
symbols = "\n ".join(["\"{}\",".format(symbol) for symbol in PLATFORM_COMMANDS.keys()]),
|
||||
commands = "\n ".join(["{cmd} = {cmd},".format(cmd = symbol) for symbol in PLATFORM_COMMANDS.keys()]),
|
||||
))
|
||||
|
||||
repository_ctx.file("BUILD.bazel", _BUILD_FILE_CONTENT.format(
|
||||
exec_compat = repository_ctx.attr.exec_compatible_with,
|
||||
target_compat = repository_ctx.attr.target_compatible_with,
|
||||
))
|
||||
|
||||
framework_toolchain_repository = repository_rule(
|
||||
doc = "A repository rule which defines a `@rules_foreign_cc//foreign_cc/private/framework:shell_toolchain` toolchain.",
|
||||
implementation = _framework_toolchain_repository_impl,
|
||||
attrs = {
|
||||
"commands_src": attr.label(
|
||||
doc = "The label of a `.bzl` source which defines toolchain commands",
|
||||
allow_files = [".bzl"],
|
||||
),
|
||||
"exec_compatible_with": attr.string_list(
|
||||
doc = "A list of constraint_values that must be present in the execution platform for this target.",
|
||||
),
|
||||
"target_compatible_with": attr.string_list(
|
||||
doc = "A list of constraint_values that must be present in the target platform for this target to be considered compatible.",
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
# buildifier: disable=unnamed-macro
|
||||
def register_framework_toolchains():
|
||||
"""Define and register the foreign_cc framework toolchains"""
|
||||
toolchains = []
|
||||
|
||||
for item in TOOLCHAIN_MAPPINGS:
|
||||
# Generate a toolchain name without the `.bzl` suffix
|
||||
toolchain_name = "rules_foreign_cc_framework_toolchain_" + item.file.name[:-len(".bzl")]
|
||||
|
||||
framework_toolchain_repository(
|
||||
name = toolchain_name,
|
||||
commands_src = item.file,
|
||||
exec_compatible_with = item.exec_compatible_with,
|
||||
target_compatible_with = item.target_compatible_with,
|
||||
)
|
||||
|
||||
toolchains.append("@{}//:toolchain".format(toolchain_name))
|
||||
|
||||
native.register_toolchains(*toolchains)
|
|
@ -0,0 +1,102 @@
|
|||
"""A module defining functionality for invoking toolchain commands"""
|
||||
|
||||
load(":commands.bzl", "FunctionAndCallInfo", "PLATFORM_COMMANDS")
|
||||
|
||||
_function_and_call_type = type(FunctionAndCallInfo(text = ""))
|
||||
|
||||
def create_context(ctx):
|
||||
"""Generate a 'context' object from the current foreign_cc framework toolchain
|
||||
|
||||
Args:
|
||||
ctx (ctx): The current rule's context object
|
||||
|
||||
Returns:
|
||||
struct: A foreign_cc framework context:
|
||||
- shell (struct): All commands for the current toolchain
|
||||
- prelude (dict): A cache for rendered functions
|
||||
"""
|
||||
return struct(
|
||||
shell = ctx.toolchains[str(Label("//foreign_cc/private/framework:shell_toolchain"))].commands,
|
||||
prelude = {},
|
||||
)
|
||||
|
||||
def call_shell(shell_context, method_, *args):
|
||||
"""Calls the 'method_' shell command from the toolchain.
|
||||
|
||||
Checks the number and types of passed arguments.
|
||||
If the command returns the resulting text wrapped into `FunctionAndCallInfo` provider,
|
||||
puts the text of the function into the 'prelude' dictionary in the 'shell_context',
|
||||
and returns only the call of that function.
|
||||
|
||||
Args:
|
||||
shell_context (struct): A shell_context created by `create_context`
|
||||
method_ (str): The command to invoke from teh shell context's commands
|
||||
*args: Optinal arguments to accomponany `method_`
|
||||
|
||||
Returns:
|
||||
str: the rendered command
|
||||
"""
|
||||
check_argument_types(method_, args)
|
||||
|
||||
func_ = getattr(shell_context.shell, method_)
|
||||
result = func_(*args)
|
||||
|
||||
if type(result) == _function_and_call_type:
|
||||
# Cache the rendered function for use when rendering
|
||||
# the full scrupt in `convert_shell_script_by_context`
|
||||
if not shell_context.prelude.get(method_):
|
||||
shell_context.prelude[method_] = shell_context.shell.define_function(method_, result.text)
|
||||
|
||||
# use provided method of calling a defined function or use default
|
||||
if hasattr(result, "call"):
|
||||
return result.call
|
||||
|
||||
# TODO: This doesn't play well with arguments such as `foo="bar"`.
|
||||
return " ".join([method_] + [_wrap_if_needed(str(arg)) for arg in args])
|
||||
|
||||
return result
|
||||
|
||||
def _quoted(arg):
|
||||
"""Check if arguments to framework functions are wrapped in quotes.
|
||||
|
||||
Args:
|
||||
arg (str): The target argument
|
||||
|
||||
Returns:
|
||||
bool: True if `arg` is quoted
|
||||
"""
|
||||
return arg.startswith("\"") and arg.endswith("\"")
|
||||
|
||||
def _wrap_if_needed(arg):
|
||||
"""Ensure arguments to framework functions are wrapped in quotes.
|
||||
|
||||
Args:
|
||||
arg (str): The target argument
|
||||
|
||||
Returns:
|
||||
str: `arg` guaranteed to be wrapped by double quotes (`"`)
|
||||
"""
|
||||
if arg.find(" ") >= 0 and not _quoted(arg):
|
||||
return "\"" + arg + "\""
|
||||
return arg
|
||||
|
||||
def check_argument_types(method_, args_list):
|
||||
"""Check a method's argument types
|
||||
|
||||
Args:
|
||||
method_ (str): The target method
|
||||
args_list (list): A list of arguments to check
|
||||
"""
|
||||
descriptor = PLATFORM_COMMANDS[method_]
|
||||
args_info = descriptor.arguments
|
||||
|
||||
if len(args_list) != len(args_info):
|
||||
fail("Wrong number ({}) of arguments ({}) in a call to '{}'".format(
|
||||
len(args_list),
|
||||
str(args_list),
|
||||
method_,
|
||||
))
|
||||
|
||||
for idx in range(0, len(args_list)):
|
||||
if type(args_list[idx]) != args_info[idx].data_type:
|
||||
fail("Wrong argument '{}' type: '{}'".format(args_info[idx].name, type(args_list[idx])))
|
|
@ -0,0 +1,218 @@
|
|||
"""A module difining all commands for a foreign_cc framework toolchain"""
|
||||
|
||||
FunctionAndCallInfo = provider(
|
||||
doc = "Wrapper to pass function definition and (if custom) function call",
|
||||
fields = {
|
||||
"call": "How to call defined function, if different from <function-name> <arg1> ...<argn>",
|
||||
"text": "Function body, without wrapping function <name>() {} fragment.",
|
||||
},
|
||||
)
|
||||
|
||||
def _command_info(arguments, doc):
|
||||
"""To pass information about the Starlark function, defining the shell fragment.
|
||||
|
||||
Args:
|
||||
arguments (list): Arguments of Starlark function (`_argument_info`)
|
||||
doc (str): What the shell script fragment, generated by this function, does.
|
||||
|
||||
Returns:
|
||||
struct: A struct of command info
|
||||
"""
|
||||
return struct(
|
||||
arguments = arguments,
|
||||
doc = doc,
|
||||
)
|
||||
|
||||
def _argument_info(name, data_type, doc):
|
||||
"""Generates a struct of information about a command argument for `_command_info` commands
|
||||
|
||||
Args:
|
||||
name (str): The name fo the argument
|
||||
data_type (str): The type of the data, typically the result of `type(...)`
|
||||
doc (str): Documentation for the argument
|
||||
|
||||
Returns:
|
||||
struct: A struct of argument info
|
||||
"""
|
||||
return struct(
|
||||
name = name,
|
||||
doc = doc,
|
||||
data_type = data_type,
|
||||
)
|
||||
|
||||
PLATFORM_COMMANDS = {
|
||||
"assert_script_errors": _command_info(
|
||||
arguments = [],
|
||||
doc = "Script fragment that stops the execution after any error",
|
||||
),
|
||||
"cat": _command_info(
|
||||
arguments = [
|
||||
_argument_info(name = "filepath", data_type = type(""), doc = "Path to the file"),
|
||||
],
|
||||
doc = "Output the file contents to stdout",
|
||||
),
|
||||
"children_to_path": _command_info(
|
||||
arguments = [
|
||||
_argument_info(name = "dir_", data_type = type(""), doc = "Directory"),
|
||||
],
|
||||
doc = "Put all immediate subdirectories (and symlinks) into PATH",
|
||||
),
|
||||
"cleanup_function": _command_info(
|
||||
arguments = [
|
||||
_argument_info(name = "on_success", data_type = type(""), doc = "Command(s) to be executed on success"),
|
||||
_argument_info(name = "on_failure", data_type = type(""), doc = "Command(s) to be executed on failure"),
|
||||
],
|
||||
doc = "Trap function called after the script is finished",
|
||||
# doc = "Read the result of the execution of the previous command, execute success or failure callbacks",
|
||||
),
|
||||
"copy_dir_contents_to_dir": _command_info(
|
||||
arguments = [
|
||||
_argument_info(
|
||||
name = "source",
|
||||
data_type = type(""),
|
||||
doc = "Source directory, immediate children of which are copied",
|
||||
),
|
||||
_argument_info(name = "target", data_type = type(""), doc = "Target directory"),
|
||||
],
|
||||
doc = "Copies contents of the directory to target directory",
|
||||
),
|
||||
"define_absolute_paths": _command_info(
|
||||
arguments = [
|
||||
_argument_info(name = "dir_", data_type = type(""), doc = "Directory where to replace"),
|
||||
_argument_info(name = "abs_path", data_type = type(""), doc = "Absolute path value"),
|
||||
],
|
||||
doc = "Replaces absolute path placeholder inside 'dir_' with a provided value 'abs_path'",
|
||||
),
|
||||
"define_function": _command_info(
|
||||
arguments = [
|
||||
_argument_info(name = "name", data_type = type(""), doc = "Function name"),
|
||||
_argument_info(name = "text", data_type = type(""), doc = "Function body"),
|
||||
],
|
||||
doc = "Defines a function with 'text' as the function body.",
|
||||
),
|
||||
"echo": _command_info(
|
||||
arguments = [_argument_info(name = "text", data_type = type(""), doc = "Text to output")],
|
||||
doc = "Outputs 'text' to stdout",
|
||||
),
|
||||
"env": _command_info(
|
||||
arguments = [],
|
||||
doc = "Print all environment variables",
|
||||
),
|
||||
"export_var": _command_info(
|
||||
arguments = [
|
||||
_argument_info(name = "name", data_type = type(""), doc = "Variable name"),
|
||||
_argument_info(name = "value", data_type = type(""), doc = "Variable value"),
|
||||
],
|
||||
doc = "Defines and exports environment variable.",
|
||||
),
|
||||
"if_else": _command_info(
|
||||
doc = "Creates if-else construct",
|
||||
arguments = [
|
||||
_argument_info(name = "condition", data_type = type(""), doc = "Condition text"),
|
||||
_argument_info(name = "if_text", data_type = type(""), doc = "If block text"),
|
||||
_argument_info(name = "else_text", data_type = type(""), doc = "Else block text"),
|
||||
],
|
||||
),
|
||||
"increment_pkg_config_path": _command_info(
|
||||
arguments = [
|
||||
_argument_info(
|
||||
name = "source",
|
||||
data_type = type(""),
|
||||
doc = "Source directory",
|
||||
),
|
||||
],
|
||||
doc = (
|
||||
"Find subdirectory inside a passed directory with *.pc files and add it " +
|
||||
"to the PKG_CONFIG_PATH"
|
||||
),
|
||||
),
|
||||
"local_var": _command_info(
|
||||
arguments = [
|
||||
_argument_info(name = "name", data_type = type(""), doc = "Variable name"),
|
||||
_argument_info(name = "value", data_type = type(""), doc = "Variable value"),
|
||||
],
|
||||
doc = "Defines local shell variable.",
|
||||
),
|
||||
"mkdirs": _command_info(
|
||||
arguments = [_argument_info(name = "path", data_type = type(""), doc = "Path to directory")],
|
||||
doc = "Creates a directory and, if neccesary, it's parents",
|
||||
),
|
||||
"os_name": _command_info(
|
||||
arguments = [],
|
||||
doc = "Returns OS name",
|
||||
),
|
||||
"path": _command_info(
|
||||
arguments = [
|
||||
_argument_info(name = "expression", data_type = type(""), doc = "Path"),
|
||||
],
|
||||
doc = "Adds passed arguments in the beginning of the PATH.",
|
||||
),
|
||||
"pwd": _command_info(
|
||||
arguments = [],
|
||||
doc = "Returns command for getting current directory.",
|
||||
),
|
||||
"redirect_out_err": _command_info(
|
||||
arguments = [
|
||||
_argument_info(name = "from_process", data_type = type(""), doc = "Process to run"),
|
||||
_argument_info(name = "to_file", data_type = type(""), doc = "File to redirect output to"),
|
||||
],
|
||||
doc = "Read the result of the execution of the previous command, execute success or failure callbacks",
|
||||
),
|
||||
"replace_absolute_paths": _command_info(
|
||||
arguments = [
|
||||
_argument_info(name = "dir_", data_type = type(""), doc = "Directory where to replace"),
|
||||
_argument_info(name = "abs_path", data_type = type(""), doc = "Absolute path value"),
|
||||
],
|
||||
doc = "Replaces absolute path 'abs_path' inside 'dir_' with a placeholder value",
|
||||
),
|
||||
"replace_in_files": _command_info(
|
||||
arguments = [
|
||||
_argument_info(name = "dir_", data_type = type(""), doc = "Directory to search recursively"),
|
||||
_argument_info(name = "from_", data_type = type(""), doc = "String to be replaced"),
|
||||
_argument_info(name = "to_", data_type = type(""), doc = "Replace target"),
|
||||
],
|
||||
doc = "Replaces all occurrences of 'from_' to 'to_' recursively in the directory 'dir'.",
|
||||
),
|
||||
"script_prelude": _command_info(
|
||||
arguments = [],
|
||||
doc = "Function for setting necessary environment variables for the platform",
|
||||
),
|
||||
"symlink_contents_to_dir": _command_info(
|
||||
arguments = [
|
||||
_argument_info(
|
||||
name = "source",
|
||||
data_type = type(""),
|
||||
doc = "Source directory, immediate children of which are symlinked, or file to be symlinked.",
|
||||
),
|
||||
_argument_info(name = "target", data_type = type(""), doc = "Target directory"),
|
||||
],
|
||||
doc = (
|
||||
"Symlink contents of the directory to target directory (create the target directory if needed). " +
|
||||
"If file is passed, symlink it into the target directory."
|
||||
),
|
||||
),
|
||||
"symlink_to_dir": _command_info(
|
||||
arguments = [
|
||||
_argument_info(
|
||||
name = "source",
|
||||
data_type = type(""),
|
||||
doc = "Source directory",
|
||||
),
|
||||
_argument_info(name = "target", data_type = type(""), doc = "Target directory"),
|
||||
],
|
||||
doc = (
|
||||
"Symlink all files from source directory to target directory (create the target directory if needed). " +
|
||||
"NB symlinks from the source directory are copied."
|
||||
),
|
||||
),
|
||||
"touch": _command_info(
|
||||
arguments = [_argument_info(name = "path", data_type = type(""), doc = "Path to file")],
|
||||
doc = "Creates a file",
|
||||
),
|
||||
"use_var": _command_info(
|
||||
arguments = [
|
||||
_argument_info(name = "name", data_type = type(""), doc = "Variable name"),
|
||||
],
|
||||
doc = "Expression to address the variable.",
|
||||
),
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
# buildifier: disable=module-docstring
|
||||
load("@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains:function_and_call.bzl", "FunctionAndCallInfo")
|
||||
"""Define default foreign_cc framework commands. Linux platforms use bash"""
|
||||
|
||||
load(":commands.bzl", "FunctionAndCallInfo")
|
||||
|
||||
_REPLACE_VALUE = "\\${EXT_BUILD_DEPS}"
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
# buildifier: disable=module-docstring
|
||||
load("@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains:function_and_call.bzl", "FunctionAndCallInfo")
|
||||
"""Define MacOS foreign_cc framework commands. MacOS platforms uses Bash"""
|
||||
|
||||
load(":commands.bzl", "FunctionAndCallInfo")
|
||||
|
||||
_REPLACE_VALUE = "\\${EXT_BUILD_DEPS}"
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
"""A module defining default toolchain info for the foreign_cc framework"""
|
||||
|
||||
def _toolchain_mapping(file, exec_compatible_with = [], target_compatible_with = []):
|
||||
"""Mapping of toolchain definition files to platform constraints
|
||||
|
||||
Args:
|
||||
file (Label): Toolchain definition file
|
||||
exec_compatible_with (list): A list of compatible execution platform constraints.
|
||||
target_compatible_with (list): Compatible target platform constraints
|
||||
|
||||
Returns:
|
||||
struct: A collection of toolchain data
|
||||
"""
|
||||
return struct(
|
||||
file = file,
|
||||
exec_compatible_with = exec_compatible_with,
|
||||
target_compatible_with = target_compatible_with,
|
||||
)
|
||||
|
||||
# This list is the single entrypoint for all foreing_cc framework toolchains.
|
||||
TOOLCHAIN_MAPPINGS = [
|
||||
_toolchain_mapping(
|
||||
exec_compatible_with = [
|
||||
"@platforms//os:linux",
|
||||
],
|
||||
file = Label("@rules_foreign_cc//foreign_cc/private/framework/toolchains:linux_commands.bzl"),
|
||||
),
|
||||
_toolchain_mapping(
|
||||
exec_compatible_with = [
|
||||
"@platforms//os:windows",
|
||||
],
|
||||
file = Label("@rules_foreign_cc//foreign_cc/private/framework/toolchains:windows_commands.bzl"),
|
||||
),
|
||||
_toolchain_mapping(
|
||||
exec_compatible_with = [
|
||||
"@platforms//os:macos",
|
||||
],
|
||||
file = Label("@rules_foreign_cc//foreign_cc/private/framework/toolchains:macos_commands.bzl"),
|
||||
),
|
||||
]
|
|
@ -1,5 +1,6 @@
|
|||
# buildifier: disable=module-docstring
|
||||
load("@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains:function_and_call.bzl", "FunctionAndCallInfo")
|
||||
"""Define windows foreign_cc framework commands. Windows uses Bash"""
|
||||
|
||||
load(":commands.bzl", "FunctionAndCallInfo")
|
||||
|
||||
_REPLACE_VALUE = "\\${EXT_BUILD_DEPS}"
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
# buildifier: disable=module-docstring
|
||||
def _provider_text(symbols):
|
||||
return """
|
||||
WRAPPER = provider(
|
||||
doc = "Wrapper to hold imported methods",
|
||||
fields = [{}]
|
||||
)
|
||||
""".format(", ".join(["\"%s\"" % symbol_ for symbol_ in symbols]))
|
||||
|
||||
def _getter_text():
|
||||
return """
|
||||
def id_from_file(file_name):
|
||||
(before, middle, after) = file_name.partition(".")
|
||||
return before
|
||||
|
||||
def get(file_name):
|
||||
id = id_from_file(file_name)
|
||||
return WRAPPER(**_MAPPING[id])
|
||||
"""
|
||||
|
||||
def _mapping_text(ids):
|
||||
data_ = []
|
||||
for id in ids:
|
||||
data_.append("{id} = wrapper_{id}".format(id = id))
|
||||
return "_MAPPING = dict(\n{data}\n)".format(data = ",\n".join(data_))
|
||||
|
||||
def _load_and_wrapper_text(id, file_path, symbols):
|
||||
load_list = ", ".join(["{id}_{symbol} = \"{symbol}\"".format(id = id, symbol = symbol_) for symbol_ in symbols])
|
||||
load_statement = "load(\":{file}\", {list})".format(file = file_path, list = load_list)
|
||||
data = ", ".join(["{symbol} = {id}_{symbol}".format(id = id, symbol = symbol_) for symbol_ in symbols])
|
||||
wrapper_statement = "wrapper_{id} = dict({data})".format(id = id, data = data)
|
||||
return struct(
|
||||
load_ = load_statement,
|
||||
wrapper = wrapper_statement,
|
||||
)
|
||||
|
||||
def id_from_file(file_name):
|
||||
(before, middle, after) = file_name.partition(".")
|
||||
return before
|
||||
|
||||
def get_file_name(file_label):
|
||||
(before, separator, after) = file_label.partition(":")
|
||||
return id_from_file(after)
|
||||
|
||||
def _copy_file(rctx, src):
|
||||
src_path = rctx.path(src)
|
||||
copy_path = src_path.basename
|
||||
rctx.template(copy_path, src_path)
|
||||
return copy_path
|
||||
|
||||
_BUILD_FILE = """\
|
||||
exports_files(
|
||||
[
|
||||
"toolchain_data_defs.bzl",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
"""
|
||||
|
||||
def _generate_overloads(rctx):
|
||||
symbols = rctx.attr.symbols
|
||||
ids = []
|
||||
lines = ["# Generated overload mappings"]
|
||||
loads = []
|
||||
wrappers = []
|
||||
for file_ in rctx.attr.files:
|
||||
id = id_from_file(file_.name)
|
||||
ids.append(id)
|
||||
copy = _copy_file(rctx, file_)
|
||||
load_and_wrapper = _load_and_wrapper_text(id, copy, symbols)
|
||||
loads.append(load_and_wrapper.load_)
|
||||
wrappers.append(load_and_wrapper.wrapper)
|
||||
lines += loads
|
||||
lines += wrappers
|
||||
lines.append(_mapping_text(ids))
|
||||
lines.append(_provider_text(symbols))
|
||||
lines.append(_getter_text())
|
||||
|
||||
rctx.file("toolchain_data_defs.bzl", "\n".join(lines))
|
||||
rctx.file("BUILD", _BUILD_FILE)
|
||||
|
||||
generate_overloads = repository_rule(
|
||||
implementation = _generate_overloads,
|
||||
attrs = {
|
||||
"files": attr.label_list(),
|
||||
"symbols": attr.string_list(),
|
||||
},
|
||||
)
|
|
@ -1,20 +0,0 @@
|
|||
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
|
||||
load(":defs.bzl", "build_part")
|
||||
|
||||
toolchain_type(
|
||||
name = "shell_commands",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
build_part(
|
||||
toolchain_type = ":shell_commands",
|
||||
)
|
||||
|
||||
bzl_library(
|
||||
name = "bzl_srcs",
|
||||
srcs = glob(["**/*.bzl"]) + [
|
||||
"@rules_foreign_cc_commands_overloads//:toolchain_data_defs.bzl",
|
||||
],
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = ["//foreign_cc/private/shell_toolchain/toolchains/impl:bzl_srcs"],
|
||||
)
|
|
@ -1,63 +0,0 @@
|
|||
# buildifier: disable=module-docstring
|
||||
load("//foreign_cc/private/shell_toolchain/toolchains:commands.bzl", "PLATFORM_COMMANDS")
|
||||
load(":function_and_call.bzl", "FunctionAndCallInfo")
|
||||
|
||||
_function_and_call_type = type(FunctionAndCallInfo(text = ""))
|
||||
|
||||
def create_context(ctx):
|
||||
return struct(
|
||||
shell = ctx.toolchains["@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains:shell_commands"].data,
|
||||
prelude = {},
|
||||
)
|
||||
|
||||
# buildifier: disable=function-docstring-header
|
||||
# buildifier: disable=function-docstring-args
|
||||
# buildifier: disable=function-docstring-return
|
||||
def call_shell(shell_context, method_, *args):
|
||||
"""Calls the 'method_' shell command from the toolchain.
|
||||
Checks the number and types of passed arguments.
|
||||
If the command returns the resulting text wrapped into FunctionAndCallInfo provider,
|
||||
puts the text of the function into the 'prelude' dictionary in the 'shell_context',
|
||||
and returns only the call of that function.
|
||||
"""
|
||||
check_argument_types(method_, args)
|
||||
|
||||
func_ = getattr(shell_context.shell, method_)
|
||||
result = func_(*args)
|
||||
|
||||
if type(result) == _function_and_call_type:
|
||||
# If needed, add function definition to the prelude part of the script
|
||||
if not shell_context.prelude.get(method_):
|
||||
define_function = getattr(shell_context.shell, "define_function")
|
||||
shell_context.prelude[method_] = define_function(method_, result.text)
|
||||
|
||||
# use provided method of calling a defined function or use default
|
||||
if hasattr(result, "call"):
|
||||
return result.call
|
||||
return " ".join([method_] + [_wrap_if_needed(str(arg)) for arg in args])
|
||||
|
||||
return result
|
||||
|
||||
def _quoted(arg):
|
||||
return arg.startswith("\"") and arg.endswith("\"")
|
||||
|
||||
def _wrap_if_needed(arg):
|
||||
if arg.find(" ") >= 0 and not _quoted(arg):
|
||||
return "\"" + arg + "\""
|
||||
return arg
|
||||
|
||||
# buildifier: disable=function-docstring
|
||||
def check_argument_types(method_, args_list):
|
||||
descriptor = PLATFORM_COMMANDS[method_]
|
||||
args_info = descriptor.arguments
|
||||
|
||||
if len(args_list) != len(args_info):
|
||||
fail("Wrong number ({}) of arguments ({}) in a call to '{}'".format(
|
||||
len(args_list),
|
||||
str(args_list),
|
||||
method_,
|
||||
))
|
||||
|
||||
for idx in range(0, len(args_list)):
|
||||
if type(args_list[idx]) != args_info[idx].type_:
|
||||
fail("Wrong argument '{}' type: '{}'".format(args_info[idx].name, type(args_list[idx])))
|
|
@ -1,194 +0,0 @@
|
|||
# buildifier: disable=module-docstring
|
||||
CommandInfo = provider(
|
||||
doc = "To pass information about the Starlark function, defining the shell fragment.",
|
||||
fields = {
|
||||
"arguments": "Arguments of Starlark function",
|
||||
"doc": "What the shell script fragment, generated by this function, does.",
|
||||
},
|
||||
)
|
||||
|
||||
ArgumentInfo = provider(
|
||||
doc = "",
|
||||
fields = {
|
||||
"doc": "",
|
||||
"name": "",
|
||||
"type_": "",
|
||||
},
|
||||
)
|
||||
|
||||
PLATFORM_COMMANDS = {
|
||||
"assert_script_errors": CommandInfo(
|
||||
arguments = [],
|
||||
doc = "Script fragment that stops the execution after any error",
|
||||
),
|
||||
"cat": CommandInfo(
|
||||
arguments = [
|
||||
ArgumentInfo(name = "filepath", type_ = type(""), doc = "Path to the file"),
|
||||
],
|
||||
doc = "Output the file contents to stdout",
|
||||
),
|
||||
"children_to_path": CommandInfo(
|
||||
arguments = [
|
||||
ArgumentInfo(name = "dir_", type_ = type(""), doc = "Directory"),
|
||||
],
|
||||
doc = "Put all immediate subdirectories (and symlinks) into PATH",
|
||||
),
|
||||
"cleanup_function": CommandInfo(
|
||||
arguments = [
|
||||
ArgumentInfo(name = "on_success", type_ = type(""), doc = "Command(s) to be executed on success"),
|
||||
ArgumentInfo(name = "on_failure", type_ = type(""), doc = "Command(s) to be executed on failure"),
|
||||
],
|
||||
doc = "Trap function called after the script is finished",
|
||||
# doc = "Read the result of the execution of the previous command, execute success or failure callbacks",
|
||||
),
|
||||
"copy_dir_contents_to_dir": CommandInfo(
|
||||
arguments = [
|
||||
ArgumentInfo(
|
||||
name = "source",
|
||||
type_ = type(""),
|
||||
doc = "Source directory, immediate children of which are copied",
|
||||
),
|
||||
ArgumentInfo(name = "target", type_ = type(""), doc = "Target directory"),
|
||||
],
|
||||
doc = "Copies contents of the directory to target directory",
|
||||
),
|
||||
"define_absolute_paths": CommandInfo(
|
||||
arguments = [
|
||||
ArgumentInfo(name = "dir_", type_ = type(""), doc = "Directory where to replace"),
|
||||
ArgumentInfo(name = "abs_path", type_ = type(""), doc = "Absolute path value"),
|
||||
],
|
||||
doc = "Replaces absolute path placeholder inside 'dir_' with a provided value 'abs_path'",
|
||||
),
|
||||
"define_function": CommandInfo(
|
||||
arguments = [
|
||||
ArgumentInfo(name = "name", type_ = type(""), doc = "Function name"),
|
||||
ArgumentInfo(name = "text", type_ = type(""), doc = "Function body"),
|
||||
],
|
||||
doc = "Defines a function with 'text' as the function body.",
|
||||
),
|
||||
"echo": CommandInfo(
|
||||
arguments = [ArgumentInfo(name = "text", type_ = type(""), doc = "Text to output")],
|
||||
doc = "Outputs 'text' to stdout",
|
||||
),
|
||||
"env": CommandInfo(
|
||||
arguments = [],
|
||||
doc = "Print all environment variables",
|
||||
),
|
||||
"export_var": CommandInfo(
|
||||
arguments = [
|
||||
ArgumentInfo(name = "name", type_ = type(""), doc = "Variable name"),
|
||||
ArgumentInfo(name = "value", type_ = type(""), doc = "Variable value"),
|
||||
],
|
||||
doc = "Defines and exports environment variable.",
|
||||
),
|
||||
"if_else": CommandInfo(
|
||||
doc = "Creates if-else construct",
|
||||
arguments = [
|
||||
ArgumentInfo(name = "condition", type_ = type(""), doc = "Condition text"),
|
||||
ArgumentInfo(name = "if_text", type_ = type(""), doc = "If block text"),
|
||||
ArgumentInfo(name = "else_text", type_ = type(""), doc = "Else block text"),
|
||||
],
|
||||
),
|
||||
"increment_pkg_config_path": CommandInfo(
|
||||
arguments = [
|
||||
ArgumentInfo(
|
||||
name = "source",
|
||||
type_ = type(""),
|
||||
doc = "Source directory",
|
||||
),
|
||||
],
|
||||
doc = (
|
||||
"Find subdirectory inside a passed directory with *.pc files and add it " +
|
||||
"to the PKG_CONFIG_PATH"
|
||||
),
|
||||
),
|
||||
"local_var": CommandInfo(
|
||||
arguments = [
|
||||
ArgumentInfo(name = "name", type_ = type(""), doc = "Variable name"),
|
||||
ArgumentInfo(name = "value", type_ = type(""), doc = "Variable value"),
|
||||
],
|
||||
doc = "Defines local shell variable.",
|
||||
),
|
||||
"mkdirs": CommandInfo(
|
||||
arguments = [ArgumentInfo(name = "path", type_ = type(""), doc = "Path to directory")],
|
||||
doc = "Creates a directory and, if neccesary, it's parents",
|
||||
),
|
||||
"os_name": CommandInfo(
|
||||
arguments = [],
|
||||
doc = "Returns OS name",
|
||||
),
|
||||
"path": CommandInfo(
|
||||
arguments = [
|
||||
ArgumentInfo(name = "expression", type_ = type(""), doc = "Path"),
|
||||
],
|
||||
doc = "Adds passed arguments in the beginning of the PATH.",
|
||||
),
|
||||
"pwd": CommandInfo(
|
||||
arguments = [],
|
||||
doc = "Returns command for getting current directory.",
|
||||
),
|
||||
"redirect_out_err": CommandInfo(
|
||||
arguments = [
|
||||
ArgumentInfo(name = "from_process", type_ = type(""), doc = "Process to run"),
|
||||
ArgumentInfo(name = "to_file", type_ = type(""), doc = "File to redirect output to"),
|
||||
],
|
||||
doc = "Read the result of the execution of the previous command, execute success or failure callbacks",
|
||||
),
|
||||
"replace_absolute_paths": CommandInfo(
|
||||
arguments = [
|
||||
ArgumentInfo(name = "dir_", type_ = type(""), doc = "Directory where to replace"),
|
||||
ArgumentInfo(name = "abs_path", type_ = type(""), doc = "Absolute path value"),
|
||||
],
|
||||
doc = "Replaces absolute path 'abs_path' inside 'dir_' with a placeholder value",
|
||||
),
|
||||
"replace_in_files": CommandInfo(
|
||||
arguments = [
|
||||
ArgumentInfo(name = "dir_", type_ = type(""), doc = "Directory to search recursively"),
|
||||
ArgumentInfo(name = "from_", type_ = type(""), doc = "String to be replaced"),
|
||||
ArgumentInfo(name = "to_", type_ = type(""), doc = "Replace target"),
|
||||
],
|
||||
doc = "Replaces all occurrences of 'from_' to 'to_' recursively in the directory 'dir'.",
|
||||
),
|
||||
"script_prelude": CommandInfo(
|
||||
arguments = [],
|
||||
doc = "Function for setting necessary environment variables for the platform",
|
||||
),
|
||||
"symlink_contents_to_dir": CommandInfo(
|
||||
arguments = [
|
||||
ArgumentInfo(
|
||||
name = "source",
|
||||
type_ = type(""),
|
||||
doc = "Source directory, immediate children of which are symlinked, or file to be symlinked.",
|
||||
),
|
||||
ArgumentInfo(name = "target", type_ = type(""), doc = "Target directory"),
|
||||
],
|
||||
doc = (
|
||||
"Symlink contents of the directory to target directory (create the target directory if needed). " +
|
||||
"If file is passed, symlink it into the target directory."
|
||||
),
|
||||
),
|
||||
"symlink_to_dir": CommandInfo(
|
||||
arguments = [
|
||||
ArgumentInfo(
|
||||
name = "source",
|
||||
type_ = type(""),
|
||||
doc = "Source directory",
|
||||
),
|
||||
ArgumentInfo(name = "target", type_ = type(""), doc = "Target directory"),
|
||||
],
|
||||
doc = (
|
||||
"Symlink all files from source directory to target directory (create the target directory if needed). " +
|
||||
"NB symlinks from the source directory are copied."
|
||||
),
|
||||
),
|
||||
"touch": CommandInfo(
|
||||
arguments = [ArgumentInfo(name = "path", type_ = type(""), doc = "Path to file")],
|
||||
doc = "Creates a file",
|
||||
),
|
||||
"use_var": CommandInfo(
|
||||
arguments = [
|
||||
ArgumentInfo(name = "name", type_ = type(""), doc = "Variable name"),
|
||||
],
|
||||
doc = "Expression to address the variable.",
|
||||
),
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
# buildifier: disable=module-docstring
|
||||
load("@rules_foreign_cc_commands_overloads//:toolchain_data_defs.bzl", "get")
|
||||
load(
|
||||
"//foreign_cc/private/shell_toolchain/polymorphism:generate_overloads.bzl",
|
||||
"get_file_name",
|
||||
)
|
||||
load(":toolchain_mappings.bzl", "TOOLCHAIN_MAPPINGS")
|
||||
|
||||
def _toolchain_data(ctx):
|
||||
return platform_common.ToolchainInfo(data = get(ctx.attr.file_name))
|
||||
|
||||
toolchain_data = rule(
|
||||
implementation = _toolchain_data,
|
||||
attrs = {
|
||||
"file_name": attr.string(),
|
||||
},
|
||||
)
|
||||
|
||||
# buildifier: disable=unnamed-macro
|
||||
def build_part(toolchain_type):
|
||||
register_mappings(toolchain_type, TOOLCHAIN_MAPPINGS)
|
||||
|
||||
# buildifier: disable=unnamed-macro
|
||||
def register_mappings(toolchain_type, mappings):
|
||||
for item in mappings:
|
||||
file_name = get_file_name(item.file)
|
||||
|
||||
toolchain_data(
|
||||
name = file_name + "_data",
|
||||
file_name = file_name,
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
native.toolchain(
|
||||
name = file_name,
|
||||
toolchain_type = toolchain_type,
|
||||
toolchain = file_name + "_data",
|
||||
exec_compatible_with = item.exec_compatible_with if hasattr(item, "exec_compatible_with") else [],
|
||||
target_compatible_with = item.target_compatible_with if hasattr(item, "target_compatible_with") else [],
|
||||
)
|
|
@ -1,8 +0,0 @@
|
|||
# buildifier: disable=module-docstring
|
||||
FunctionAndCallInfo = provider(
|
||||
doc = "Wrapper to pass function definition and (if custom) function call",
|
||||
fields = {
|
||||
"call": "How to call defined function, if different from <function-name> <arg1> ...<argn>",
|
||||
"text": "Function body, without wrapping function <name>() {} fragment.",
|
||||
},
|
||||
)
|
|
@ -1,175 +0,0 @@
|
|||
# buildifier: disable=module-docstring
|
||||
load("@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains:function_and_call.bzl", "FunctionAndCallInfo")
|
||||
|
||||
_REPLACE_VALUE = "\\${EXT_BUILD_DEPS}"
|
||||
|
||||
def os_name():
|
||||
return "linux"
|
||||
|
||||
def pwd():
|
||||
return "$(pwd)"
|
||||
|
||||
def echo(text):
|
||||
return "echo \"{text}\"".format(text = text)
|
||||
|
||||
def export_var(name, value):
|
||||
return "export {name}={value}".format(name = name, value = value)
|
||||
|
||||
def local_var(name, value):
|
||||
return "local {name}={value}".format(name = name, value = value)
|
||||
|
||||
def use_var(name):
|
||||
return "$" + name
|
||||
|
||||
def env():
|
||||
return "env"
|
||||
|
||||
def path(expression):
|
||||
return "export PATH=\"{expression}:$PATH\"".format(expression = expression)
|
||||
|
||||
def touch(path):
|
||||
return "touch " + path
|
||||
|
||||
def mkdirs(path):
|
||||
return "mkdir -p " + path
|
||||
|
||||
def if_else(condition, if_text, else_text):
|
||||
return """\
|
||||
if [ {condition} ]; then
|
||||
{if_text}
|
||||
else
|
||||
{else_text}
|
||||
fi
|
||||
""".format(condition = condition, if_text = if_text, else_text = else_text)
|
||||
|
||||
# buildifier: disable=function-docstring
|
||||
def define_function(name, text):
|
||||
lines = []
|
||||
lines.append("function " + name + "() {")
|
||||
for line_ in text.splitlines():
|
||||
lines.append(" " + line_)
|
||||
lines.append("}")
|
||||
return "\n".join(lines)
|
||||
|
||||
def replace_in_files(dir, from_, to_):
|
||||
return FunctionAndCallInfo(
|
||||
text = """\
|
||||
if [ -d "$1" ]; then
|
||||
find -L $1 -type f \\( -name "*.pc" -or -name "*.la" -or -name "*-config" -or -name "*.cmake" \\) -exec sed -i 's@'"$2"'@'"$3"'@g' {} ';'
|
||||
fi
|
||||
""",
|
||||
)
|
||||
|
||||
def copy_dir_contents_to_dir(source, target):
|
||||
return """cp -L -r --no-target-directory "{source}" "{target}" && find {target} -type f -exec touch -r "{source}" "{{}}" \\;""".format(
|
||||
source = source,
|
||||
target = target,
|
||||
)
|
||||
|
||||
def symlink_contents_to_dir(source, target):
|
||||
text = """\
|
||||
local target="$2"
|
||||
mkdir -p "$target"
|
||||
if [[ -f "$1" ]]; then
|
||||
##symlink_to_dir## "$1" "$target"
|
||||
elif [[ -L "$1" ]]; then
|
||||
local actual=$(readlink "$1")
|
||||
##symlink_contents_to_dir## "$actual" "$target"
|
||||
elif [[ -d "$1" ]]; then
|
||||
SAVEIFS=$IFS
|
||||
IFS=$'\n'
|
||||
local children=($(find -H "$1" -maxdepth 1 -mindepth 1))
|
||||
IFS=$SAVEIFS
|
||||
for child in "${children[@]:-}"; do
|
||||
##symlink_to_dir## "$child" "$target"
|
||||
done
|
||||
fi
|
||||
"""
|
||||
return FunctionAndCallInfo(text = text)
|
||||
|
||||
def symlink_to_dir(source, target):
|
||||
text = """\
|
||||
local target="$2"
|
||||
mkdir -p "$target"
|
||||
if [[ -f "$1" ]]; then
|
||||
ln -s -f -t "$target" "$1"
|
||||
elif [[ -L "$1" ]]; then
|
||||
local actual=$(readlink "$1")
|
||||
##symlink_to_dir## "$actual" "$target"
|
||||
elif [[ -d "$1" ]]; then
|
||||
SAVEIFS=$IFS
|
||||
IFS=$'\n'
|
||||
local children=($(find -H "$1" -maxdepth 1 -mindepth 1))
|
||||
IFS=$SAVEIFS
|
||||
local dirname=$(basename "$1")
|
||||
for child in "${children[@]:-}"; do
|
||||
if [[ "$dirname" != *.ext_build_deps ]]; then
|
||||
##symlink_to_dir## "$child" "$target/$dirname"
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "Can not copy $1"
|
||||
fi
|
||||
"""
|
||||
return FunctionAndCallInfo(text = text)
|
||||
|
||||
def script_prelude():
|
||||
return "set -euo pipefail"
|
||||
|
||||
def increment_pkg_config_path(source):
|
||||
text = """\
|
||||
local children=$(find $1 -mindepth 1 -name '*.pc')
|
||||
# assume there is only one directory with pkg config
|
||||
for child in $children; do
|
||||
export PKG_CONFIG_PATH="$${PKG_CONFIG_PATH:-}$$:$(dirname $child)"
|
||||
return
|
||||
done
|
||||
"""
|
||||
return FunctionAndCallInfo(text = text)
|
||||
|
||||
def cat(filepath):
|
||||
return "cat \"{}\"".format(filepath)
|
||||
|
||||
def redirect_out_err(from_process, to_file):
|
||||
return from_process + " &> " + to_file
|
||||
|
||||
def assert_script_errors():
|
||||
return "set -e"
|
||||
|
||||
def cleanup_function(on_success, on_failure):
|
||||
text = "\n".join([
|
||||
"local ecode=$?",
|
||||
"if [ $ecode -eq 0 ]; then",
|
||||
on_success,
|
||||
"else",
|
||||
on_failure,
|
||||
"fi",
|
||||
])
|
||||
return FunctionAndCallInfo(text = text, call = "trap \"cleanup_function\" EXIT")
|
||||
|
||||
def children_to_path(dir_):
|
||||
text = """\
|
||||
if [ -d {dir_} ]; then
|
||||
local tools=$(find $EXT_BUILD_DEPS/bin -maxdepth 1 -mindepth 1)
|
||||
for tool in $tools;
|
||||
do
|
||||
if [[ -d \"$tool\" ]] || [[ -L \"$tool\" ]]; then
|
||||
export PATH=$PATH:$tool
|
||||
fi
|
||||
done
|
||||
fi""".format(dir_ = dir_)
|
||||
return FunctionAndCallInfo(text = text)
|
||||
|
||||
def define_absolute_paths(dir_, abs_path):
|
||||
return "##replace_in_files## {dir_} {REPLACE_VALUE} {abs_path}".format(
|
||||
dir_ = dir_,
|
||||
REPLACE_VALUE = _REPLACE_VALUE,
|
||||
abs_path = abs_path,
|
||||
)
|
||||
|
||||
def replace_absolute_paths(dir_, abs_path):
|
||||
return "##replace_in_files## {dir_} {abs_path} {REPLACE_VALUE}".format(
|
||||
dir_ = dir_,
|
||||
REPLACE_VALUE = _REPLACE_VALUE,
|
||||
abs_path = abs_path,
|
||||
)
|
|
@ -1,34 +0,0 @@
|
|||
# buildifier: disable=module-docstring
|
||||
# buildifier: disable=name-conventions
|
||||
ToolchainMapping = provider(
|
||||
doc = "Mapping of toolchain definition files to platform constraints",
|
||||
fields = {
|
||||
"exec_compatible_with": "Compatible execution platform constraints",
|
||||
"file": "Toolchain definition file",
|
||||
"target_compatible_with": "Compatible target platform constraints",
|
||||
},
|
||||
)
|
||||
|
||||
TOOLCHAIN_MAPPINGS = [
|
||||
ToolchainMapping(
|
||||
exec_compatible_with = [
|
||||
"@platforms//os:linux",
|
||||
],
|
||||
file = "@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains/impl:linux_commands.bzl",
|
||||
),
|
||||
ToolchainMapping(
|
||||
exec_compatible_with = [
|
||||
"@platforms//os:windows",
|
||||
],
|
||||
file = "@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains/impl:windows_commands.bzl",
|
||||
),
|
||||
ToolchainMapping(
|
||||
exec_compatible_with = [
|
||||
"@platforms//os:macos",
|
||||
],
|
||||
file = "@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains/impl:macos_commands.bzl",
|
||||
),
|
||||
ToolchainMapping(
|
||||
file = "@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains/impl:default_commands.bzl",
|
||||
),
|
||||
]
|
|
@ -1,31 +0,0 @@
|
|||
# buildifier: disable=module-docstring
|
||||
load(
|
||||
"//foreign_cc/private/shell_toolchain/polymorphism:generate_overloads.bzl",
|
||||
"generate_overloads",
|
||||
"get_file_name",
|
||||
)
|
||||
load("//foreign_cc/private/shell_toolchain/toolchains:commands.bzl", "PLATFORM_COMMANDS")
|
||||
load(":toolchain_mappings.bzl", "TOOLCHAIN_MAPPINGS")
|
||||
|
||||
# buildifier: disable=unnamed-macro
|
||||
# buildifier: disable=function-docstring
|
||||
def workspace_part(
|
||||
additional_toolchain_mappings = [],
|
||||
additonal_shell_toolchain_package = None):
|
||||
mappings = additional_toolchain_mappings + TOOLCHAIN_MAPPINGS
|
||||
generate_overloads(
|
||||
name = "rules_foreign_cc_commands_overloads",
|
||||
files = [item.file for item in mappings],
|
||||
symbols = PLATFORM_COMMANDS.keys(),
|
||||
)
|
||||
ordered_toolchains = []
|
||||
for item in additional_toolchain_mappings:
|
||||
if not additonal_shell_toolchain_package:
|
||||
fail("Please specify the package, where the toolchains will be created")
|
||||
if not additonal_shell_toolchain_package.endswith(":"):
|
||||
additonal_shell_toolchain_package = additonal_shell_toolchain_package + ":"
|
||||
ordered_toolchains.append(additonal_shell_toolchain_package + get_file_name(item.file))
|
||||
prefix = "@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains:"
|
||||
for item in TOOLCHAIN_MAPPINGS:
|
||||
ordered_toolchains.append(prefix + get_file_name(item.file))
|
||||
native.register_toolchains(*ordered_toolchains)
|
|
@ -2,10 +2,7 @@
|
|||
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
|
||||
load(
|
||||
"//foreign_cc/private/shell_toolchain/toolchains:ws_defs.bzl",
|
||||
shell_toolchain_workspace_initalization = "workspace_part",
|
||||
)
|
||||
load("//foreign_cc/private/framework:toolchain.bzl", "register_framework_toolchains")
|
||||
load("//toolchains:toolchains.bzl", "built_toolchains", "prebuilt_toolchains", "preinstalled_toolchains")
|
||||
|
||||
# buildifier: disable=unnamed-macro
|
||||
|
@ -16,9 +13,7 @@ def rules_foreign_cc_dependencies(
|
|||
make_version = "4.3",
|
||||
ninja_version = "1.10.2",
|
||||
register_preinstalled_tools = True,
|
||||
register_built_tools = True,
|
||||
additional_shell_toolchain_mappings = [],
|
||||
additional_shell_toolchain_package = None):
|
||||
register_built_tools = True):
|
||||
"""Call this function from the WORKSPACE file to initialize rules_foreign_cc \
|
||||
dependencies and let neccesary code generation happen \
|
||||
(Code generation is needed to support different variants of the C++ Starlark API.).
|
||||
|
@ -46,22 +41,9 @@ def rules_foreign_cc_dependencies(
|
|||
installed on the exec host
|
||||
|
||||
register_built_tools: If true, toolchains that build the tools from source are registered
|
||||
|
||||
additional_shell_toolchain_mappings: Mappings of the shell toolchain functions to
|
||||
execution and target platforms constraints. Similar to what defined in
|
||||
@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains:toolchain_mappings.bzl
|
||||
in the TOOLCHAIN_MAPPINGS list. Please refer to example in @rules_foreign_cc//toolchain_examples.
|
||||
|
||||
additional_shell_toolchain_package: A package under which additional toolchains, referencing
|
||||
the generated data for the passed additonal_shell_toolchain_mappings, will be defined.
|
||||
This value is needed since register_toolchains() is called for these toolchains.
|
||||
Please refer to example in @rules_foreign_cc//toolchain_examples.
|
||||
"""
|
||||
|
||||
shell_toolchain_workspace_initalization(
|
||||
additional_shell_toolchain_mappings,
|
||||
additional_shell_toolchain_package,
|
||||
)
|
||||
register_framework_toolchains()
|
||||
|
||||
native.register_toolchains(*native_tools_toolchains)
|
||||
|
||||
|
|
|
@ -29,20 +29,13 @@ config_setting(
|
|||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
result_file = select({
|
||||
":macos": "expected/inner_fun_text_osx.txt",
|
||||
"//conditions:default": "expected/inner_fun_text.txt",
|
||||
})
|
||||
|
||||
result_file_symlink_dirs = select({
|
||||
":macos": "expected/out_symlinked_dirs_osx.txt",
|
||||
"//conditions:default": "expected/out_symlinked_dirs.txt",
|
||||
})
|
||||
|
||||
diff_test(
|
||||
name = "shell_script_inner_fun_test",
|
||||
file1 = ":shell_script_inner_fun",
|
||||
file2 = result_file,
|
||||
file2 = select({
|
||||
":macos": "expected/inner_fun_text_osx.txt",
|
||||
"//conditions:default": "expected/inner_fun_text.txt",
|
||||
}),
|
||||
)
|
||||
|
||||
filegroup(
|
||||
|
@ -64,6 +57,9 @@ symlink_contents_to_dir_test_rule(
|
|||
|
||||
diff_test(
|
||||
name = "shell_method_symlink_contents_to_dir_test",
|
||||
file1 = result_file_symlink_dirs,
|
||||
file1 = select({
|
||||
":macos": "expected/out_symlinked_dirs_osx.txt",
|
||||
"//conditions:default": "expected/out_symlinked_dirs.txt",
|
||||
}),
|
||||
file2 = ":symlink_dirs",
|
||||
)
|
||||
|
|
|
@ -4,7 +4,7 @@ load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest")
|
|||
|
||||
# buildifier: disable=bzl-visibility
|
||||
load(
|
||||
"//foreign_cc/private:shell_script_helper.bzl",
|
||||
"//foreign_cc/private/framework:helpers.bzl",
|
||||
"convert_shell_script_by_context",
|
||||
"do_function_call",
|
||||
"replace_var_ref",
|
||||
|
@ -12,7 +12,7 @@ load(
|
|||
)
|
||||
|
||||
# buildifier: disable=bzl-visibility
|
||||
load("//foreign_cc/private/shell_toolchain/toolchains:function_and_call.bzl", "FunctionAndCallInfo")
|
||||
load("//foreign_cc/private/framework/toolchains:commands.bzl", "FunctionAndCallInfo")
|
||||
|
||||
def _use_var_linux(varname):
|
||||
return "$" + varname
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# buildifier: disable=module-docstring
|
||||
# buildifier: disable=bzl-visibility
|
||||
load("//foreign_cc/private:shell_script_helper.bzl", "convert_shell_script")
|
||||
load("//foreign_cc/private/framework:helpers.bzl", "convert_shell_script")
|
||||
|
||||
def _impl(ctx):
|
||||
text = convert_shell_script(ctx, ctx.attr.script)
|
||||
|
@ -18,6 +18,6 @@ shell_script_helper_test_rule = rule(
|
|||
"script": attr.string_list(mandatory = True),
|
||||
},
|
||||
toolchains = [
|
||||
"@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains:shell_commands",
|
||||
"@rules_foreign_cc//foreign_cc/private/framework:shell_toolchain",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
load("@rules_foreign_cc//foreign_cc/private:detect_root.bzl", "detect_root", "filter_containing_dirs_from_inputs")
|
||||
|
||||
# buildifier: disable=bzl-visibility
|
||||
load("@rules_foreign_cc//foreign_cc/private:shell_script_helper.bzl", "convert_shell_script")
|
||||
load("@rules_foreign_cc//foreign_cc/private/framework:helpers.bzl", "convert_shell_script")
|
||||
|
||||
def _symlink_contents_to_dir_test_rule_impl(ctx):
|
||||
out = ctx.actions.declare_file(ctx.attr.out)
|
||||
|
@ -37,6 +37,6 @@ symlink_contents_to_dir_test_rule = rule(
|
|||
"out": attr.string(),
|
||||
},
|
||||
toolchains = [
|
||||
"@rules_foreign_cc//foreign_cc/private/shell_toolchain/toolchains:shell_commands",
|
||||
"@rules_foreign_cc//foreign_cc/private/framework:shell_toolchain",
|
||||
],
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue