build: make executable and test roots package actions
This commit is contained in:
@@ -2810,15 +2810,16 @@ the final component of its import path; two logical identities for one physical
|
||||
directory are rejected rather than compiled twice.
|
||||
|
||||
Packages compile serially in dependency-first postorder. The compiler emits the
|
||||
existing deterministic `.wwi` interface for every importable package. Its
|
||||
primary section contains that package's byte-sorted direct imports and exported
|
||||
declarations. The compiler then appends byte-sorted, origin-tagged sections for
|
||||
only the exported foreign type and constant facts recursively reachable from
|
||||
the primary public signatures. This makes each direct dependency interface
|
||||
self-contained for the public type information its consumers need while
|
||||
retaining the deeper declarations' original package identity. Checked fixed
|
||||
array dimensions are emitted as numeric type facts, so a public layout never
|
||||
requires exposing the private constant spelling that produced its length.
|
||||
existing deterministic `.wwi` interface for every directory-package action,
|
||||
including an executable root. Its primary section contains that package's
|
||||
byte-sorted direct imports and exported declarations. The compiler then appends
|
||||
byte-sorted, origin-tagged sections for only the foreign type and constant facts
|
||||
recursively reachable from the primary public signatures. Reachable owner-local
|
||||
private nominal types are carried without `export`: they make the export
|
||||
self-contained for type checking, but qualified source lookup still rejects
|
||||
their names. Checked fixed array dimensions are emitted as numeric type facts,
|
||||
so a public layout never requires exposing the private constant spelling that
|
||||
produced its length.
|
||||
|
||||
A package compilation unit contains only that package's own byte-sorted sources
|
||||
and deterministic `//ww:module-reset` separators. Each **direct** import is a
|
||||
@@ -2835,19 +2836,25 @@ source-like `.wwi` syntax remains a transitional export encoding pending the
|
||||
binary `.wwe` format described above, but the separate direct-input ownership
|
||||
boundary is live in production Cstage and WWstage compilers and drivers.
|
||||
|
||||
An ordinary root is linked with the full reachable object closure into the
|
||||
requested executable (legacy WW programs may use a package name other than
|
||||
`main`). `ww build -p -o lib.a DIR` explicitly requests a non-main package
|
||||
product: it emits a deterministic archive at `lib.a` and its compiler interface
|
||||
at `lib.a.wwi`, without invoking the linker. A logical target retains its full
|
||||
An ordinary executable directory root is one normal package action. Its
|
||||
declared package identity tags its owner-only unit; it receives only direct
|
||||
exports, emits `.wwi`, `.o`, and a deterministic `.a`, and is compiled exactly
|
||||
once. The narrow compiler `--entry` flag controls only bare `main` codegen and is
|
||||
independent of export production. The linker receives that root archive first,
|
||||
then the complete reachable package-archive closure and runtime archive; it
|
||||
never receives `.wwi`. The linkers seed `main` before archive selection, so the
|
||||
existing WWAR member protocol needs no special root object or format change.
|
||||
|
||||
`ww build -p -o lib.a DIR` explicitly requests a non-main package product: it
|
||||
emits a deterministic archive at `lib.a` and its compiler interface at
|
||||
`lib.a.wwi`, without invoking the linker. A logical target retains its full
|
||||
identity (`ww build -p -I ROOT -o bar.a foo.bar` emits `foo.bar.*` symbols),
|
||||
while a literal directory uses its declared leaf package. Package output
|
||||
requires a directory and `-p` cannot be combined with assembly-only `-S`. Two
|
||||
cold builds with identical inputs are required to produce byte-identical
|
||||
requested products. Compiler intrinsics keep their package-mode runtime ABI
|
||||
independent of transitive source interfaces (for example, `alloc` lowers to the
|
||||
runtime allocator without requiring an `rt.wwi` compiler input), while the
|
||||
linker still receives every reachable package archive plus the runtime archive.
|
||||
runtime allocator without requiring an `rt.wwi` compiler input).
|
||||
|
||||
### 11.7 Implemented directory package-test slice
|
||||
|
||||
@@ -2868,11 +2875,14 @@ semantic selections are only the directory and selected variant/package
|
||||
identities; it also carries output destinations, coordinator-private completion
|
||||
paths, import search roots, and the optional command-scoped work-directory
|
||||
policy. The command owns source selection, package loading, compiler inputs,
|
||||
archive construction, and linking for every non-importable root:
|
||||
archive construction, generated-main construction, and linking for every
|
||||
package variant:
|
||||
|
||||
- `same-test` selects the byte-sorted production files followed by the
|
||||
byte-sorted matching `package p` test files. They form one compiler unit, so
|
||||
tests can use private production declarations.
|
||||
- The ordinary production action selects the directory's byte-sorted
|
||||
non-test files and is reused wherever that canonical package is imported.
|
||||
- `same-test` is a distinct internal production-plus-test action. It selects
|
||||
the byte-sorted production files followed by the byte-sorted matching
|
||||
`package p` test files, so tests can use private production declarations.
|
||||
- `external-test` selects only matching `package p_test` files. Its `import p`
|
||||
is a direct edge to the canonical production action for that directory.
|
||||
That action compiles with module qualifier `p`, selects every production
|
||||
@@ -2882,17 +2892,23 @@ archive construction, and linking for every non-importable root:
|
||||
owning root, such as `__ww-test-001-external-production`; a normal import of
|
||||
the same `p` and canonical directory reuses that action rather than creating
|
||||
a second compilation.
|
||||
- Each selected internal or external variant gets a distinct generated-main
|
||||
package action. Its generated owner-only unit declares `package main` and
|
||||
imports exactly the selected variant and test-support package. It consumes
|
||||
exactly those direct `.wwi` artifacts, emits its own `.wwi/.o/.a`, and alone
|
||||
receives compiler `-T --entry`.
|
||||
|
||||
The command loads all roots into one command-scoped package universe. Each root
|
||||
retains an injective artifact key derived from its deterministic request ordinal
|
||||
and variant, such as `__ww-test-000-same` or
|
||||
`__ww-test-003-external`. Hyphens make that namespace illegal as a WW import
|
||||
identity. Imports of the same canonical production directory intern to one
|
||||
production node across every selected test directory. A deterministic
|
||||
dependency-first traversal of the complete union therefore invokes the
|
||||
compiler and archiver once for every reachable canonical production package,
|
||||
even when many directory products need it. Each root is still compiled once
|
||||
with its own selected sources and linked separately. The shared plan is
|
||||
The command loads all variants into one command-scoped package universe.
|
||||
Directory variants retain injective artifact keys such as
|
||||
`__ww-test-000-same` or `__ww-test-003-external`; their generated mains use
|
||||
matching `__ww-test-NNN-main` keys and distinct internal package identities.
|
||||
Hyphens keep artifact keys illegal as WW import identities. Repeated requests
|
||||
for the same canonical directory and variant reuse one compile action, and
|
||||
imports of the same canonical production directory intern to one production
|
||||
action across every selected test product. A deterministic dependency-first
|
||||
traversal of the complete union therefore invokes the compiler and archiver
|
||||
once per package variant, even when many products share it. Generated-main
|
||||
actions remain product-specific and are linked separately. The shared plan is
|
||||
deliberately package-test-specific: it is not a generalized scheduler, action
|
||||
schema, cache, or protocol.
|
||||
|
||||
@@ -2914,26 +2930,30 @@ missing product as a build failure. The single union build and completed test
|
||||
products share the coordinator's existing `-j` process bound; captured output
|
||||
is still emitted only in byte-sorted directory/package order.
|
||||
|
||||
Every non-root dependency is always a production variant, so dependency
|
||||
Every source-imported dependency is a production variant, so dependency
|
||||
`*_test.ww` files never enter the graph. Imports that occur only in selected
|
||||
test files add edges only to that test root. Each compiler unit contains only
|
||||
the variant's owned source set, while its invocation receives only the
|
||||
byte-sorted direct dependency `.wwi` artifacts as separate inputs. The final
|
||||
test link still receives the root object and the complete reverse-topological
|
||||
archive closure. The compiler-generated `-T` dispatcher owns the implicit
|
||||
direct test-runtime support edge and remains embedded in each independently
|
||||
compiled test root; it is the narrow test-main variant, not a
|
||||
coordinator-generated graph package. The command-scoped plan compiles the
|
||||
common runtime production package once for the complete test request. The
|
||||
command resolves that edge from the selected toolchain source tree, not the
|
||||
user search path; the support package's own imports are also loaded in that
|
||||
toolchain context. Normally its graph
|
||||
test files add edges only to that internal or external variant. Each compiler
|
||||
unit contains only its action's owned source set, while its invocation receives
|
||||
only the byte-sorted direct dependency `.wwi` artifacts as separate inputs.
|
||||
Variant compiles receive `--test-package`, which validates and retains private
|
||||
`@test` declarations as compiler-only export metadata without synthesizing an
|
||||
entry point. The distinct generated-main action consumes that metadata from its
|
||||
direct variant export and synthesizes the dispatcher with `-T`.
|
||||
|
||||
The generated-main action, rather than the tested variant, owns the implicit
|
||||
direct test-runtime support edge. The command-scoped plan compiles the common
|
||||
support production package once for the complete test request. The command
|
||||
resolves that edge from the selected toolchain source tree, not the user search
|
||||
path; the support package's own imports are also loaded in that toolchain
|
||||
context. Normally its graph
|
||||
qualifier is `test`, so an explicit source `import test` coalesces with the same
|
||||
canonical package. When a real user package occupies that identity, the command
|
||||
presents the runtime edge to the compiler under the reserved `__wwtest`
|
||||
qualifier. This keeps a production package named `test` available to external
|
||||
tests while preserving raw `w6c -T` compatibility, whose default unresolved
|
||||
qualifier remains `test`.
|
||||
tests. Explicit raw single-file `ww test FILE` fixtures retain the narrow fused
|
||||
`-T` compatibility path because an anonymous multi-package raw unit is not a
|
||||
canonical directory package; that path still consumes support as a direct
|
||||
export and emits a root `.wwi/.a`.
|
||||
|
||||
The reserved support action and an ordinary source-imported toolchain `test`
|
||||
action may coexist in the command universe because their compiler qualifiers
|
||||
@@ -2947,24 +2967,25 @@ only narrow action-role exceptions: each product closure is checked to contain
|
||||
at most one importable action for a compiler module qualifier, so unrelated
|
||||
roles can never introduce duplicate linked package symbols.
|
||||
|
||||
The selected test roots and a production variant reached by their imports or
|
||||
test-runtime closure are the only sanctioned graph nodes that may share a
|
||||
physical directory. This also lets a toolchain package's own tests coexist with
|
||||
the production variant required by the test runtime. A same-package root
|
||||
already defines those production symbols, so the production archive is omitted
|
||||
from that product's final link while the production node's dependency archives
|
||||
remain in its closure. A reserved compiler-support action at that same physical
|
||||
directory is still retained. The external product includes the production
|
||||
archive.
|
||||
Variant-only archives are never linked into the other product. All ordinary
|
||||
logical and physical package-identity collision checks remain unchanged.
|
||||
The Cstage linker, like the WWstage linker, passes the root object, every
|
||||
reachable archive, the runtime, and explicit `-L`/`-l` values through a
|
||||
structured argument vector; no fixed flattened command buffer can truncate a
|
||||
large closure. WWstage emits joined `-Ldir` and `-lname` arguments accepted by
|
||||
its native linker, while Cstage preserves the equivalent split forms. Generated
|
||||
artifact paths are bounds-checked before any unit is opened, so distinct root
|
||||
keys cannot alias by truncation.
|
||||
The selected internal/external variants and a production action reached by
|
||||
their imports or test-runtime closure are the sanctioned graph nodes that may
|
||||
share a physical directory. This also lets a toolchain package's own tests
|
||||
coexist with the production action required by the test runtime. An internal
|
||||
variant already defines those production symbols, so the colocated production
|
||||
archive is omitted from that product's final link while the production action's
|
||||
dependency archives remain in the closure. The external product includes the
|
||||
production archive. Variant-only archives are never linked into another
|
||||
product. All ordinary logical and physical package-identity collision checks
|
||||
remain unchanged.
|
||||
|
||||
Both stage linkers receive the generated-main archive first, followed by the
|
||||
complete reverse-topological reachable package-archive closure, runtime, and
|
||||
explicit `-L`/`-l` values through a structured argument vector. No `.wwi` or
|
||||
special root `.o` appears in linker argv, and no fixed flattened command buffer
|
||||
can truncate a large closure. WWstage emits joined `-Ldir` and `-lname`
|
||||
arguments accepted by its native linker, while Cstage preserves the equivalent
|
||||
split forms. Generated artifact paths are bounds-checked before any unit is
|
||||
opened, so distinct root keys cannot alias by truncation.
|
||||
Recursive discovery groups by physical directory before sorting filenames, and
|
||||
one stable escaped request key names the persistent command work directory.
|
||||
Every `*_test.ww` package variant is built even when a file only
|
||||
@@ -3021,7 +3042,7 @@ package, compiler actions receive direct dependency exports as individual
|
||||
arguments beside an owner-only `.unit.ww`, and links receive the complete
|
||||
per-root `.a` closure. Repository-native coverage wraps all three real stage
|
||||
tools at executable paths containing spaces, records every argument boundary,
|
||||
inspects `.unit.ww`, `.wwi`, `.a`, and root object placement, runs the published
|
||||
inspects `.unit.ww`, `.wwi`, `.a`, and root archive placement, runs the published
|
||||
binary, compares repeated Cstage/WWstage artifacts and traces, and removes one
|
||||
direct export at compiler entry to compare package-attributed diagnostics.
|
||||
|
||||
@@ -3198,22 +3219,26 @@ schema or identity record.
|
||||
The exact-argv regression uses the real diamond
|
||||
`base -> {left,right} -> root`. It proves one compile per node; no input for
|
||||
`base`; only `base.wwi` for each middle node; only sorted `left.wwi` and
|
||||
`right.wwi` for `root`; exact owner-only unit bytes; the complete three-archive
|
||||
link closure; no link-time `.wwi`; exit status 42; and byte-identical units,
|
||||
exports, archives, executables, and tool argument vectors across two clean
|
||||
`right.wwi` for `root`; exact owner-only unit bytes; the complete four-package
|
||||
link closure including the root archive; no link-time `.wwi`; exit status 42;
|
||||
and byte-identical units, exports, archives, executables, and tool argument
|
||||
vectors across two clean
|
||||
Cstage builds and two clean WWstage builds. The existing directory-package
|
||||
variant regression checks exact direct inputs for internal and external
|
||||
generated roots and the external-production action; both stages also compile
|
||||
and run ordinary production and support actions with owner-only units and
|
||||
byte-identical artifacts.
|
||||
variant regression checks separate production, internal, external, and
|
||||
generated-main actions, exact generated-main direct variant/support exports,
|
||||
the external-production action, and archive-only link closures. Both stages
|
||||
compile and run those actions with owner-only units and byte-identical
|
||||
artifacts.
|
||||
|
||||
The pinned Go 1.26.5 implementation supplies the design boundary:
|
||||
The pinned official Go 1.26.5 tag (commit
|
||||
`c19862e5f8415b4f24b189d065ed739517c548ba`) supplies the design boundary:
|
||||
|
||||
- Directory identity starts with `ImportDir`'s named directory
|
||||
([`go/build/build.go`, lines 521–524](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/go/build/build.go#521)); directory reads are name-sorted
|
||||
([lines 108–111](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/go/build/build.go#108)), lookup selects directory candidates
|
||||
([lines 725–809](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/go/build/build.go#725)), and the selected directory is enumerated
|
||||
([lines 859–900](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/go/build/build.go#859)).
|
||||
([lines 859–900](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/go/build/build.go#859)). The sorted iteration filters files and appends each source to exactly one ordinary/internal/external-test bucket
|
||||
([lines 895–1036](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/go/build/build.go#895)).
|
||||
- The loader records direct imports
|
||||
([`load/pkg.go`, lines 220–225](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/load/pkg.go#220)), guarantees repeated cache loads return the same package pointer
|
||||
([lines 633–636](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/load/pkg.go#633)), keys reuse by canonical import path
|
||||
@@ -3221,22 +3246,26 @@ The pinned Go 1.26.5 implementation supplies the design boundary:
|
||||
([lines 2776–2795](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/load/pkg.go#2776)).
|
||||
- Build actions are interned by mode and package identity
|
||||
([`work/action.go`, lines 437–447](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/action.go#437)); compilation depends only on direct imports
|
||||
([lines 628–659](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/action.go#628)), whereas link actions expand transitive dependencies
|
||||
([lines 628–659](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/action.go#628)), and even package `main` receives that normal interned archive-producing compile action
|
||||
([lines 641–647](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/action.go#641)). A link action places that main compile action at its first dependency and expands transitive dependencies
|
||||
([lines 918–957](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/action.go#918),
|
||||
[lines 1034–1068](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/action.go#1034)). The executor derives compiler import inputs from those direct actions
|
||||
([`work/exec.go`, lines 864–884](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/exec.go#864)), passes them separately from source files
|
||||
([lines 928–930](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/exec.go#928)), and separately emits the expanded linker closure
|
||||
([lines 1592–1647](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/exec.go#1592)).
|
||||
([lines 928–930](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/exec.go#928)), packs remaining objects into the package archive and records it as the built result
|
||||
([lines 1017–1033](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/exec.go#1017)), then supplies the root archive and all expanded package inputs to linking
|
||||
([lines 1592–1624](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/exec.go#1592),
|
||||
[lines 1635–1647](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/exec.go#1635)).
|
||||
- Tests preserve four package roles
|
||||
([`load/test.go`, lines 85–102](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/load/test.go#85)): internal production-plus-test
|
||||
([lines 175–225](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/load/test.go#175)), external test
|
||||
([lines 228–265](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/load/test.go#228)), and generated main
|
||||
([lines 272–293](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/load/test.go#272)), with their distinct imports attached at
|
||||
([lines 272–293](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/load/test.go#272)). Its support imports are loaded for that generated package
|
||||
([lines 307–332](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/load/test.go#307)), with the selected internal/external variants attached as distinct direct imports at
|
||||
[lines 351–373](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/load/test.go#351).
|
||||
- Unified export writing re-links, re-exports, and prunes facts
|
||||
([`noder/unified.go`, lines 152–165](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/compile/internal/noder/unified.go#152)), finalizes self-contained data
|
||||
([lines 463–470](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/compile/internal/noder/unified.go#463)), and sorts declarations and bodies before serialization
|
||||
([lines 514–570](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/compile/internal/noder/unified.go#514)). Compiler import lookup opens the separately mapped artifact
|
||||
([lines 463–470](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/compile/internal/noder/unified.go#463)), selects export roots, and sorts declaration and body indices before serialization
|
||||
([lines 495–570](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/compile/internal/noder/unified.go#495)). Compiler import lookup opens the separately mapped artifact
|
||||
([`noder/import.go`, lines 61–101](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/compile/internal/noder/import.go#61)) and decodes its exports independently of source parsing
|
||||
([lines 170–225](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/compile/internal/noder/import.go#170)); `ReadPackage` consumes that package decoder
|
||||
([`importer/ureader.go`, lines 28–62](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/compile/internal/importer/ureader.go#28)).
|
||||
|
||||
Reference in New Issue
Block a user