mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
bazel: Make generator configurable, minor improvements
This change merges the internal version of `sapi.bzl` with the external version again: - Add more docstrings to the various macros - Skip creation of `.isystem` file, get info from toolchain instead PiperOrigin-RevId: 437730588 Change-Id: I6f670d32e3d7177a6a160fd24cbee6f8f3ca9503
This commit is contained in:
parent
f928f1dd7c
commit
466cc07254
|
@ -12,9 +12,10 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Macros that simplifies header and library generation for Sandboxed API."""
|
||||
"""Starlark rules for projects using Sandboxed API."""
|
||||
|
||||
load("//sandboxed_api/bazel:embed_data.bzl", "sapi_cc_embed_data")
|
||||
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
|
||||
|
||||
# Helper functions
|
||||
def append_arg(arguments, name, value):
|
||||
|
@ -31,6 +32,16 @@ def get_embed_dir():
|
|||
return native.package_name()
|
||||
|
||||
def sort_deps(deps):
|
||||
"""Sorts a list of dependencies.
|
||||
|
||||
This does not convert absolute references targeting the current package
|
||||
into relative ones.
|
||||
|
||||
Args:
|
||||
deps: List of labels to be sorted
|
||||
Returns:
|
||||
A sorted list of dependencies, with local deps (starting with ":") first.
|
||||
"""
|
||||
deps = depset(deps).to_list()
|
||||
colon_deps = [x for x in deps if x.startswith(":")]
|
||||
other_deps = [x for x in deps if not x.startswith(":")]
|
||||
|
@ -39,6 +50,9 @@ def sort_deps(deps):
|
|||
def sapi_interface_impl(ctx):
|
||||
"""Implementation of build rule that generates SAPI interface."""
|
||||
|
||||
cpp_toolchain = find_cpp_toolchain(ctx)
|
||||
use_clang_generator = ctx.executable.generator.basename == "generator_tool"
|
||||
|
||||
# TODO(szwl): warn if input_files is not set and we didn't find anything
|
||||
input_files_paths = []
|
||||
input_files = []
|
||||
|
@ -50,10 +64,6 @@ def sapi_interface_impl(ctx):
|
|||
append_arg(args, "--sapi_embed_name", ctx.attr.embed_name)
|
||||
append_arg(args, "--sapi_functions", ",".join(ctx.attr.functions))
|
||||
append_arg(args, "--sapi_ns", ctx.attr.namespace)
|
||||
if ctx.attr.isystem:
|
||||
isystem = ctx.attr.isystem.files.to_list()[0]
|
||||
append_arg(args, "--sapi_isystem", isystem.path)
|
||||
input_files += [isystem]
|
||||
|
||||
if ctx.attr.limit_scan_depth:
|
||||
args.append("--sapi_limit_scan_depth")
|
||||
|
@ -67,7 +77,7 @@ def sapi_interface_impl(ctx):
|
|||
# package path. Including extra headers is harmless except that
|
||||
# we may hit Bazel's file-count limit, so be conservative and
|
||||
# pass a lot through that we don't strictly need.
|
||||
|
||||
#
|
||||
extra_flags = []
|
||||
cc_ctx = ctx.attr.lib[CcInfo].compilation_context
|
||||
|
||||
|
@ -75,20 +85,31 @@ def sapi_interface_impl(ctx):
|
|||
input_files += cc_ctx.headers.to_list()
|
||||
|
||||
quote_includes = cc_ctx.quote_includes.to_list()
|
||||
append_all(extra_flags, "-D", cc_ctx.defines.to_list())
|
||||
append_all(extra_flags, "-isystem", cc_ctx.system_includes.to_list())
|
||||
append_all(extra_flags, "-iquote", quote_includes)
|
||||
|
||||
if use_clang_generator:
|
||||
input_files += cpp_toolchain.all_files.to_list()
|
||||
|
||||
# TODO(cblichmann): Get language standard from the toolchain
|
||||
extra_flags.append("--extra-arg=-std=c++17")
|
||||
|
||||
# Disable warnings in parsed code
|
||||
extra_flags.append("--extra-arg=-Wno-everything")
|
||||
extra_flags += ["--extra-arg=-isystem{}".format(d) for d in cpp_toolchain.built_in_include_directories]
|
||||
extra_flags += ["--extra-arg=-D{}".format(d) for d in cc_ctx.defines.to_list()]
|
||||
extra_flags += ["--extra-arg=-isystem{}".format(i) for i in cc_ctx.system_includes.to_list()]
|
||||
extra_flags += ["--extra-arg=-iquote{}".format(i) for i in quote_includes]
|
||||
else:
|
||||
append_all(extra_flags, "-D", cc_ctx.defines.to_list())
|
||||
append_all(extra_flags, "-isystem", cc_ctx.system_includes.to_list())
|
||||
append_all(extra_flags, "-iquote", quote_includes)
|
||||
|
||||
if ctx.attr.input_files:
|
||||
for target in ctx.attr.input_files:
|
||||
if target.files:
|
||||
for f in target.files.to_list():
|
||||
input_files_paths.append(f.path)
|
||||
input_files.append(f)
|
||||
for f in ctx.files.input_files:
|
||||
input_files.append(f)
|
||||
input_files_paths.append(f.path)
|
||||
else:
|
||||
# Try to find files automatically
|
||||
for h in cc_ctx.direct_headers:
|
||||
# Collect all headers as dependency.
|
||||
if h.extension != "h" or "/PROTECTED/" in h.path:
|
||||
continue
|
||||
|
||||
|
@ -97,8 +118,11 @@ def sapi_interface_impl(ctx):
|
|||
if (h.owner.package == ctx.attr.lib.label.package):
|
||||
input_files_paths.append(h.path)
|
||||
|
||||
append_arg(args, "--sapi_in", ",".join(input_files_paths))
|
||||
args += ["--"] + extra_flags
|
||||
if use_clang_generator:
|
||||
args += extra_flags + input_files_paths
|
||||
else:
|
||||
append_arg(args, "--sapi_in", ",".join(input_files_paths))
|
||||
args += ["--"] + extra_flags
|
||||
|
||||
progress_msg = ("Generating {} from {} header files." +
|
||||
"").format(ctx.outputs.out.short_path, len(input_files_paths))
|
||||
|
@ -107,7 +131,7 @@ def sapi_interface_impl(ctx):
|
|||
outputs = [ctx.outputs.out],
|
||||
arguments = args,
|
||||
progress_message = progress_msg,
|
||||
executable = ctx.executable._sapi_generator,
|
||||
executable = ctx.executable.generator,
|
||||
)
|
||||
|
||||
# Build rule that generates SAPI interface.
|
||||
|
@ -118,22 +142,23 @@ sapi_interface = rule(
|
|||
"embed_dir": attr.string(),
|
||||
"embed_name": attr.string(),
|
||||
"functions": attr.string_list(allow_empty = True, default = []),
|
||||
"include_prefix": attr.string(),
|
||||
"input_files": attr.label_list(allow_files = True),
|
||||
"lib": attr.label(providers = [CcInfo], mandatory = True),
|
||||
"lib_name": attr.string(mandatory = True),
|
||||
"namespace": attr.string(),
|
||||
"isystem": attr.label(),
|
||||
"limit_scan_depth": attr.bool(default = False),
|
||||
"_sapi_generator": attr.label(
|
||||
"generator": attr.label(
|
||||
executable = True,
|
||||
cfg = "host",
|
||||
allow_files = True,
|
||||
default = Label("@com_google_sandboxed_api//sandboxed_api/" +
|
||||
"tools/generator2:sapi_generator"),
|
||||
default = Label("//sandboxed_api/tools/generator2:sapi_generator"),
|
||||
),
|
||||
"_cc_toolchain": attr.label(
|
||||
default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"),
|
||||
),
|
||||
},
|
||||
output_to_genfiles = True,
|
||||
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
|
||||
)
|
||||
|
||||
def sapi_library(
|
||||
|
@ -143,6 +168,7 @@ def sapi_library(
|
|||
namespace = "",
|
||||
embed = True,
|
||||
add_default_deps = True,
|
||||
limit_scan_depth = False,
|
||||
srcs = [],
|
||||
hdrs = [],
|
||||
functions = [],
|
||||
|
@ -150,10 +176,35 @@ def sapi_library(
|
|||
input_files = [],
|
||||
deps = [],
|
||||
tags = [],
|
||||
generator_executable = "//sandboxed_api/tools/generator2:sapi_generator",
|
||||
visibility = None):
|
||||
"""Provides the implementation of a Sandboxed API library."""
|
||||
"""Provides the implementation of a Sandboxed API library.
|
||||
|
||||
Args:
|
||||
name: Name of the sandboxed library
|
||||
lib: Label of the library target to sandbox
|
||||
lib_name: Name of the class which will proxy the library functions from
|
||||
the functions list
|
||||
malloc: Override the default dependency on malloc
|
||||
namespace: A C++ namespace identifier to place the API class into
|
||||
embed: Whether the SAPI library should be embedded inside the host code
|
||||
add_default_deps: Add SAPI dependencies to target (deprecated)
|
||||
limit_scan_depth: Limit include depth for header generator (deprecated)
|
||||
srcs: Any additional sources to include with the sandboxed library
|
||||
hdrs: Like srcs, any additional headers to include with the sandboxed
|
||||
library
|
||||
functions: A list for function to use from host code
|
||||
header: If set, do not generate a header, but use the specified one
|
||||
(deprecated).
|
||||
input_files: List of source files which the SAPI interface generator
|
||||
should scan for function declaration
|
||||
deps: Extra dependencies to add to the SAPI library
|
||||
tags: Extra tags to associate with the target
|
||||
generator_executable: Label of the SAPI interface generator to use
|
||||
(experimental).
|
||||
visibility: Target visibility
|
||||
"""
|
||||
|
||||
rprefix = "@com_google_sandboxed_api"
|
||||
common = {
|
||||
"tags": tags,
|
||||
}
|
||||
|
@ -164,7 +215,7 @@ def sapi_library(
|
|||
|
||||
# Reference (pull into the archive) required functions only. If the functions'
|
||||
# array is empty, pull in the whole archive (may not compile with MSAN).
|
||||
exported_funcs = ["-Wl,--export-dynamic-symbol," + s for s in functions]
|
||||
exported_funcs = ["-Wl,-u," + s for s in functions]
|
||||
if (not exported_funcs):
|
||||
exported_funcs = [
|
||||
"-Wl,--whole-archive",
|
||||
|
@ -177,7 +228,7 @@ def sapi_library(
|
|||
else:
|
||||
lib_hdrs += [generated_header]
|
||||
|
||||
default_deps = [rprefix + "//sandboxed_api/sandbox2"]
|
||||
default_deps = ["//sandboxed_api/sandbox2"]
|
||||
|
||||
# Library that contains generated interface and sandboxed binary as a data
|
||||
# dependency. Add this as a dependency instead of original library.
|
||||
|
@ -188,11 +239,12 @@ def sapi_library(
|
|||
data = [":" + name + ".bin"],
|
||||
deps = sort_deps(
|
||||
[
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
rprefix + "//sandboxed_api:sapi",
|
||||
rprefix + "//sandboxed_api/util:status",
|
||||
rprefix + "//sandboxed_api:vars",
|
||||
"//sandboxed_api:sapi",
|
||||
"//sandboxed_api/util:status",
|
||||
"//sandboxed_api:vars",
|
||||
] + deps +
|
||||
([":" + name + "_embed"] if embed else []) +
|
||||
(default_deps if add_default_deps else []),
|
||||
|
@ -204,14 +256,12 @@ def sapi_library(
|
|||
name = name + ".bin",
|
||||
linkopts = [
|
||||
"-ldl", # For dlopen(), dlsym()
|
||||
# The sandboxing client must have access to all symbols used in
|
||||
# the sandboxed library, so these must be both referenced, and
|
||||
# exported
|
||||
"-Wl,-E",
|
||||
] + exported_funcs,
|
||||
# The sandboxing client must have access to all
|
||||
"-Wl,-E", # symbols used in the sandboxed library, so these
|
||||
] + exported_funcs, # must be both referenced, and exported
|
||||
deps = [
|
||||
":" + name + ".lib",
|
||||
rprefix + "//sandboxed_api:client",
|
||||
"//sandboxed_api:client",
|
||||
],
|
||||
**common
|
||||
)
|
||||
|
@ -246,15 +296,7 @@ def sapi_library(
|
|||
embed_name = embed_name,
|
||||
embed_dir = embed_dir,
|
||||
namespace = namespace,
|
||||
isystem = ":" + name + ".isystem",
|
||||
generator = generator_executable,
|
||||
limit_scan_depth = limit_scan_depth,
|
||||
**common
|
||||
)
|
||||
|
||||
native.genrule(
|
||||
name = name + ".isystem",
|
||||
outs = [name + ".isystem.list"],
|
||||
cmd = """$(CC) -E -x c++ -v /dev/null 2>&1 |
|
||||
awk '/> search starts here:/{f=1;next}/^End of search/{f=0}f{print $$1}' > $@
|
||||
""",
|
||||
toolchains = ["@bazel_tools//tools/cpp:current_cc_toolchain"],
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue
Block a user