Skip to content

Fix a bug of $ROOT path when using path dependency - #348

Open
DiyouS wants to merge 1 commit into
masterfrom
fix/root_path
Open

Fix a bug of $ROOT path when using path dependency#348
DiyouS wants to merge 1 commit into
masterfrom
fix/root_path

Conversation

@DiyouS

@DiyouS DiyouS commented Aug 10, 2026

Copy link
Copy Markdown

Fix $ROOT variable collision in generated build scripts

(vsim/vcs/riviera/synopsys/genus/formality/vivado)

Problem

bender script <fmt> emits generated build scripts (Tcl for
vsim/riviera/synopsys/genus/formality/vivado, shell for vcs) that shorten
absolute source paths by replacing the invoking package's root directory
with a script variable, e.g. $ROOT. When a dependency is a path-type
dependency that resolves outside the invoking package's own directory tree
(e.g. { path: "../some_sibling_pkg" }), and that sibling directory's name
happens to share the root directory's name as a prefix (e.g. root is
.../foo, sibling is .../foo_bar), the generated variable reference
silently corrupts:

set ROOT "/path/to/foo"
...
vlog ... "$ROOT_bar/src/some_file.sv" \

Both Tcl and POSIX shell parse $ROOT_bar as a reference to a variable
named ROOT_bar, not $ROOT followed by literal _bar. Since ROOT_bar
is never defined, this raises an "undefined variable" error. Because every
vlog/vcom invocation in these templates is wrapped in if {[catch { ... }]} {return 1} (or the shell equivalent), the error is swallowed and the
entire script silently aborts at that point — no error is printed, and
everything after it (including the dependency's own sources) is never
compiled. The only visible symptom is that compilation output stops partway
through with no error message.

Root cause

The templates build these paths with Tera's replace filter:

{{ file.file | replace(from=root, to='$ROOT') }}

replace performs a plain substring replacement (like Rust's
str::replace), with no awareness of path boundaries. If root (e.g.
/scratch/.../foo) occurs as a literal prefix substring of a longer,
unrelated path (e.g. /scratch/.../foo_bar/src/x.sv), it gets replaced
anyway, and the leftover suffix (_bar/src/x.sv) is concatenated directly
onto $ROOT with no boundary — producing $ROOT_bar/src/x.sv. Both Tcl and
shell greedily consume [A-Za-z0-9_] characters after an unbraced $ when
resolving a variable reference, so $ROOT_bar is read as one identifier,
not $ROOT + literal text.

Fix

Use the braced form ${ROOT} instead of the bare $ROOT wherever it's
emitted into generated scripts. ${ROOT} is valid, standard syntax in both
Tcl and POSIX shell for explicitly delimiting a variable name, and correctly
disambiguates ${ROOT}_bar as "value of ROOT" + literal _bar, matching
the intended behavior in all cases (including the common case where no
collision occurs).

Applied to every to='$ROOT' occurrence, and the two literal "$ROOT{{ ... }}" occurrences in genus_tcl.tera/formality_tcl.tera, across:

  • vsim_tcl.tera
  • vcs_sh.tera
  • riviera_tcl.tera
  • synopsys_tcl.tera
  • genus_tcl.tera
  • formality_tcl.tera
  • vivado_tcl.tera

(verilator_sh.tera, flist.tera, flist-plus.tera, and
precision_tcl.tera don't use this substitution pattern and are
unaffected.)

Repro

  • Package foo (root) has a path dependency { path: "../foo_bar" } (or
    any sibling directory whose name is prefixed by the root directory's own
    name).
  • bender script vsim (or vcs/riviera/synopsys/genus/formality/vivado)
    emits a source block for files under foo_bar referencing $ROOT_bar/...,
    which is undefined.
  • Running the generated script compiles everything up to that point with no
    reported error, then silently stops.

@DiyouS

DiyouS commented Aug 10, 2026

Copy link
Copy Markdown
Author

The CI failed because we added a { } pair guarding ROOT, which causes mismatch comapred with main

@DiyouS
DiyouS marked this pull request as ready for review August 10, 2026 12:01
@DiyouS
DiyouS requested a review from micprog August 10, 2026 12:01
@DiyouS DiyouS self-assigned this Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant