mirror of
https://github.com/The-OpenROAD-Project/OpenROAD.git
synced 2026-06-02 01:08:34 +08:00
- Extract shared transitive-depset helpers into bazel/swig_common.bzl; tcl_wrap_cc and python_wrap_cc had identical copy-pasted helpers. Providers stay distinct so deps type safety is preserved. - Delete empty bazel/build_helper.bzl (never loaded anywhere). - Remove dead .tcl/.py endswith filter in tcl_encode_or.bzl; the attr.label_list(allow_files=[".tcl", ".py"]) already enforces it. - Deduplicate -Wall/-Wextra/-Wno-sign-compare/-Wno-unused-parameter in OPENROAD_COPTS; these are already set globally via .bazelrc. - Add missing doc= for runtime_header attr; drop stale "for google3" docstring and obsolete/incorrect narration comments. Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
150 lines
4.7 KiB
Python
150 lines
4.7 KiB
Python
# SPDX-License-Identifier: BSD-3-Clause
|
|
# Copyright (c) 2025-2025, The OpenROAD Authors
|
|
|
|
"""A Python SWIG wrapping rule
|
|
|
|
These rules generate a C++ src file that is expected to be used as srcs in
|
|
cc_library or cc_binary rules. See below for expected usage.
|
|
cc_library(srcs=[":python_foo"])
|
|
python_wrap_cc(name = "python_foo", srcs=["exception.i"],...)
|
|
"""
|
|
|
|
load(
|
|
"//bazel:swig_common.bzl",
|
|
"get_transitive_includes",
|
|
"get_transitive_options",
|
|
"get_transitive_srcs",
|
|
)
|
|
|
|
PythonSwigInfo = provider(
|
|
"PythonSwigInfo for taking dependencies on other swig info rules",
|
|
fields = [
|
|
"transitive_srcs",
|
|
"includes",
|
|
"swig_options",
|
|
],
|
|
)
|
|
|
|
PYTHON_STABLE_API_DEFINE = "Py_LIMITED_API=0x030A0000"
|
|
|
|
PYTHON_EXTENSION_LINKOPTS = select({
|
|
"@platforms//os:macos": [
|
|
"-undefined",
|
|
"dynamic_lookup",
|
|
],
|
|
"//conditions:default": [],
|
|
})
|
|
|
|
def _python_wrap_cc_impl(ctx):
|
|
"""Generates a single C++ file from the provided srcs in a DefaultInfo."""
|
|
if len(ctx.files.srcs) > 1 and not ctx.attr.root_swig_src:
|
|
fail("If multiple src files are provided, root_swig_src must be specified.")
|
|
|
|
swig_lib_dir = ctx.file._swig_swg.dirname
|
|
|
|
root_file = ctx.file.root_swig_src or ctx.files.srcs[0]
|
|
|
|
cc_outfile_name = ctx.attr.out or (ctx.attr.name + ".cc")
|
|
cc_output_file = ctx.actions.declare_file(cc_outfile_name)
|
|
py_outfile_name = ctx.attr.module + ".py"
|
|
py_output_file = ctx.actions.declare_file(py_outfile_name)
|
|
|
|
include_root_directory = ""
|
|
if ctx.label.workspace_root:
|
|
include_root_directory = ctx.label.workspace_root + "/"
|
|
if ctx.label.package:
|
|
include_root_directory += ctx.label.package + "/"
|
|
|
|
src_inputs = get_transitive_srcs(
|
|
PythonSwigInfo,
|
|
ctx.files.srcs + ctx.files.root_swig_src,
|
|
ctx.attr.deps,
|
|
)
|
|
includes_paths = get_transitive_includes(
|
|
PythonSwigInfo,
|
|
["{}{}".format(include_root_directory, include) for include in ctx.attr.swig_includes],
|
|
ctx.attr.deps,
|
|
)
|
|
swig_options = get_transitive_options(PythonSwigInfo, ctx.attr.swig_options, ctx.attr.deps)
|
|
|
|
args = ctx.actions.args()
|
|
args.add("-DBAZEL=1")
|
|
args.add("-python")
|
|
args.add("-c++")
|
|
args.add("-flatstaticmethod")
|
|
args.add("-module")
|
|
args.add(ctx.attr.module)
|
|
args.add_all(swig_options.to_list())
|
|
args.add_all(includes_paths.to_list(), format_each = "-I%s")
|
|
args.add("-o")
|
|
args.add(cc_output_file.path)
|
|
args.add(root_file.path)
|
|
|
|
ctx.actions.run(
|
|
outputs = [cc_output_file, py_output_file],
|
|
inputs = src_inputs,
|
|
arguments = [args],
|
|
env = {"SWIG_LIB": swig_lib_dir},
|
|
tools = ctx.files._swig_lib,
|
|
executable = ctx.executable._swig,
|
|
)
|
|
return [
|
|
DefaultInfo(files = depset([cc_output_file, py_output_file])),
|
|
PythonSwigInfo(
|
|
transitive_srcs = src_inputs,
|
|
includes = includes_paths,
|
|
swig_options = swig_options,
|
|
),
|
|
]
|
|
|
|
python_wrap_cc = rule(
|
|
implementation = _python_wrap_cc_impl,
|
|
attrs = {
|
|
"deps": attr.label_list(
|
|
allow_empty = True,
|
|
doc = "python_wrap_cc dependencies",
|
|
providers = [PythonSwigInfo],
|
|
),
|
|
"module": attr.string(
|
|
mandatory = True,
|
|
doc = "swig module",
|
|
),
|
|
"out": attr.string(
|
|
doc = "The name of the C++ source file generated by these rules. If not set, defaults to '<name>.cc'.",
|
|
),
|
|
"root_swig_src": attr.label(
|
|
allow_single_file = [".swig", ".i"],
|
|
doc = """If more than one swig file is included in this rule.
|
|
The root file must be explicitly provided. This is the file which will be passed to
|
|
swig for generation.""",
|
|
),
|
|
"srcs": attr.label_list(
|
|
allow_empty = False,
|
|
allow_files = [".i", ".swig", ".h", ".hpp", ".hh"],
|
|
doc = "Swig files that generate C++ files",
|
|
),
|
|
"swig_includes": attr.string_list(
|
|
doc = "List of directories relative to the BUILD file to append as -I flags to SWIG",
|
|
),
|
|
"swig_options": attr.string_list(
|
|
doc = "args to pass directly to the swig binary",
|
|
),
|
|
"_swig": attr.label(
|
|
default = "@swig",
|
|
allow_files = True,
|
|
cfg = "exec",
|
|
executable = True,
|
|
),
|
|
"_swig_lib": attr.label(
|
|
default = "@swig//:lib_python",
|
|
allow_files = True,
|
|
),
|
|
"_swig_swg": attr.label(
|
|
default = "@swig//:swig_swg",
|
|
allow_single_file = True,
|
|
doc = "SWIG swig.swg library file used for determining SWIG_LIB " +
|
|
"env variable (internal attribute).",
|
|
),
|
|
},
|
|
)
|