Skip to content

Commit

Permalink
feat(build): allow in-tree lex/yacc toolchains (#4880)
Browse files Browse the repository at this point in the history
  • Loading branch information
shahms committed Apr 6, 2021
1 parent c9a80e0 commit ad8f098
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 11 deletions.
4 changes: 2 additions & 2 deletions tools/build_rules/lexyacc/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ lexyacc_variables(name = "current_lexyacc_toolchain")

lexyacc_toolchain(
name = "lexyacc_remote",
lex = "/usr/bin/flex",
yacc = "/usr/bin/bison",
lex_path = "/usr/bin/flex",
yacc_path = "/usr/bin/bison",
)

bzl_library(
Expand Down
43 changes: 34 additions & 9 deletions tools/build_rules/lexyacc/lexyacc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def genlex(name, src, out, includes = []):
srcs = [src] + includes,
cmd = cmd,
toolchains = ["@io_kythe//tools/build_rules/lexyacc:current_lexyacc_toolchain"],
exec_tools = ["@io_kythe//tools/build_rules/lexyacc:current_lexyacc_toolchain"],
)

def genyacc(name, src, header_out, source_out, extra_outs = []):
Expand All @@ -35,16 +36,18 @@ def genyacc(name, src, header_out, source_out, extra_outs = []):
srcs = [src],
cmd = cmd,
toolchains = ["@io_kythe//tools/build_rules/lexyacc:current_lexyacc_toolchain"],
exec_tools = ["@io_kythe//tools/build_rules/lexyacc:current_lexyacc_toolchain"],
)

LexYaccInfo = provider(
doc = "Paths to lex and yacc binaries.",
fields = ["lex", "yacc"],
fields = ["lex", "yacc", "runfiles"],
)

def _lexyacc_variables(ctx):
lyinfo = ctx.toolchains["@io_kythe//tools/build_rules/lexyacc:toolchain_type"].lexyaccinfo
return [
DefaultInfo(runfiles = lyinfo.runfiles, files = lyinfo.runfiles.files),
platform_common.TemplateVariableInfo({
"LEX": lyinfo.lex,
"YACC": lyinfo.yacc,
Expand All @@ -57,28 +60,50 @@ lexyacc_variables = rule(
)

def _lexyacc_toolchain_impl(ctx):
runfiles = ctx.runfiles()
if bool(ctx.attr.lex) == bool(ctx.attr.lex_path):
fail("Exactly one of lex and lex_path is required")

if ctx.attr.lex:
runfiles = runfiles.merge(ctx.attr.lex[DefaultInfo].default_runfiles)

if bool(ctx.attr.yacc) == bool(ctx.attr.yacc_path):
fail("Exactly one of yacc and yacc_path is required")

if ctx.attr.yacc:
runfiles = runfiles.merge(ctx.attr.yacc[DefaultInfo].default_runfiles)

return [
platform_common.ToolchainInfo(
lexyaccinfo = LexYaccInfo(
lex = ctx.attr.lex,
yacc = ctx.attr.yacc,
lex = ctx.attr.lex_path or ctx.executable.lex.path,
yacc = ctx.attr.yacc_path or ctx.executable.yacc.path,
runfiles = runfiles,
),
),
]

_lexyacc_toolchain = rule(
implementation = _lexyacc_toolchain_impl,
attrs = {
"lex": attr.string(),
"yacc": attr.string(),
"lex_path": attr.string(),
"yacc_path": attr.string(),
"lex": attr.label(
executable = True,
cfg = "exec",
),
"yacc": attr.label(
executable = True,
cfg = "exec",
),
},
provides = [
platform_common.ToolchainInfo,
],
)

def lexyacc_toolchain(name, lex, yacc):
_lexyacc_toolchain(name = name, lex = lex, yacc = yacc)
def lexyacc_toolchain(name, **kwargs):
_lexyacc_toolchain(name = name, **kwargs)
native.toolchain(
name = name + "_toolchain",
toolchain = ":" + name,
Expand Down Expand Up @@ -116,8 +141,8 @@ def _local_lexyacc(repository_ctx):
"package(default_visibility=[\"//visibility:public\"])",
"lexyacc_toolchain(",
" name = \"lexyacc_local\",",
" lex = \"%s\"," % flex,
" yacc = \"%s\"," % bison,
" lex_path = \"%s\"," % flex,
" yacc_path = \"%s\"," % bison,
")",
]),
)
Expand Down

0 comments on commit ad8f098

Please sign in to comment.