xref: /aosp_15_r20/external/sandboxed-api/sandboxed_api/bazel/sapi.bzl (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1*ec63e07aSXin Li# Copyright 2019 Google LLC
2*ec63e07aSXin Li#
3*ec63e07aSXin Li# Licensed under the Apache License, Version 2.0 (the "License");
4*ec63e07aSXin Li# you may not use this file except in compliance with the License.
5*ec63e07aSXin Li# You may obtain a copy of the License at
6*ec63e07aSXin Li#
7*ec63e07aSXin Li#     https://www.apache.org/licenses/LICENSE-2.0
8*ec63e07aSXin Li#
9*ec63e07aSXin Li# Unless required by applicable law or agreed to in writing, software
10*ec63e07aSXin Li# distributed under the License is distributed on an "AS IS" BASIS,
11*ec63e07aSXin Li# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*ec63e07aSXin Li# See the License for the specific language governing permissions and
13*ec63e07aSXin Li# limitations under the License.
14*ec63e07aSXin Li
15*ec63e07aSXin Li"""Starlark rules for projects using Sandboxed API."""
16*ec63e07aSXin Li
17*ec63e07aSXin Liload("//sandboxed_api/bazel:build_defs.bzl", "sapi_platform_copts")
18*ec63e07aSXin Liload("//sandboxed_api/bazel:embed_data.bzl", "sapi_cc_embed_data")
19*ec63e07aSXin Liload(
20*ec63e07aSXin Li    "//sandboxed_api/bazel:proto.bzl",
21*ec63e07aSXin Li    _sapi_proto_library = "sapi_proto_library",
22*ec63e07aSXin Li)
23*ec63e07aSXin Liload("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain", "use_cpp_toolchain")
24*ec63e07aSXin Li
25*ec63e07aSXin Li# Reexport symbols
26*ec63e07aSXin Lisapi_proto_library = _sapi_proto_library
27*ec63e07aSXin Li
28*ec63e07aSXin Li# Helper functions
29*ec63e07aSXin Lidef append_arg(arguments, name, value):
30*ec63e07aSXin Li    if value:
31*ec63e07aSXin Li        arguments.append("{}".format(name))
32*ec63e07aSXin Li        arguments.append(value)
33*ec63e07aSXin Li
34*ec63e07aSXin Lidef append_all(arguments, name, values):
35*ec63e07aSXin Li    if values:
36*ec63e07aSXin Li        for v in values:
37*ec63e07aSXin Li            append_arg(arguments, name, v)
38*ec63e07aSXin Li
39*ec63e07aSXin Lidef get_embed_dir():
40*ec63e07aSXin Li    return native.package_name()
41*ec63e07aSXin Li
42*ec63e07aSXin Lidef make_exec_label(label):
43*ec63e07aSXin Li    return attr.label(
44*ec63e07aSXin Li        default = label,
45*ec63e07aSXin Li        cfg = "exec",
46*ec63e07aSXin Li        allow_files = True,
47*ec63e07aSXin Li        executable = True,
48*ec63e07aSXin Li    )
49*ec63e07aSXin Li
50*ec63e07aSXin Li# buildifier: disable=function-docstring
51*ec63e07aSXin Lidef select_generator(ctx):
52*ec63e07aSXin Li    if ctx.attr.generator_version == 1:
53*ec63e07aSXin Li        return ctx.executable._generator_v1
54*ec63e07aSXin Li    return ctx.executable._generator_v2
55*ec63e07aSXin Li
56*ec63e07aSXin Lidef sort_deps(deps):
57*ec63e07aSXin Li    """Sorts a list of dependencies.
58*ec63e07aSXin Li
59*ec63e07aSXin Li    This does not convert absolute references targeting the current package
60*ec63e07aSXin Li    into relative ones.
61*ec63e07aSXin Li
62*ec63e07aSXin Li    Args:
63*ec63e07aSXin Li      deps: List of labels to be sorted
64*ec63e07aSXin Li    Returns:
65*ec63e07aSXin Li      A sorted list of dependencies, with local deps (starting with ":") first.
66*ec63e07aSXin Li    """
67*ec63e07aSXin Li
68*ec63e07aSXin Li    deps = depset(deps).to_list()
69*ec63e07aSXin Li    colon_deps = [x for x in deps if x.startswith(":")]
70*ec63e07aSXin Li    other_deps = [x for x in deps if not x.startswith(":")]
71*ec63e07aSXin Li    return sorted(colon_deps) + sorted(other_deps)
72*ec63e07aSXin Li
73*ec63e07aSXin Lidef cc_library_virtual_includes(target):
74*ec63e07aSXin Li    """Checks a target for virtual includes.
75*ec63e07aSXin Li
76*ec63e07aSXin Li    Those can be created by the deprecated `cc_inc_library` rule, or by using
77*ec63e07aSXin Li    a combination of `cc_library()`s `includes`, `include_prefix` and
78*ec63e07aSXin Li    `strip_include_prefix` attributes.
79*ec63e07aSXin Li
80*ec63e07aSXin Li    Args:
81*ec63e07aSXin Li      target: The Target to analyze
82*ec63e07aSXin Li    Returns:
83*ec63e07aSXin Li      A depset with include paths generated by cc_inc_library targets.
84*ec63e07aSXin Li    """
85*ec63e07aSXin Li    cc_ctx = target[CcInfo].compilation_context
86*ec63e07aSXin Li
87*ec63e07aSXin Li    includes = []
88*ec63e07aSXin Li    for f in cc_ctx.headers.to_list():
89*ec63e07aSXin Li        p = f.path
90*ec63e07aSXin Li        if not p.startswith("blaze-out") and not p.startswith("bazel-out"):
91*ec63e07aSXin Li            continue
92*ec63e07aSXin Li        for path_marker in ["/_virtual_includes/", "/_/"]:
93*ec63e07aSXin Li            i = p.find(path_marker)
94*ec63e07aSXin Li            if i == -1:
95*ec63e07aSXin Li                continue
96*ec63e07aSXin Li            includes.append(p[:i] + path_marker +
97*ec63e07aSXin Li                            p[i + len(path_marker):].split("/", 1)[0])
98*ec63e07aSXin Li
99*ec63e07aSXin Li    return depset(includes)
100*ec63e07aSXin Li
101*ec63e07aSXin Lidef _sapi_interface_impl(ctx):
102*ec63e07aSXin Li    cpp_toolchain = find_cpp_toolchain(ctx)
103*ec63e07aSXin Li    generator = select_generator(ctx)
104*ec63e07aSXin Li    use_clang_generator = ctx.attr.generator_version == 2
105*ec63e07aSXin Li
106*ec63e07aSXin Li    # TODO(szwl): warn if input_files is not set and we didn't find anything
107*ec63e07aSXin Li    input_files_paths = []
108*ec63e07aSXin Li    input_files = []
109*ec63e07aSXin Li
110*ec63e07aSXin Li    args = []
111*ec63e07aSXin Li    append_arg(args, "--sapi_name", ctx.attr.lib_name)
112*ec63e07aSXin Li    append_arg(args, "--sapi_out", ctx.outputs.out.path)
113*ec63e07aSXin Li    append_arg(args, "--sapi_embed_dir", ctx.attr.embed_dir)
114*ec63e07aSXin Li    append_arg(args, "--sapi_embed_name", ctx.attr.embed_name)
115*ec63e07aSXin Li    append_arg(args, "--sapi_functions", ",".join(ctx.attr.functions))
116*ec63e07aSXin Li    append_arg(args, "--sapi_ns", ctx.attr.namespace)
117*ec63e07aSXin Li
118*ec63e07aSXin Li    if ctx.attr.limit_scan_depth:
119*ec63e07aSXin Li        args.append("--sapi_limit_scan_depth")
120*ec63e07aSXin Li
121*ec63e07aSXin Li    # Parse provided files.
122*ec63e07aSXin Li
123*ec63e07aSXin Li    # The parser doesn't need the entire set of transitive headers
124*ec63e07aSXin Li    # here, just the top-level cc_library headers.
125*ec63e07aSXin Li    #
126*ec63e07aSXin Li    # Allow all headers through that contain the dependency's
127*ec63e07aSXin Li    # package path. Including extra headers is harmless except that
128*ec63e07aSXin Li    # we may hit Bazel's file-count limit, so be conservative and
129*ec63e07aSXin Li    # pass a lot through that we don't strictly need.
130*ec63e07aSXin Li    #
131*ec63e07aSXin Li    extra_flags = []
132*ec63e07aSXin Li    cc_ctx = ctx.attr.lib[CcInfo].compilation_context
133*ec63e07aSXin Li
134*ec63e07aSXin Li    # Append all headers as dependencies
135*ec63e07aSXin Li    input_files += cc_ctx.headers.to_list()
136*ec63e07aSXin Li
137*ec63e07aSXin Li    # Gather direct include paths as well as virtual ones
138*ec63e07aSXin Li    quote_includes = (cc_ctx.quote_includes.to_list() +
139*ec63e07aSXin Li                      cc_library_virtual_includes(ctx.attr.lib).to_list())
140*ec63e07aSXin Li
141*ec63e07aSXin Li    if use_clang_generator:
142*ec63e07aSXin Li        input_files += cpp_toolchain.all_files.to_list()
143*ec63e07aSXin Li
144*ec63e07aSXin Li        # TODO(cblichmann): Get language standard from the toolchain
145*ec63e07aSXin Li        extra_flags.append("--extra-arg=-std=c++17")
146*ec63e07aSXin Li
147*ec63e07aSXin Li        # Disable warnings in parsed code
148*ec63e07aSXin Li        extra_flags.append("--extra-arg=-Wno-everything")
149*ec63e07aSXin Li        extra_flags += ["--extra-arg=-D{}".format(d) for d in cc_ctx.defines.to_list()]
150*ec63e07aSXin Li        extra_flags += ["--extra-arg=-isystem{}".format(i) for i in cc_ctx.system_includes.to_list()]
151*ec63e07aSXin Li        extra_flags += ["--extra-arg=-iquote{}".format(i) for i in quote_includes]
152*ec63e07aSXin Li        extra_flags += ["--extra-arg=-isystem{}".format(d) for d in cpp_toolchain.built_in_include_directories]
153*ec63e07aSXin Li    else:
154*ec63e07aSXin Li        append_all(extra_flags, "-D", cc_ctx.defines.to_list())
155*ec63e07aSXin Li        append_all(extra_flags, "-isystem", cc_ctx.system_includes.to_list())
156*ec63e07aSXin Li        append_all(extra_flags, "-iquote", quote_includes)
157*ec63e07aSXin Li
158*ec63e07aSXin Li    if ctx.attr.input_files:
159*ec63e07aSXin Li        for f in ctx.files.input_files:
160*ec63e07aSXin Li            input_files.append(f)
161*ec63e07aSXin Li            input_files_paths.append(f.path)
162*ec63e07aSXin Li    else:
163*ec63e07aSXin Li        # Try to find files automatically
164*ec63e07aSXin Li        for h in cc_ctx.direct_headers:
165*ec63e07aSXin Li            if h.extension != "h" or "/PROTECTED/" in h.path:
166*ec63e07aSXin Li                continue
167*ec63e07aSXin Li
168*ec63e07aSXin Li            # Include only headers coming from the target
169*ec63e07aSXin Li            # not ones that it depends on by comparing the label packages.
170*ec63e07aSXin Li            if (h.owner.package == ctx.attr.lib.label.package):
171*ec63e07aSXin Li                input_files_paths.append(h.path)
172*ec63e07aSXin Li
173*ec63e07aSXin Li    if use_clang_generator:
174*ec63e07aSXin Li        args += extra_flags + input_files_paths
175*ec63e07aSXin Li    else:
176*ec63e07aSXin Li        append_arg(args, "--sapi_in", ",".join(input_files_paths))
177*ec63e07aSXin Li        args += ["--"] + extra_flags
178*ec63e07aSXin Li
179*ec63e07aSXin Li    progress_msg = ("Generating {} from {} header files." +
180*ec63e07aSXin Li                    "").format(ctx.outputs.out.short_path, len(input_files_paths))
181*ec63e07aSXin Li    ctx.actions.run(
182*ec63e07aSXin Li        inputs = input_files,
183*ec63e07aSXin Li        outputs = [ctx.outputs.out],
184*ec63e07aSXin Li        arguments = args,
185*ec63e07aSXin Li        mnemonic = "SapiInterfaceGen",
186*ec63e07aSXin Li        progress_message = progress_msg,
187*ec63e07aSXin Li        executable = generator,
188*ec63e07aSXin Li    )
189*ec63e07aSXin Li
190*ec63e07aSXin Li# Build rule that generates SAPI interface.
191*ec63e07aSXin Lisapi_interface = rule(
192*ec63e07aSXin Li    implementation = _sapi_interface_impl,
193*ec63e07aSXin Li    attrs = {
194*ec63e07aSXin Li        "out": attr.output(mandatory = True),
195*ec63e07aSXin Li        "embed_dir": attr.string(),
196*ec63e07aSXin Li        "embed_name": attr.string(),
197*ec63e07aSXin Li        "functions": attr.string_list(
198*ec63e07aSXin Li            allow_empty = True,
199*ec63e07aSXin Li            default = [],
200*ec63e07aSXin Li        ),
201*ec63e07aSXin Li        "input_files": attr.label_list(
202*ec63e07aSXin Li            providers = [CcInfo],
203*ec63e07aSXin Li            allow_files = True,
204*ec63e07aSXin Li        ),
205*ec63e07aSXin Li        "lib": attr.label(
206*ec63e07aSXin Li            providers = [CcInfo],
207*ec63e07aSXin Li            mandatory = True,
208*ec63e07aSXin Li        ),
209*ec63e07aSXin Li        "lib_name": attr.string(mandatory = True),
210*ec63e07aSXin Li        "namespace": attr.string(),
211*ec63e07aSXin Li        "limit_scan_depth": attr.bool(default = False),
212*ec63e07aSXin Li        "api_version": attr.int(
213*ec63e07aSXin Li            default = 1,
214*ec63e07aSXin Li            values = [1],  # Only a single version is defined right now
215*ec63e07aSXin Li        ),
216*ec63e07aSXin Li        "generator_version": attr.int(
217*ec63e07aSXin Li            default = 1,
218*ec63e07aSXin Li            values = [1, 2],
219*ec63e07aSXin Li        ),
220*ec63e07aSXin Li        "_generator_v1": make_exec_label(
221*ec63e07aSXin Li            "//sandboxed_api/tools/generator2:sapi_generator",
222*ec63e07aSXin Li        ),
223*ec63e07aSXin Li        "_generator_v2": make_exec_label(
224*ec63e07aSXin Li            # TODO(cblichmann): Add prebuilt version of Clang based generator
225*ec63e07aSXin Li            "//sandboxed_api/tools/clang_generator:generator_tool",
226*ec63e07aSXin Li        ),
227*ec63e07aSXin Li        "_cc_toolchain": attr.label(
228*ec63e07aSXin Li            default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"),
229*ec63e07aSXin Li        ),
230*ec63e07aSXin Li    },
231*ec63e07aSXin Li    output_to_genfiles = True,
232*ec63e07aSXin Li    toolchains = use_cpp_toolchain(),
233*ec63e07aSXin Li)
234*ec63e07aSXin Li
235*ec63e07aSXin Lidef sapi_library(
236*ec63e07aSXin Li        name,
237*ec63e07aSXin Li        lib,
238*ec63e07aSXin Li        lib_name,
239*ec63e07aSXin Li        malloc = "@bazel_tools//tools/cpp:malloc",
240*ec63e07aSXin Li        namespace = "",
241*ec63e07aSXin Li        api_version = 1,
242*ec63e07aSXin Li        embed = True,
243*ec63e07aSXin Li        add_default_deps = True,
244*ec63e07aSXin Li        limit_scan_depth = False,
245*ec63e07aSXin Li        srcs = [],
246*ec63e07aSXin Li        data = [],
247*ec63e07aSXin Li        hdrs = [],
248*ec63e07aSXin Li        copts = sapi_platform_copts(),
249*ec63e07aSXin Li        defines = [],
250*ec63e07aSXin Li        functions = [],
251*ec63e07aSXin Li        header = "",
252*ec63e07aSXin Li        input_files = [],
253*ec63e07aSXin Li        deps = [],
254*ec63e07aSXin Li        tags = [],
255*ec63e07aSXin Li        generator_version = 1,
256*ec63e07aSXin Li        visibility = None,
257*ec63e07aSXin Li        compatible_with = None,
258*ec63e07aSXin Li        default_copts = []):
259*ec63e07aSXin Li    """Provides the implementation of a Sandboxed API library.
260*ec63e07aSXin Li
261*ec63e07aSXin Li    Args:
262*ec63e07aSXin Li      name: Name of the sandboxed library
263*ec63e07aSXin Li      lib: Label of the library target to sandbox
264*ec63e07aSXin Li      lib_name: Name of the class which will proxy the library functions from
265*ec63e07aSXin Li        the functions list
266*ec63e07aSXin Li      malloc: Override the default dependency on malloc
267*ec63e07aSXin Li      namespace: A C++ namespace identifier to place the API class into
268*ec63e07aSXin Li      embed: Whether the SAPI library should be embedded inside the host code
269*ec63e07aSXin Li      add_default_deps: Add SAPI dependencies to target (deprecated)
270*ec63e07aSXin Li      limit_scan_depth: Limit include depth for header generator (deprecated)
271*ec63e07aSXin Li      api_version: Which version of the Sandboxed API to generate. Currently,
272*ec63e07aSXin Li        only version 1 is defined.
273*ec63e07aSXin Li      srcs: Any additional sources to include with the sandboxed library
274*ec63e07aSXin Li      data: To be used with srcs, any additional data files to make available
275*ec63e07aSXin Li        to the sandboxed library.
276*ec63e07aSXin Li      hdrs: Like srcs, any additional headers to include with the sandboxed
277*ec63e07aSXin Li        library
278*ec63e07aSXin Li      copts: Add these options to the C++ compilation command. See
279*ec63e07aSXin Li        cc_library.copts.
280*ec63e07aSXin Li      defines: List of defines to add to the compile line. See
281*ec63e07aSXin Li        cc_library.defines.
282*ec63e07aSXin Li      functions: A list for function to use from host code
283*ec63e07aSXin Li      header: If set, do not generate a header, but use the specified one
284*ec63e07aSXin Li        (deprecated).
285*ec63e07aSXin Li      input_files: List of source files which the SAPI interface generator
286*ec63e07aSXin Li        should scan for function declarations
287*ec63e07aSXin Li      deps: Extra dependencies to add to the SAPI library
288*ec63e07aSXin Li      tags: Extra tags to associate with the target
289*ec63e07aSXin Li      generator_version: Which version the the interface generator to use
290*ec63e07aSXin Li        (experimental). Version 1 uses the Python/libclang based `generator2`,
291*ec63e07aSXin Li        version 2 uses the newer C++ implementation that uses the full clang
292*ec63e07aSXin Li        compiler front-end for parsing. Both emit equivalent Sandboxed APIs.
293*ec63e07aSXin Li      visibility: Target visibility
294*ec63e07aSXin Li      compatible_with: The list of environments this target can be built for,
295*ec63e07aSXin Li        in addition to default-supported environments.
296*ec63e07aSXin Li      default_copts: List of package level default copts, an additional
297*ec63e07aSXin Li        attribute since copts already has default value.
298*ec63e07aSXin Li    """
299*ec63e07aSXin Li
300*ec63e07aSXin Li    common = {
301*ec63e07aSXin Li        "tags": tags,
302*ec63e07aSXin Li    }
303*ec63e07aSXin Li    if visibility:
304*ec63e07aSXin Li        common["visibility"] = visibility
305*ec63e07aSXin Li
306*ec63e07aSXin Li    if compatible_with != None:
307*ec63e07aSXin Li        common["compatible_with"] = compatible_with
308*ec63e07aSXin Li
309*ec63e07aSXin Li    generated_header = name + ".sapi.h"
310*ec63e07aSXin Li
311*ec63e07aSXin Li    # Reference (pull into the archive) required functions only. If the functions'
312*ec63e07aSXin Li    # array is empty, pull in the whole archive (may not compile with MSAN).
313*ec63e07aSXin Li    exported_funcs = ["-Wl,-u," + s for s in functions]
314*ec63e07aSXin Li    if (not exported_funcs):
315*ec63e07aSXin Li        exported_funcs = [
316*ec63e07aSXin Li            "-Wl,--whole-archive",
317*ec63e07aSXin Li            "-Wl,--allow-multiple-definition",
318*ec63e07aSXin Li        ]
319*ec63e07aSXin Li
320*ec63e07aSXin Li    lib_hdrs = hdrs or []
321*ec63e07aSXin Li    if header:
322*ec63e07aSXin Li        lib_hdrs += [header]
323*ec63e07aSXin Li    else:
324*ec63e07aSXin Li        lib_hdrs += [generated_header]
325*ec63e07aSXin Li
326*ec63e07aSXin Li    default_deps = ["//sandboxed_api/sandbox2"]
327*ec63e07aSXin Li
328*ec63e07aSXin Li    # Library that contains generated interface and sandboxed binary as a data
329*ec63e07aSXin Li    # dependency. Add this as a dependency instead of original library.
330*ec63e07aSXin Li    native.cc_library(
331*ec63e07aSXin Li        name = name,
332*ec63e07aSXin Li        srcs = srcs,
333*ec63e07aSXin Li        data = [":" + name + ".bin"] + data,
334*ec63e07aSXin Li        hdrs = lib_hdrs,
335*ec63e07aSXin Li        copts = default_copts + copts,
336*ec63e07aSXin Li        defines = defines,
337*ec63e07aSXin Li        deps = sort_deps(
338*ec63e07aSXin Li            [
339*ec63e07aSXin Li                "@com_google_absl//absl/base:core_headers",
340*ec63e07aSXin Li                "@com_google_absl//absl/status",
341*ec63e07aSXin Li                "@com_google_absl//absl/status:statusor",
342*ec63e07aSXin Li                "//sandboxed_api:sapi",
343*ec63e07aSXin Li                "//sandboxed_api/util:status",
344*ec63e07aSXin Li                "//sandboxed_api:vars",
345*ec63e07aSXin Li            ] + deps +
346*ec63e07aSXin Li            ([":" + name + "_embed"] if embed else []) +
347*ec63e07aSXin Li            (default_deps if add_default_deps else []),
348*ec63e07aSXin Li        ),
349*ec63e07aSXin Li        **common
350*ec63e07aSXin Li    )
351*ec63e07aSXin Li
352*ec63e07aSXin Li    native.cc_binary(
353*ec63e07aSXin Li        name = name + ".bin",
354*ec63e07aSXin Li        linkopts = [
355*ec63e07aSXin Li            "-ldl",  # For dlopen(), dlsym()
356*ec63e07aSXin Li            # The sandboxing client must have access to all
357*ec63e07aSXin Li            "-Wl,-E",  # symbols used in the sandboxed library, so these
358*ec63e07aSXin Li        ] + exported_funcs,  # must be both referenced, and exported
359*ec63e07aSXin Li        malloc = malloc,
360*ec63e07aSXin Li        deps = [
361*ec63e07aSXin Li            ":" + name + ".lib",
362*ec63e07aSXin Li            "//sandboxed_api:client",
363*ec63e07aSXin Li        ],
364*ec63e07aSXin Li        copts = default_copts,
365*ec63e07aSXin Li        **common
366*ec63e07aSXin Li    )
367*ec63e07aSXin Li
368*ec63e07aSXin Li    native.cc_library(
369*ec63e07aSXin Li        name = name + ".lib",
370*ec63e07aSXin Li        deps = [lib],
371*ec63e07aSXin Li        alwayslink = 1,  # All functions are linked into depending binaries
372*ec63e07aSXin Li        copts = default_copts,
373*ec63e07aSXin Li        **common
374*ec63e07aSXin Li    )
375*ec63e07aSXin Li
376*ec63e07aSXin Li    embed_name = ""
377*ec63e07aSXin Li    embed_dir = ""
378*ec63e07aSXin Li    if embed:
379*ec63e07aSXin Li        embed_name = name
380*ec63e07aSXin Li
381*ec63e07aSXin Li        sapi_cc_embed_data(
382*ec63e07aSXin Li            name = name + "_embed",
383*ec63e07aSXin Li            srcs = [name + ".bin"],
384*ec63e07aSXin Li            namespace = namespace,
385*ec63e07aSXin Li            **common
386*ec63e07aSXin Li        )
387*ec63e07aSXin Li        embed_dir = get_embed_dir()
388*ec63e07aSXin Li
389*ec63e07aSXin Li    sapi_interface(
390*ec63e07aSXin Li        name = name + ".interface",
391*ec63e07aSXin Li        lib_name = lib_name,
392*ec63e07aSXin Li        lib = lib,
393*ec63e07aSXin Li        functions = functions,
394*ec63e07aSXin Li        input_files = input_files,
395*ec63e07aSXin Li        out = generated_header,
396*ec63e07aSXin Li        embed_name = embed_name,
397*ec63e07aSXin Li        embed_dir = embed_dir,
398*ec63e07aSXin Li        namespace = namespace,
399*ec63e07aSXin Li        api_version = api_version,
400*ec63e07aSXin Li        generator_version = generator_version,
401*ec63e07aSXin Li        limit_scan_depth = limit_scan_depth,
402*ec63e07aSXin Li        **common
403*ec63e07aSXin Li    )
404