ubx compile --all discovers every stack in the workspace, resolves the dependency order from @name cross-stack references, and compiles each stack in sequence.
Directory layout
Flat workspace
The simplest layout is a flat directory with one subdirectory per stack:Nested workspace
Stacks can be at any depth. Every directory containing.xcl files is treated as an independent stack:
Cross-stack references
Use@stackName.outputName to reference an output from another stack:
@name is the directory basename of the dependency.
Sibling discovery rule
When the compiler encounters@networking, it looks for the networking stack at:
cluster/ and networking/ are siblings, this resolves correctly:
cluster/→ parent isworkspace/→ looks forworkspace/networking/✓
infra/cluster/→ parent isinfra/→ looks forinfra/networking/✓apps/addons/→ parent isapps/→ looks forapps/gitops/✓
apps/addons stack cannot reference @networking from infra/networking — the compiler would look for apps/networking/ which doesn’t exist.
Compiling a workspace
Dependency resolution
The compiler builds a dependency graph by:- Parsing each stack’s
.xclfiles (lex + parse — no typechecking yet) - Scanning for
@namecross-stack references using the parsed AST - Building an adjacency map: stack → [dependent stacks]
- Topological sort (DFS-based) to determine compilation order
Circular dependency detection
If stacks reference each other in a cycle, the compiler reports a clear error and aborts:Duplicate stack names
Two stacks in different subdirectories cannot have the same directory name — this would make@name references ambiguous:

