Skip to content

Commit 3205c86

Browse files
helly25skvadrik
authored andcommitted
Provide a min viable http://bazel.build integration.
This allows other projects that use bazel to utilize re2c as a tool. Limitations: . Input files (docs, lexer, parser) are not being re-generated. . No tests are executed. . Only the main binary is being build as nothing else is needed. A user will load the package using bazel's 'http_archive' in their WORKSPACE file. In their BUILD files they can then use: ``` load("@re2c//bazel:re2c.bzl", "re2c_gen") re2c_gen( name = "file_re2c", srcs = ["file.re2c"], outs = [ "file.cc", "file.h", ] ) cc_library( name = "file_cc", srcs = ["file.cc"], hdrs = ["file.h"], ) ``` The approach here is to automate as much as possible. In that way, all source and header files will be found automatically (using glob). Also, the provided bazel integration is kept to an absolute minimum. An alternative is to use a `rules_foreign_cc` based approach. But that would require much more bazel work and knowledge. Plus the result would end up being a non-hermetic build, thereby bypassing bazel's advantages. Further, using a rules_foreign_cc approach is much slower (for me ~x10).
1 parent 2dda36a commit 3205c86

File tree

6 files changed

+147
-0
lines changed

6 files changed

+147
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
/m4
1212
/test_*
1313
/.build*
14+
/bazel-*
1415

1516
# Ignore user defined CMake presets
1617
CMakeUserPresets.json

BUILD.bazel

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package(default_visibility = ["//visibility:private"])
2+
3+
genrule(
4+
name = "re2c_config",
5+
srcs = [
6+
"CMakeLists.txt",
7+
"//bazel:re2c_config.h",
8+
],
9+
outs = ["config.h"],
10+
cmd = """
11+
cat $(location //:CMakeLists.txt) |\\
12+
sed -rne 's/project\\(re2c VERSION ([^ ]+).*/#define PACKAGE_VERSION "\\1-bootstrap"/p' >> "$@"
13+
cat $(location //bazel:re2c_config.h) >> "$@"
14+
""",
15+
)
16+
17+
cc_library(
18+
name = "re2c_config_cc",
19+
hdrs = ["config.h"],
20+
defines = ["""RE2C_STDLIB_DIR='"$(BINDIR)/re2c.runfiles/re2c/include"'"""],
21+
data = ["include/unicode_categories.re"],
22+
)
23+
24+
cc_library(
25+
name = "re2c_bootstrap_cc",
26+
includes = ["bootstrap"],
27+
hdrs = glob([
28+
"bootstrap/src/**/*.h",
29+
"src/**/*.h",
30+
]),
31+
srcs = glob([
32+
"bootstrap/src/**/*.cc",
33+
"src/**/*.cc",
34+
]),
35+
deps = [
36+
"re2c_config_cc", # Needed for 're2c_config_cc' data files
37+
],
38+
)
39+
40+
cc_binary(
41+
name = "re2c",
42+
srcs = ["src/main.cc"],
43+
deps = [":re2c_bootstrap_cc"],
44+
visibility = ["//visibility:public"],
45+
)

WORKSPACE

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
workspace(name = "re2c")
2+
3+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
4+
5+
http_archive(
6+
name = "bazel_skylib",
7+
urls = [
8+
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz",
9+
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz",
10+
],
11+
sha256 = "74d544d96f4a5bb630d465ca8bbcfe231e3594e5aae57e1edbf17a6eb3ca2506",
12+
)
13+
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
14+
bazel_skylib_workspace()

bazel/BUILD.bazel

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package(default_visibility = ["//visibility:private"])
2+
3+
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
4+
5+
exports_files([
6+
"re2c_config.h",
7+
])
8+
9+
bzl_library(
10+
name = "re2c_bzl",
11+
srcs = ["re2c.bzl"],
12+
visibility = ["//visibility:public"],
13+
)

bazel/re2c.bzl

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# re2c generator rules - assuming that re2c is available as '@re2c//:re2c'.
2+
3+
load("@bazel_skylib//lib:paths.bzl", "paths")
4+
5+
visibility("public")
6+
7+
# Define supported extensions as defined by:
8+
# . https://bazel.build/reference/be/c-cpp#cc_library_args
9+
# . https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/cpp/CppFileTypes.java
10+
_C_SRC_EXT = [".c", ".cc", ".cpp", ".cxx", ".c++", ".C", ".cu", ".cl"]
11+
_C_HDR_EXT = [".h", ".hh", ".hpp", ".ipp", ".hxx", ".h++", ".inc", ".inl", ".tlh", ".tli", ".H", ".tcc"]
12+
_RE2C_EXT = [".re", ".re2c"]
13+
14+
def _re2c_impl(ctx):
15+
srcs = ctx.files.srcs
16+
if len(srcs) != 1:
17+
fail("Attribute `srcs` must contain exactly 1 re2c source file ({exts}).".format(exts=", ".join(_RE2C_EXT)))
18+
outs = ctx.outputs.outs
19+
if not outs or [o for o in outs if paths.split_extension(o.path)[1] not in _C_SRC_EXT + _C_HDR_EXT]:
20+
fail("Attribute `outs` must contain at least 1 C/C++ shource or header file ({exts}).".format(exts=", ".join(_C_SRC_EXT + _C_HDR_EXT)))
21+
ctx.actions.run_shell(
22+
outputs = outs + [err_file],
23+
tools = [ctx.executable._re2c_tool],
24+
inputs = ctx.files.srcs + ctx.files.data,
25+
command = """
26+
"{re2c}" "{src}" -o "{out}" {re2c_args} {includes}
27+
""".format(
28+
re2c = ctx.executable._re2c_tool.path,
29+
src = srcs[0].path,
30+
out = outs[0].path,
31+
includes = " ".join(list(dict([("-I" + f.dirname, 1) for f in ctx.files.data]))),
32+
re2c_args = " ".join(ctx.attr.re2c_args),
33+
),
34+
mnemonic = "RE2C",
35+
progress_message = "Generating re2c %{label}",
36+
)
37+
38+
_re2c_attr = {
39+
"srcs": attr.label_list(
40+
doc = "The re2c source.",
41+
allow_files = _RE2C_EXT,
42+
mandatory = True,
43+
),
44+
"data": attr.label_list(
45+
doc = "Other input data files (e.g. include files).",
46+
allow_files = _C_SRC_EXT + _C_HDR_EXT,
47+
mandatory = False,
48+
),
49+
"outs": attr.output_list(
50+
doc = "The generated output source.",
51+
mandatory = True,
52+
),
53+
"re2c_args": attr.string_list(
54+
doc = "Arguments to re2c invocation.",
55+
),
56+
"_re2c_tool": attr.label(
57+
doc = "The target of the 're2c' executable.",
58+
default = Label("//:re2c"),
59+
allow_single_file = True,
60+
executable = True,
61+
cfg = "exec",
62+
),
63+
}
64+
65+
re2c_gen = rule(
66+
attrs = _re2c_attr,
67+
doc = """Use re2c tool to create an output file (e.g. '.cc') from a '.re' input.""",
68+
output_to_genfiles = True,
69+
implementation = _re2c_impl,
70+
)

bazel/re2c_config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#define HAVE_SYS_TYPES_H 1
2+
#define HAVE_SYS_STAT_H 1
3+
#define HAVE_FCNTL_H 1
4+
#define HAVE_UNISTD_H 1

0 commit comments

Comments
 (0)