Skip to content

Commit 4843503

Browse files
committed
feat: expose a build's options to the run step as {build_opts_file}
A run step that compiles for itself instead of loading the build's snapshot has to compile the way the build did. Every build now records its options in build_opts.f, named by the hjson as {build_opts_file}. Signed-off-by: Martin Velay <mvelay@lowrisc.org>
1 parent ecb7bb1 commit 4843503

3 files changed

Lines changed: 51 additions & 0 deletions

File tree

src/dvsim/job/deploy.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
"Deploy",
3737
)
3838

39+
# Name of the file that records the options a build used. It sits in the build directory, and
40+
# SimCfg turns it into the {build_opts_file} substitution variable the HJson can name.
41+
BUILD_OPTS_FILE_NAME = "build_opts.f"
42+
3943

4044
class Deploy:
4145
"""Abstraction to create and maintain a runnable job (builds, runs, etc.)."""
@@ -431,6 +435,7 @@ def __init__(self, build_mode: "BuildMode", sim_cfg: "SimCfg") -> None:
431435
self.build_cmd: str = ""
432436
self.build_dir: str = ""
433437
self.build_opts: list[str] = []
438+
self.build_opts_file: str = ""
434439
self.post_build_cmds: list[str] = []
435440
self.build_fail_patterns: list[str] = []
436441
self.build_pass_patterns: list[str] = []
@@ -485,6 +490,7 @@ def _define_attrs(self) -> None:
485490
self.mandatory_misc_attrs.update(
486491
{
487492
"build_fail_patterns": False,
493+
"build_opts_file": False,
488494
"build_pass_patterns": False,
489495
"build_timeout_mins": False,
490496
"cov_db_dir": False,
@@ -509,6 +515,23 @@ def _set_attrs(self) -> None:
509515
if self.sim_cfg.args.build_timeout_mins is not None:
510516
self.build_timeout_mins = self.sim_cfg.args.build_timeout_mins
511517

518+
def _write_build_opts_file(self) -> None:
519+
"""Record the options this build used, in the build directory.
520+
521+
A run step that compiles and elaborates for itself, rather than loading the snapshot the
522+
build produced, has to compile the way the build did: build modes and individual cfgs each
523+
add their own defines, include paths and libraries, and a run compiled with a different set
524+
would simulate a differently configured design. The merged option list exists only here, so
525+
it is written out in a form the tools accept as an option file, for the run step to read
526+
back with {build_opts_file}.
527+
"""
528+
opts_file = Path(self.build_opts_file)
529+
opts_file.parent.mkdir(parents=True, exist_ok=True)
530+
opts_file.write_text(
531+
"".join(f"{opt.strip()}\n" for opt in self.build_opts if opt.strip()),
532+
encoding="UTF-8",
533+
)
534+
512535
def pre_launch(self) -> Callable[[], None]:
513536
"""Get pre-launch callback."""
514537

@@ -518,6 +541,8 @@ def callback() -> None:
518541
# need to do this because the build directory is not 'renewed'.
519542
rm_path(Path(self.cov_db_dir))
520543

544+
self._write_build_opts_file()
545+
521546
return callback
522547

523548
def get_timeout_mins(self) -> float:

src/dvsim/sim/flow.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from dvsim.flow.base import FlowCfg
1818
from dvsim.job.data import CompletedJobStatus, JobSpec
1919
from dvsim.job.deploy import (
20+
BUILD_OPTS_FILE_NAME,
2021
CompileSim,
2122
CovAnalyze,
2223
CovMerge,
@@ -200,6 +201,11 @@ def _expand(self) -> None:
200201
if self.args.verbosity is not None:
201202
self.verbosity = self.args.verbosity
202203

204+
# Where each build records the options it compiled with, for a run step that compiles for
205+
# itself rather than loading the snapshot the build produced, see
206+
# CompileSim._write_build_opts_file().
207+
self.build_opts_file = "{build_dir}/" + BUILD_OPTS_FILE_NAME
208+
203209
super()._expand()
204210

205211
if self.variant:

tests/job/test_deploy.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"""Test Job deployment models."""
66

77
from collections.abc import Mapping
8+
from pathlib import Path
89

910
import pytest
1011
from hamcrest import assert_that, equal_to
@@ -48,6 +49,7 @@ def __init__(self) -> None:
4849
self.pre_build_cmds = ["A", "B"]
4950
self.post_build_cmds = ["C", "D"]
5051
self.build_dir = "build/dir"
52+
self.build_opts_file = "{build_dir}/build_opts.f"
5153
self.build_pass_patterns = None
5254
self.build_fail_patterns = None
5355
self.build_seed = 123
@@ -202,6 +204,24 @@ def test_seed(
202204

203205
assert_that(job.seed, equal_to(seed))
204206

207+
@staticmethod
208+
def test_build_opts_file(tmp_path: Path) -> None:
209+
"""Test that a CompileSim records the options it built with, for the run step."""
210+
build_dir = tmp_path / "build" / "dir"
211+
job = _build_compile_sim(
212+
sim_overrides={"build_dir": str(build_dir), "cov_db_dir": str(tmp_path / "cov")},
213+
)
214+
215+
assert_that(job.build_opts_file, equal_to(str(build_dir / "build_opts.f")))
216+
217+
# The build directory does not exist until the build job launches.
218+
job.pre_launch()()
219+
220+
assert_that(
221+
Path(job.build_opts_file).read_text(encoding="UTF-8"),
222+
equal_to('-b path/here\n-a "Quoted"\n'),
223+
)
224+
205225
@staticmethod
206226
@pytest.mark.parametrize(
207227
("cli_args_overrides", "build_overrides", "timeout"),

0 commit comments

Comments
 (0)