Skip to content

Commit 3a2a04b

Browse files
committed
Merge branch 'master' of https://github.com/The-OpenROAD-Project-private/OpenROAD into secure-hier-repair-tie-fanout
Signed-off-by: Jaehyun Kim <[email protected]>
2 parents 2c453d0 + 7136f1c commit 3a2a04b

File tree

327 files changed

+130171
-1244
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

327 files changed

+130171
-1244
lines changed

.github/workflows/github-actions-lint-tcl.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ jobs:
1919
- name: Install Dependencies
2020
run: |
2121
python3 -m venv venv
22-
venv/bin/pip install tclint==0.4.2
22+
venv/bin/pip install tclint==0.6.1
2323
2424
- name: Lint
2525
run: |
2626
source venv/bin/activate
2727
tclfmt --version
2828
tclfmt --in-place .
2929
git diff --exit-code
30-
tclint --no-check-style .
30+
tclint .
3131

BUILD.bazel

Lines changed: 108 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
55
load("//bazel:tcl_encode_or.bzl", "tcl_encode")
66
load("//bazel:tcl_wrap_cc.bzl", "tcl_wrap_cc")
7+
load("//bazel:python_wrap_cc.bzl", "python_wrap_cc", "PYTHON_STABLE_API_DEFINE")
78

89
package(
910
features = [
@@ -55,6 +56,10 @@ OPENROAD_LIBRARY_DEPS = [
5556
"//src/cts:ui",
5657
"//src/cut",
5758
"//src/dbSta",
59+
"//src/dbSta:dbNetwork",
60+
"//src/dbSta:dbReadVerilog",
61+
"//src/dbSta:dbSdcNetwork",
62+
"//src/dbSta:SpefWriter",
5863
"//src/dbSta:ui",
5964
"//src/dft",
6065
"//src/dft:ui",
@@ -133,23 +138,26 @@ cc_binary(
133138
name = "openroad",
134139
srcs = [
135140
"src/Main.cc",
136-
"//bazel:runfiles",
137141
],
138142
copts = OPENROAD_COPTS,
139143
features = ["-use_header_modules"],
140-
malloc = "@tcmalloc//tcmalloc",
144+
malloc = select({
145+
"@platforms//os:linux": "@tcmalloc//tcmalloc",
146+
"@platforms//os:macos": "@bazel_tools//tools/cpp:malloc",
147+
}),
141148
visibility = ["//visibility:public"],
142149
deps = [
143150
":openroad_lib",
144151
":openroad_version",
145-
"//:ord",
152+
":ord",
146153
"//src/cut",
147154
"//src/gui",
148155
"//src/sta:opensta_lib",
149156
"//src/utl",
150157
"@boost.stacktrace",
151158
"@rules_cc//cc/runfiles",
152159
"@tk_tcl//:tcl",
160+
"//bazel:runfiles",
153161
],
154162
)
155163

@@ -262,6 +270,94 @@ tcl_wrap_cc(
262270
],
263271
)
264272

273+
274+
# This target compiles the SWIG C++ wrapper into a shared library (.so)
275+
# that Python can load dynamically.
276+
cc_binary(
277+
name = "_openroadpy.so",
278+
srcs = [":openroad_swig-py"],
279+
linkshared = True,
280+
deps = [
281+
":openroad_lib", # Depends on the core odb C++ library
282+
":ord",
283+
"//src/odb",
284+
"//src/ifp",
285+
"//src/utl",
286+
"//src/gpl",
287+
"//src/ant",
288+
"//src/cts",
289+
"//src/dpl",
290+
"//src/drt",
291+
"//src/exa",
292+
"//src/fin",
293+
"//src/grt",
294+
"//src/par",
295+
"//src/pdn",
296+
"//src/ppl",
297+
"//src/psm",
298+
"//src/rcx",
299+
"//src/stt",
300+
"//src/gui",
301+
"//src/tap",
302+
"@boost.stacktrace",
303+
"@openroad_rules_python//python/cc:current_py_cc_headers",
304+
],
305+
defines = [PYTHON_STABLE_API_DEFINE],
306+
)
307+
308+
# This packages the SWIG-generated Python wrapper (odb.py) and the
309+
# compiled C++ extension (_odb.so) together.
310+
py_library(
311+
name = "ord_py",
312+
srcs = [":openroad_swig-py"], # Use the .py output from the swig-py rule
313+
# The data attribute makes the .so file available at runtime.
314+
data = [":_openroadpy.so"],
315+
deps = [
316+
"//src/utl:utl_py",
317+
"//src/odb:odb_py",
318+
],
319+
# This allows imports relative to the workspace root.
320+
imports = ["."],
321+
visibility = ["//visibility:public",]
322+
)
323+
324+
python_wrap_cc(
325+
name = "openroad_swig-py",
326+
srcs = [
327+
"src/OpenRoad-py.i",
328+
":error_swig-py",
329+
"include/ord/Tech.h",
330+
"include/ord/Design.h",
331+
"include/ord/Timing.h",
332+
],
333+
module = "openroadpy",
334+
root_swig_src = "src/OpenRoad-py.i",
335+
swig_includes = [
336+
"include",
337+
"src",
338+
],
339+
deps = [
340+
"//src/gpl:swig-py",
341+
"//src/ifp:swig-py",
342+
"//src/ant:swig-py",
343+
"//src/cts:swig-py",
344+
"//src/dpl:swig-py",
345+
"//src/drt:swig-py",
346+
"//src/exa:swig-py",
347+
"//src/fin:swig-py",
348+
"//src/grt:swig-py",
349+
"//src/par:swig-py",
350+
"//src/pdn:swig-py",
351+
"//src/ppl:swig-py",
352+
"//src/psm:swig-py",
353+
"//src/rcx:swig-py",
354+
"//src/stt:swig-py",
355+
"//src/tap:swig-py",
356+
"//src/odb:swig-py",
357+
"//src/utl:swig-py",
358+
]
359+
)
360+
265361
filegroup(
266362
name = "error_swig",
267363
srcs = [
@@ -270,9 +366,17 @@ filegroup(
270366
visibility = ["@//:__subpackages__"],
271367
)
272368

369+
filegroup(
370+
name = "error_swig-py",
371+
srcs = [
372+
"src/Exception-py.i",
373+
],
374+
visibility = ["@//:__subpackages__"],
375+
)
376+
273377
filegroup(
274378
name = "design_swig",
275379
srcs = [
276380
"src/Design.i",
277381
],
278-
)
382+
)

MODULE.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ python.toolchain(
138138
ignore_root_user_error = True,
139139
python_version = "3.13",
140140
)
141+
use_repo(python, "python_3_13")
141142

142143
pip = use_extension("@openroad_rules_python//python/extensions:pip.bzl", "pip")
143144
pip.parse(

bazel/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ cc_library(
1616
deps = [
1717
"@rules_cc//cc/runfiles",
1818
],
19+
alwayslink = True,
1920
)

bazel/InitRunFiles.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
#include <optional>
77
#include <string>
88

9+
#if defined(__APPLE__)
10+
#include <mach-o/dyld.h>
11+
#include <sys/param.h>
12+
#endif
13+
914
#include "rules_cc/cc/runfiles/runfiles.h"
1015

1116
// Avoid adding any dependencies like boost.filesystem
@@ -19,7 +24,7 @@ static std::optional<std::string> getProgramLocation()
1924
char result[MAXPATHLEN + 1] = {'\0'};
2025
uint32_t path_len = MAXPATHLEN;
2126
if (_NSGetExecutablePath(result, &path_len) != 0) {
22-
path_len = readlink("/proc/self/exe", result, MAXPATHLEN);
27+
path_len = readlink(result, result, MAXPATHLEN);
2328
}
2429
#else
2530
char result[PATH_MAX + 1] = {'\0'};
@@ -50,9 +55,9 @@ class BazelInitializer
5055
}
5156

5257
// Set the TCL_LIBRARY environment variable
53-
std::string path = runfiles->Rlocation("tk_tcl/library/");
54-
if (!path.empty()) {
55-
setenv("TCL_LIBRARY", path.c_str(), 0);
58+
const std::string tcl_path = runfiles->Rlocation("tk_tcl/library/");
59+
if (!tcl_path.empty()) {
60+
setenv("TCL_LIBRARY", tcl_path.c_str(), 0);
5661
} else {
5762
std::cerr << "Error: Could not locate 'tk_tcl/library/' in runfiles."
5863
<< std::endl;

bazel/python_wrap_cc.bzl

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
# Copyright (c) 2025-2025, The OpenROAD Authors
3+
4+
"""A Python SWIG wrapping rule
5+
6+
These rules generate a C++ src file that is expected to be used as srcs in
7+
cc_library or cc_binary rules. See below for expected usage.
8+
cc_library(srcs=[":python_foo"])
9+
python_wrap_cc(name = "python_foo", srcs=["exception.i"],...)
10+
"""
11+
PythonSwigInfo = provider(
12+
"PythonSwigInfo for taking dependencies on other swig info rules",
13+
fields = [
14+
"transitive_srcs",
15+
"includes",
16+
"swig_options",
17+
],
18+
)
19+
20+
PYTHON_STABLE_API_DEFINE = "Py_LIMITED_API=0x030A0000"
21+
22+
def _get_transitive_srcs(srcs, deps):
23+
return depset(
24+
srcs,
25+
transitive = [dep[PythonSwigInfo].transitive_srcs for dep in deps],
26+
)
27+
28+
def _get_transitive_includes(local_includes, deps):
29+
return depset(
30+
local_includes,
31+
transitive = [dep[PythonSwigInfo].includes for dep in deps],
32+
)
33+
34+
def _get_transitive_options(options, deps):
35+
return depset(
36+
options,
37+
transitive = [dep[PythonSwigInfo].swig_options for dep in deps],
38+
)
39+
40+
def _python_wrap_cc_impl(ctx):
41+
"""Generates a single C++ file from the provided srcs in a DefaultInfo."""
42+
if len(ctx.files.srcs) > 1 and not ctx.attr.root_swig_src:
43+
fail("If multiple src files are provided, root_swig_src must be specified.")
44+
45+
root_file = ctx.file.root_swig_src or ctx.files.srcs[0]
46+
47+
cc_outfile_name = ctx.attr.out or (ctx.attr.name + ".cc")
48+
cc_output_file = ctx.actions.declare_file(cc_outfile_name)
49+
py_outfile_name = ctx.attr.module + ".py"
50+
py_output_file = ctx.actions.declare_file(py_outfile_name)
51+
52+
include_root_directory = ""
53+
if ctx.label.package:
54+
include_root_directory = ctx.label.package + "/"
55+
56+
src_inputs = _get_transitive_srcs(ctx.files.srcs + ctx.files.root_swig_src, ctx.attr.deps)
57+
includes_paths = _get_transitive_includes(
58+
["{}{}".format(include_root_directory, include) for include in ctx.attr.swig_includes],
59+
ctx.attr.deps,
60+
)
61+
swig_options = _get_transitive_options(ctx.attr.swig_options, ctx.attr.deps)
62+
63+
args = ctx.actions.args()
64+
args.add("-DBAZEL=1")
65+
args.add("-python")
66+
args.add("-c++")
67+
args.add("-flatstaticmethod")
68+
args.add("-module")
69+
args.add(ctx.attr.module)
70+
args.add_all(swig_options.to_list())
71+
args.add_all(includes_paths.to_list(), format_each = "-I%s")
72+
args.add("-o")
73+
args.add(cc_output_file.path)
74+
args.add(root_file.path)
75+
76+
ctx.actions.run(
77+
outputs = [cc_output_file, py_output_file],
78+
inputs = src_inputs,
79+
arguments = [args],
80+
tools = ctx.files._swig,
81+
executable = ([file for file in ctx.files._swig if file.basename == "swig"][0]),
82+
)
83+
return [
84+
DefaultInfo(files = depset([cc_output_file, py_output_file])),
85+
PythonSwigInfo(
86+
transitive_srcs = src_inputs,
87+
includes = includes_paths,
88+
swig_options = swig_options,
89+
),
90+
]
91+
92+
python_wrap_cc = rule(
93+
implementation = _python_wrap_cc_impl,
94+
attrs = {
95+
"deps": attr.label_list(
96+
allow_empty = True,
97+
doc = "python_wrap_cc dependencies",
98+
providers = [PythonSwigInfo],
99+
),
100+
"module": attr.string(
101+
mandatory = True,
102+
doc = "swig module",
103+
),
104+
"out": attr.string(
105+
doc = "The name of the C++ source file generated by these rules. If not set, defaults to '<name>.cc'.",
106+
),
107+
"root_swig_src": attr.label(
108+
allow_single_file = [".swig", ".i"],
109+
doc = """If more than one swig file is included in this rule.
110+
The root file must be explicitly provided. This is the file which will be passed to
111+
swig for generation.""",
112+
),
113+
"srcs": attr.label_list(
114+
allow_empty = False,
115+
allow_files = [".i", ".swig", ".h", ".hpp", ".hh"],
116+
doc = "Swig files that generate C++ files",
117+
),
118+
"swig_includes": attr.string_list(
119+
doc = "List of directories relative to the BUILD file to append as -I flags to SWIG",
120+
),
121+
"swig_options": attr.string_list(
122+
doc = "args to pass directly to the swig binary",
123+
),
124+
"_swig": attr.label(
125+
default = "@org_swig//:swig_stable",
126+
allow_files = True,
127+
cfg = "exec",
128+
),
129+
},
130+
)

bazel/tcl_encode_or.bzl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,15 @@ def _tcl_encode_or_impl(ctx):
1919
args.add("--varname", ctx.attr.char_array_name)
2020
args.add("--namespace", ctx.attr.namespace)
2121

22+
# Only keep .tcl and .py files.
23+
allowed_extensions = (".tcl", ".py")
24+
filtered_sources = [
25+
f for f in ctx.files.srcs if f.basename.endswith(allowed_extensions)
26+
]
27+
2228
ctx.actions.run(
2329
outputs = [output_file],
24-
inputs = ctx.files.srcs,
30+
inputs = filtered_sources,
2531
arguments = [args],
2632
tools = [ctx.executable._encode_script],
2733
executable = ctx.toolchains["@rules_python//python:toolchain_type"].py3_runtime.interpreter,
@@ -44,7 +50,7 @@ tcl_encode = rule(
4450
),
4551
"srcs": attr.label_list(
4652
allow_empty = False,
47-
allow_files = [".tcl"],
53+
allow_files = [".tcl", ".py"],
4854
doc = "Files to be wrapped.",
4955
),
5056
"_encode_script": attr.label(

0 commit comments

Comments
 (0)