2021-06-02 18:58:56 +00:00
|
|
|
"""A rule for building projects using the [GNU Make](https://www.gnu.org/software/make/) build tool"""
|
|
|
|
|
2021-03-12 16:54:14 +00:00
|
|
|
load(
|
|
|
|
"//foreign_cc/private:cc_toolchain_util.bzl",
|
|
|
|
"get_flags_info",
|
|
|
|
"get_tools_info",
|
|
|
|
)
|
|
|
|
load(
|
|
|
|
"//foreign_cc/private:detect_root.bzl",
|
|
|
|
"detect_root",
|
|
|
|
)
|
|
|
|
load(
|
|
|
|
"//foreign_cc/private:framework.bzl",
|
|
|
|
"CC_EXTERNAL_RULE_ATTRIBUTES",
|
|
|
|
"CC_EXTERNAL_RULE_FRAGMENTS",
|
|
|
|
"cc_external_rule_impl",
|
|
|
|
"create_attrs",
|
2021-07-19 19:44:21 +00:00
|
|
|
"expand_locations",
|
2021-03-12 16:54:14 +00:00
|
|
|
)
|
2021-03-15 16:00:46 +00:00
|
|
|
load("//foreign_cc/private:make_script.bzl", "create_make_script")
|
2021-07-28 14:30:04 +00:00
|
|
|
load("//foreign_cc/private:transitions.bzl", _make_variant = "make_variant")
|
2021-03-12 16:54:14 +00:00
|
|
|
load("//toolchains/native_tools:tool_access.bzl", "get_make_data")
|
|
|
|
|
|
|
|
def _make(ctx):
|
|
|
|
make_data = get_make_data(ctx)
|
|
|
|
|
|
|
|
tools_deps = ctx.attr.tools_deps + make_data.deps
|
|
|
|
|
|
|
|
attrs = create_attrs(
|
|
|
|
ctx.attr,
|
2021-07-29 13:13:26 +00:00
|
|
|
configure_name = "Make",
|
2021-03-12 16:54:14 +00:00
|
|
|
create_configure_script = _create_make_script,
|
|
|
|
tools_deps = tools_deps,
|
|
|
|
make_path = make_data.path,
|
|
|
|
)
|
|
|
|
return cc_external_rule_impl(ctx, attrs)
|
|
|
|
|
|
|
|
def _create_make_script(configureParameters):
|
|
|
|
ctx = configureParameters.ctx
|
2021-03-17 13:42:44 +00:00
|
|
|
attrs = configureParameters.attrs
|
2021-03-12 16:54:14 +00:00
|
|
|
inputs = configureParameters.inputs
|
|
|
|
|
|
|
|
root = detect_root(ctx.attr.lib_source)
|
|
|
|
|
|
|
|
tools = get_tools_info(ctx)
|
|
|
|
flags = get_flags_info(ctx)
|
|
|
|
|
2021-06-14 16:59:49 +00:00
|
|
|
data = ctx.attr.data + ctx.attr.build_data
|
2021-03-17 13:42:44 +00:00
|
|
|
|
|
|
|
# Generate a list of arguments for make
|
|
|
|
args = " ".join([
|
|
|
|
ctx.expand_location(arg, data)
|
|
|
|
for arg in ctx.attr.args
|
|
|
|
])
|
|
|
|
|
|
|
|
make_commands = []
|
2021-07-30 08:09:06 +00:00
|
|
|
prefix = "{} ".format(expand_locations(ctx, attrs.tool_prefix, data)) if attrs.tool_prefix else ""
|
2021-04-12 15:23:42 +00:00
|
|
|
for target in ctx.attr.targets:
|
2021-11-24 23:24:29 +00:00
|
|
|
make_commands.append("{prefix}{make} -C $$BUILD_TMPDIR$$ {target} {args} PREFIX={install_prefix}".format(
|
2021-06-14 16:59:49 +00:00
|
|
|
prefix = prefix,
|
2021-04-12 15:23:42 +00:00
|
|
|
make = attrs.make_path,
|
|
|
|
args = args,
|
|
|
|
target = target,
|
2021-08-03 13:11:07 +00:00
|
|
|
install_prefix = ctx.attr.install_prefix,
|
2021-04-12 15:23:42 +00:00
|
|
|
))
|
2021-03-12 16:54:14 +00:00
|
|
|
|
|
|
|
return create_make_script(
|
|
|
|
root = root,
|
|
|
|
inputs = inputs,
|
2021-03-17 13:42:44 +00:00
|
|
|
make_commands = make_commands,
|
2021-03-12 16:54:14 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
def _attrs():
|
|
|
|
attrs = dict(CC_EXTERNAL_RULE_ATTRIBUTES)
|
|
|
|
attrs.update({
|
2021-03-17 13:42:44 +00:00
|
|
|
"args": attr.string_list(
|
|
|
|
doc = "A list of arguments to pass to the call to `make`",
|
|
|
|
),
|
2021-08-03 13:11:07 +00:00
|
|
|
"install_prefix": attr.string(
|
|
|
|
doc = (
|
|
|
|
"Install prefix, i.e. relative path to where to install the result of the build. " +
|
|
|
|
"Passed as an arg to \"make\" as PREFIX=<install_prefix>."
|
|
|
|
),
|
|
|
|
mandatory = False,
|
|
|
|
default = "$$INSTALLDIR$$",
|
|
|
|
),
|
2021-03-17 13:42:44 +00:00
|
|
|
"targets": attr.string_list(
|
|
|
|
doc = (
|
|
|
|
"A list of targets within the foreign build system to produce. An empty string (`\"\"`) will result in " +
|
|
|
|
"a call to the underlying build system with no explicit target set"
|
2021-03-12 16:54:14 +00:00
|
|
|
),
|
|
|
|
mandatory = False,
|
2021-03-17 13:42:44 +00:00
|
|
|
default = ["", "install"],
|
2021-03-12 16:54:14 +00:00
|
|
|
),
|
|
|
|
})
|
|
|
|
return attrs
|
|
|
|
|
|
|
|
make = rule(
|
|
|
|
doc = (
|
|
|
|
"Rule for building external libraries with GNU Make. " +
|
2021-08-03 13:11:07 +00:00
|
|
|
"GNU Make commands (make and make install by default) are invoked with PREFIX=\"install\" " +
|
2021-03-12 16:54:14 +00:00
|
|
|
"(by default), and other environment variables for compilation and linking, taken from Bazel C/C++ " +
|
|
|
|
"toolchain and passed dependencies."
|
|
|
|
),
|
|
|
|
attrs = _attrs(),
|
|
|
|
fragments = CC_EXTERNAL_RULE_FRAGMENTS,
|
|
|
|
output_to_genfiles = True,
|
|
|
|
implementation = _make,
|
|
|
|
toolchains = [
|
|
|
|
"@rules_foreign_cc//toolchains:make_toolchain",
|
2021-04-30 16:03:32 +00:00
|
|
|
"@rules_foreign_cc//foreign_cc/private/framework:shell_toolchain",
|
2021-03-12 16:54:14 +00:00
|
|
|
"@bazel_tools//tools/cpp:toolchain_type",
|
|
|
|
],
|
2021-04-19 15:01:50 +00:00
|
|
|
# TODO: Remove once https://github.com/bazelbuild/bazel/issues/11584 is closed and the min supported
|
|
|
|
# version is updated to a release of Bazel containing the new default for this setting.
|
|
|
|
incompatible_use_toolchain_transition = True,
|
2021-03-12 16:54:14 +00:00
|
|
|
)
|
2021-07-28 14:30:04 +00:00
|
|
|
|
|
|
|
def make_variant(name, toolchain, **kwargs):
|
|
|
|
""" Wrapper macro around the make() rule to force usage of the given make variant toolchain.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
name: The target name
|
|
|
|
toolchain: The desired make variant toolchain to use, e.g. @rules_foreign_cc//toolchains:preinstalled_nmake_toolchain
|
|
|
|
**kwargs: Remaining keyword arguments
|
|
|
|
"""
|
|
|
|
_make_variant(
|
|
|
|
name = name,
|
|
|
|
rule = make,
|
|
|
|
toolchain = toolchain,
|
|
|
|
**kwargs
|
|
|
|
)
|