1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
# Forked from header_template_rule. header_template_rule is not
# compatible with our usage of select because its substitutions
# attribute is a dict, and dicts may not be appended with select. We
# get around this limitation by using a list as our substitutions.
def _cmake_configure_file_impl(ctx):
command = ["cat $1"]
for definition in ctx.attr.definitions:
command.append(
"| sed 's@#cmakedefine {}@#define {}@'".format(
definition,
definition,
),
)
# Replace any that remain with /* #undef FOO */.
command.append("| sed -r 's@#cmakedefine ([A-Z0-9_]+)@/* #undef \\1 */@'")
command.append("> $2")
ctx.actions.run_shell(
inputs = [ctx.file.src],
outputs = [ctx.outputs.out],
command = " ".join(command),
arguments = [
ctx.file.src.path,
ctx.outputs.out.path,
],
)
return [
# create a provider which says that this
# out file should be made available as a header
CcInfo(compilation_context = cc_common.create_compilation_context(
# pass out the include path for finding this header
includes = depset([ctx.outputs.out.dirname, ctx.bin_dir.path]),
# and the actual header here.
headers = depset([ctx.outputs.out]),
)),
]
cmake_configure_file = rule(
implementation = _cmake_configure_file_impl,
doc = """
Mimics CMake's configure_file in Bazel.
Args:
name: A unique name for this rule.
src: The input file template.
out: The generated output.
definitions: A mapping of identifier in template to its value.
""",
attrs = {
# We use attr.string_list for compatibility with select and
# config_setting. See the comment above _cmake_configure_file_impl
# for more information.
"definitions": attr.string_list(mandatory = True),
"out": attr.output(mandatory = True),
"src": attr.label(
mandatory = True,
allow_single_file = True,
),
},
# output_to_genfiles is required for header files.
output_to_genfiles = True,
)
|