Remove msys dependency for Windows.

Bazel genrules require a msys shell to execute
shell commands. Replace the genrules with a
simple C++ regex replacement binary.

Fixes #303.
This commit is contained in:
Tom Lundell 2020-06-12 22:10:46 -04:00 committed by Andreas Schuh
parent ef8e134d48
commit 1137acc9e0
4 changed files with 131 additions and 26 deletions

View file

@ -0,0 +1,5 @@
cc_binary(
name = "expand_template",
srcs = ["expand_template.cc"],
visibility = ["//visibility:public"],
)

View file

@ -0,0 +1,62 @@
#include <fstream>
#include <regex>
#include <streambuf>
#include <string>
#include <vector>
struct Substitution {
std::basic_regex<char> regex;
std::string replacement;
};
// Simple app that does a regex search-and-replace on a template
// and outputs the result.
//
// To invoke:
// expand_template
// --template PATH
// --output PATH
// regex0;replacement0
// regex1;replacement1
// ...
//
// Since it's only used as a private implementation detail of a rule and not
// user invoked we don't bother with error checking.
int main(int argc, const char** argv) {
// Parse args.
const char* template_path = nullptr;
const char* output_path = nullptr;
std::vector<Substitution> substitutions;
for (int i = 1; i < argc; ++i) {
const char* arg = argv[i];
if (strcmp(arg, "--template") == 0) {
template_path = argv[++i];
} else if (strcmp(arg, "--output") == 0) {
output_path = argv[++i];
} else {
const char* mid = strchr(arg, ';');
if (mid != nullptr) {
substitutions.push_back(Substitution{
std::basic_regex<char>(arg, mid - arg),
std::string(mid + 1),
});
}
}
}
// Read template.
std::ifstream ifs(template_path);
std::string str(std::istreambuf_iterator<char>(ifs),
(std::istreambuf_iterator<char>()));
// Apply regexes.
for (const auto& subst : substitutions) {
str = std::regex_replace(str, subst.regex, subst.replacement);
}
// Output file.
std::ofstream file(output_path);
file << str;
return 0;
}

View file

@ -0,0 +1,35 @@
def _impl(ctx):
args = ctx.actions.args()
args.add("--template", ctx.file.template)
args.add("--output", ctx.outputs.out)
args.add_all([k + ';' + v for k, v in ctx.attr.substitutions.items()])
ctx.actions.run(
executable = ctx.executable._bin,
arguments = [args],
inputs = [ctx.file.template],
outputs = [ctx.outputs.out],
)
return [
DefaultInfo(
files = depset(direct = [ctx.outputs.out]),
runfiles = ctx.runfiles(files = [ctx.outputs.out]),
),
]
expanded_template = rule(
implementation = _impl,
attrs = {
"out": attr.output(mandatory = True),
"template": attr.label(
allow_single_file = True,
mandatory = True,
),
"substitutions": attr.string_dict(),
"_bin": attr.label(
default = "//bazel/expanded_template:expand_template",
executable = True,
allow_single_file = True,
cfg = "host",
),
},
)

View file

@ -1,43 +1,46 @@
load("//bazel/expanded_template:expanded_template.bzl", "expanded_template")
# ------------------------------------------------------------------------------
# Add native rules to configure source files
def gflags_sources(namespace=["google", "gflags"]):
native.genrule(
expanded_template(
name = "gflags_declare_h",
srcs = ["src/gflags_declare.h.in"],
outs = ["gflags_declare.h"],
cmd = ("awk '{ " +
"gsub(/@GFLAGS_NAMESPACE@/, \"" + namespace[0] + "\"); " +
"gsub(/@(HAVE_STDINT_H|HAVE_SYS_TYPES_H|HAVE_INTTYPES_H|GFLAGS_INTTYPES_FORMAT_C99)@/, \"1\"); " +
"gsub(/@([A-Z0-9_]+)@/, \"0\"); " +
"print; }' $(<) > $(@)")
template = "src/gflags_declare.h.in",
out = "gflags_declare.h",
substitutions = {
"@GFLAGS_NAMESPACE@": namespace[0],
"@(HAVE_STDINT_H|HAVE_SYS_TYPES_H|HAVE_INTTYPES_H|GFLAGS_INTTYPES_FORMAT_C99)@": "1",
"@([A-Z0-9_]+)@": "0",
},
)
gflags_ns_h_files = []
for ns in namespace[1:]:
gflags_ns_h_file = "gflags_{}.h".format(ns)
native.genrule(
expanded_template(
name = gflags_ns_h_file.replace('.', '_'),
srcs = ["src/gflags_ns.h.in"],
outs = [gflags_ns_h_file],
cmd = ("awk '{ " +
"gsub(/@ns@/, \"" + ns + "\"); " +
"gsub(/@NS@/, \"" + ns.upper() + "\"); " +
"print; }' $(<) > $(@)")
template = "src/gflags_ns.h.in",
out = gflags_ns_h_file,
substitutions = {
"@ns@": ns,
"@NS@": ns.upper(),
}
)
gflags_ns_h_files.append(gflags_ns_h_file)
native.genrule(
expanded_template(
name = "gflags_h",
srcs = ["src/gflags.h.in"],
outs = ["gflags.h"],
cmd = ("awk '{ " +
"gsub(/@GFLAGS_ATTRIBUTE_UNUSED@/, \"\"); " +
"gsub(/@INCLUDE_GFLAGS_NS_H@/, \"" + '\n'.join(["#include \\\"gflags/{}\\\"".format(hdr) for hdr in gflags_ns_h_files]) + "\"); " +
"print; }' $(<) > $(@)")
template = "src/gflags.h.in",
out = "gflags.h",
substitutions = {
"@GFLAGS_ATTRIBUTE_UNUSED@": "",
"@INCLUDE_GFLAGS_NS_H@": '\n'.join(["#include \"gflags/{}\"".format(hdr) for hdr in gflags_ns_h_files]),
},
)
native.genrule(
expanded_template(
name = "gflags_completions_h",
srcs = ["src/gflags_completions.h.in"],
outs = ["gflags_completions.h"],
cmd = "awk '{ gsub(/@GFLAGS_NAMESPACE@/, \"" + namespace[0] + "\"); print; }' $(<) > $(@)"
template = "src/gflags_completions.h.in",
out = "gflags_completions.h",
substitutions = {
"@GFLAGS_NAMESPACE@": namespace[0],
},
)
hdrs = [":gflags_h", ":gflags_declare_h", ":gflags_completions_h"]
hdrs.extend([':' + hdr.replace('.', '_') for hdr in gflags_ns_h_files])