Skip to content

Commit b23706a

Browse files
authored
Merge pull request #4234 from oharboe/klayout-sandbox-abspath
flow/util/generate_klayout_tech: write absolute LEF paths for Bazel sandbox
2 parents 5c27245 + 2d3d7e9 commit b23706a

3 files changed

Lines changed: 24 additions & 45 deletions

File tree

flow/Makefile

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,6 @@ do-klayout:
200200
--template $(KLAYOUT_TECH_FILE) \
201201
--output $(OBJECTS_DIR)/klayout.lyt \
202202
--lef-files $(OBJECTS_DIR)/klayout_tech.lef $(SC_LEF) $(ADDITIONAL_LEFS) \
203-
--reference-dir $(RESULTS_DIR) \
204203
--map-files $(wildcard $(FLOW_HOME)/platforms/$(PLATFORM)/*map)
205204

206205
$(OBJECTS_DIR)/klayout_wrap.lyt: $(KLAYOUT_TECH_FILE) $(OBJECTS_DIR)/klayout_tech.lef
@@ -212,8 +211,7 @@ do-klayout_wrap:
212211
$(PYTHON_EXE) $(UTILS_DIR)/generate_klayout_tech.py \
213212
--template $(KLAYOUT_TECH_FILE) \
214213
--output $(OBJECTS_DIR)/klayout_wrap.lyt \
215-
--lef-files $(OBJECTS_DIR)/klayout_tech.lef $(WRAP_LEFS) \
216-
--reference-dir $(OBJECTS_DIR)/def
214+
--lef-files $(OBJECTS_DIR)/klayout_tech.lef $(WRAP_LEFS)
217215

218216
$(WRAPPED_LEFS):
219217
mkdir -p $(OBJECTS_DIR)/lef $(OBJECTS_DIR)/def

flow/test/test_generate_klayout_tech.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -120,22 +120,21 @@ def test_basic_generation(self):
120120
template_lyt=self.template,
121121
output_lyt=self.output,
122122
lef_files=[lef_path],
123-
reference_dir=self.results_dir,
124123
map_files=[],
125-
use_relative_paths=True,
126124
)
127125

128126
with open(self.output) as f:
129127
content = f.read()
130128

131129
self.assertIn("<lef-files>", content)
132130
self.assertNotIn("original.lef", content)
133-
# Path should be relative to results_dir
134-
expected_rel = os.path.relpath(
135-
os.path.realpath(lef_path),
136-
os.path.realpath(self.results_dir),
137-
)
138-
self.assertIn(expected_rel, content)
131+
# LEF paths are written as plain abspath (not relpath, not realpath):
132+
# klayout's Layout.read resolves relative <lef-files> entries
133+
# against the realpath of the DEF being merged, which under a
134+
# Bazel sandbox is the bare execroot -- the in-flight sibling
135+
# files only exist in the per-action sandbox. Absolute paths
136+
# bypass the relative-resolution dance.
137+
self.assertIn(os.path.abspath(lef_path), content)
139138

140139
def test_with_map_files(self):
141140
with open(self.template, "w") as f:
@@ -151,15 +150,16 @@ def test_with_map_files(self):
151150
template_lyt=self.template,
152151
output_lyt=self.output,
153152
lef_files=[lef_path],
154-
reference_dir=self.results_dir,
155153
map_files=[map_path],
156-
use_relative_paths=False,
157154
)
158155

159156
with open(self.output) as f:
160157
content = f.read()
161158

162-
self.assertIn(os.path.realpath(map_path), content)
159+
# Same abspath semantics as LEFs: map files are also written as
160+
# plain absolute paths so klayout doesn't resolve them relative
161+
# to the bare-execroot realpath of the input DEF.
162+
self.assertIn(os.path.abspath(map_path), content)
163163
self.assertNotIn("original.map", content)
164164

165165
def test_multiple_lef_files(self):
@@ -177,9 +177,7 @@ def test_multiple_lef_files(self):
177177
template_lyt=self.template,
178178
output_lyt=self.output,
179179
lef_files=lef_files,
180-
reference_dir=self.results_dir,
181180
map_files=[],
182-
use_relative_paths=True,
183181
)
184182

185183
with open(self.output) as f:

flow/util/generate_klayout_tech.py

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -30,37 +30,32 @@ def replace_map_files(content, map_files):
3030
return content
3131

3232

33-
def generate_klayout_tech(
34-
template_lyt,
35-
output_lyt,
36-
lef_files,
37-
reference_dir,
38-
map_files,
39-
use_relative_paths,
40-
):
33+
def generate_klayout_tech(template_lyt, output_lyt, lef_files, map_files=None):
4134
"""Generate a klayout .lyt file from a platform template.
4235
4336
Args:
4437
template_lyt: Path to the platform .lyt template file.
4538
output_lyt: Path to write the generated .lyt file.
4639
lef_files: List of LEF file paths to include.
47-
reference_dir: Directory to compute relative paths from.
4840
map_files: List of map file paths.
49-
use_relative_paths: If True, compute paths relative to reference_dir.
5041
"""
5142
with open(template_lyt, "r") as f:
5243
content = f.read()
5344

54-
# Both modes use relative paths from reference_dir, matching the
55-
# original sed-based behavior which always uses realpath --relative-to.
56-
resolved_lefs = [
57-
os.path.relpath(os.path.realpath(f), os.path.realpath(reference_dir))
58-
for f in lef_files
59-
]
45+
# Write absolute (not relative, not realpath'd) LEF paths into the LYT.
46+
# Klayout's Layout.read(def, layout_options) follows the symlinked input
47+
# DEF to its realpath at the bare execroot and resolves relative
48+
# <lef-files> entries from there. Sibling intermediates like
49+
# objects/klayout_tech.lef don't exist at the bare execroot during
50+
# action execution -- they're only at the per-action sandbox -- so
51+
# resolution fails with errno=2. Plain abspath (NOT realpath, which
52+
# would chase Bazel input-file symlinks back out to the bare execroot)
53+
# keeps klayout pointed at the in-sandbox file.
54+
resolved_lefs = [os.path.abspath(f) for f in lef_files]
6055

6156
content = replace_lef_files(content, resolved_lefs)
6257

63-
resolved_maps = [os.path.realpath(f) for f in map_files]
58+
resolved_maps = [os.path.abspath(f) for f in (map_files or [])]
6459
content = replace_map_files(content, resolved_maps)
6560

6661
with open(output_lyt, "w") as f:
@@ -78,28 +73,16 @@ def main():
7873
parser.add_argument(
7974
"--lef-files", nargs="*", default=[], help="LEF files to include"
8075
)
81-
parser.add_argument(
82-
"--reference-dir",
83-
required=True,
84-
help="Directory for computing relative paths",
85-
)
8676
parser.add_argument(
8777
"--map-files", nargs="*", default=[], help="Map files to include"
8878
)
89-
parser.add_argument(
90-
"--use-relative-paths",
91-
action="store_true",
92-
help="Use paths relative to reference-dir",
93-
)
9479
args = parser.parse_args()
9580

9681
generate_klayout_tech(
9782
template_lyt=args.template,
9883
output_lyt=args.output,
9984
lef_files=args.lef_files,
100-
reference_dir=args.reference_dir,
10185
map_files=args.map_files,
102-
use_relative_paths=args.use_relative_paths,
10386
)
10487

10588

0 commit comments

Comments
 (0)