ww: select build action from package declaration
This commit is contained in:
@@ -2843,34 +2843,78 @@ 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 executable directory root is one normal package action. Its
|
||||
finalized canonical import identity tags its owner-only unit; it receives only
|
||||
direct exports, emits `.wwi`, `.o`, and a deterministic `.a`, and is compiled
|
||||
exactly once. The declared package name validates the last component of that
|
||||
identity for ordinary importable packages. A selected command root may declare
|
||||
`package main`; `main` validates its executable role and never replaces or
|
||||
truncates an identity such as `cmd.tool`. The narrow compiler `--entry` flag
|
||||
both classifies that primary unit as a command and controls bare `main` codegen;
|
||||
the package driver uses the parser-only `--command-package` marker for command
|
||||
test variants that must remain ordinary archive code. Neither flag changes
|
||||
export identity, and imported interfaces remain under strict leaf validation.
|
||||
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.
|
||||
A selected production root is one normal package action. Its finalized
|
||||
canonical import identity tags its owner-only unit; it receives only direct
|
||||
exports, emits `.wwi`, `.o`, and a deterministic `.a`, and is compiled exactly
|
||||
once. The declared package name validates the last component of that identity
|
||||
for ordinary importable packages. After loading and identity finalization, the
|
||||
declaration also selects the terminal build action: `package main` is a command
|
||||
and every other valid declaration is a compile-only library. A command root
|
||||
receives the narrow compiler `--entry` flag, which controls bare `main` codegen,
|
||||
then the linker receives that root archive first, the complete reachable
|
||||
package-archive closure, and the runtime archive; it never receives `.wwi`. A
|
||||
non-main root receives no `--entry` and never enters the linker. `main` validates
|
||||
command kind but never replaces or truncates an identity such as `cmd.tool`.
|
||||
The explicit package-less single-file compatibility path has no directory
|
||||
package declaration to classify and remains a raw command unit; it does not
|
||||
participate in canonical directory-package interning.
|
||||
The package driver still uses the parser-only `--command-package` marker for
|
||||
command test variants that must remain ordinary archive code. Neither marker
|
||||
changes export identity, and imported interfaces remain under strict leaf
|
||||
validation. 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 is reverse-resolved through the active source roots
|
||||
or receives the deterministic local identity described below. Its declared
|
||||
leaf can never invent or truncate that identity. 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).
|
||||
Publication is separate from that semantic action choice. `ww build -o lib.a
|
||||
DIR` or `ww build -I ROOT -o bar.a foo.bar` automatically publishes a non-main
|
||||
root's deterministic archive and self-contained compiler export at
|
||||
`FILE.wwi`, without invoking the linker; the latter retains `foo.bar.*` symbols.
|
||||
Without `-o`, a non-main root and its dependencies are compiled in the selected
|
||||
scratch or persistent work directory and no cwd product is invented. For a
|
||||
command, `-o` continues to name the executable publication path. Output names,
|
||||
request order, and whether publication was requested never enter package or
|
||||
action identity. The historical action-selecting `-p` exception is removed and
|
||||
rejected as an unknown build flag. Assembly-only `-S` still stops before object,
|
||||
archive, publication, or link production. A literal directory is
|
||||
reverse-resolved through the active source roots or receives the deterministic
|
||||
local identity described below; its declared leaf can never invent or truncate
|
||||
that identity. 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).
|
||||
|
||||
This rule follows the pinned official Go 1.26.5 source at commit
|
||||
`c19862e5f8415b4f24b189d065ed739517c548ba`. `go/build.Package` stores source
|
||||
directory, declared name, and import path independently, and defines a command
|
||||
solely as a package named `main`
|
||||
([`go/build/build.go`, lines 436–449](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build.go#L436-L449),
|
||||
[`go/build/build.go`, lines 514–519](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build.go#L514-L519)).
|
||||
The Go builder's `AutoAction` links only `main` and returns the archive compile
|
||||
action for every other package
|
||||
([`cmd/go/internal/work/action.go`, lines 450–456](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L450-L456)).
|
||||
The build command invents a default output only for one `main`, applies an
|
||||
explicit `-o` to either AutoAction result, and otherwise builds each requested
|
||||
package without conflating publication and semantic kind
|
||||
([`cmd/go/internal/work/build.go`, lines 473–478](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/build.go#L473-L478),
|
||||
[`cmd/go/internal/work/build.go`, lines 508–548](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/build.go#L508-L548),
|
||||
[`cmd/go/internal/work/build.go`, lines 551–558](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/build.go#L551-L558)).
|
||||
|
||||
Both WW stages represent the rule with the existing loaded declaration and
|
||||
stable root action index; no package, dependency, ownership, locator, traversal,
|
||||
or closure allocation is added. `ww run` adds only a command-kind requirement:
|
||||
a successfully loaded, cycle-free non-main root produces the deterministic
|
||||
`package PATH is not a main package` diagnostic before any compiler, assembler,
|
||||
or linker invocation; package and graph failures retain precedence. Before a
|
||||
non-main `-o` build invokes a producer, both stages validate the longest atomic
|
||||
publication spelling, `FILE.wwi.new`, so an incomplete archive/export pair is
|
||||
never caused by a late path-overflow failure. Package loading, cycle detection,
|
||||
and closure validation retain diagnostic precedence over this publication-only
|
||||
check, and `-S` does not validate a publication path it never consumes.
|
||||
Build workdir format 12 invalidates older build-mode unit vouchers before reuse
|
||||
because root compiler argv changed; test workdir format 11 is unchanged because
|
||||
test variants still link only their explicit generated-main action. Thereafter
|
||||
an equivalent warm library build invokes no tools, a private dependency change
|
||||
stops at its unchanged export, and an export change recompiles its direct
|
||||
importer under the existing propagation rule.
|
||||
|
||||
### 11.7 Implemented directory package-test slice
|
||||
|
||||
@@ -2939,7 +2983,7 @@ invocation, each still-unbound directory is finalized by this exact algorithm:
|
||||
invalidates a name inferred from a later or nested root.
|
||||
3. Bind the first precedence-valid candidate from each reaching context through
|
||||
the command-global bidirectional interner. An identity supplied by successful
|
||||
logical package lookup, such as `-p encoding.utf8`, is already bound and is
|
||||
logical package lookup, such as `encoding.utf8`, is already bound and is
|
||||
preserved exactly. That forward-selected identity is authoritative: reverse
|
||||
derivation applies only to still-unbound literal roots, so a nested active
|
||||
root cannot rename an explicitly resolved package.
|
||||
|
||||
Reference in New Issue
Block a user