ww: preserve command package identities

This commit is contained in:
2026-08-13 03:37:08 +09:00
parent 10d24a3237
commit 4377634bb9
10 changed files with 348 additions and 43 deletions

View File

@@ -2805,9 +2805,14 @@ compilation.
A directory package consists of its immediate regular non-symlink `.ww` files,
excluding `*_test.ww`, in byte-sorted filename order. Every selected file must
declare the same package. An imported directory's declared package must equal
the final component of its import path; two logical identities for one physical
directory are rejected rather than compiled twice.
declare the same package. An ordinary importable directory's declaration must
equal the final component of its import path. A selected command directory
instead declares `package main` to validate command kind while retaining its
complete canonical import identity. A source import of a command package from a
different directory is rejected; the one same-directory exception is an
external `main_test` variant's canonical import of its production action. 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 directory-package action,
@@ -2839,13 +2844,18 @@ 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 only validates the last component of
that identity. 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.
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.
`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
@@ -2941,7 +2951,11 @@ invocation, each still-unbound directory is finalized by this exact algorithm:
The selected full identity's final component is then validated against the
ordinary declared package name (or against the ordinary leaf obtained by
removing `_test` for the external variant). There is no fallback from an empty
removing `_test` for the external variant). The one command-kind rule is that a
selected command family declares `main`/`main_test` while keeping the finalized
ordinary identity unchanged. A source import of that command from another
directory rejects as a program before tools; a colocated external command test
may reuse the canonical production action. There is no fallback from an empty
import path to a declaration name. Relative, absolute, and symlink spellings
converge through the canonical directory; two unrelated local directories with
the same declaration therefore remain distinct. One bound import path mapping
@@ -3292,7 +3306,14 @@ and `b/foo` directories declaring the same `package foo` publish distinct
coexist in one command under distinct reversible local identities. Equivalent
recursive spellings reuse the same persistent request directory without new
compilation, while source imports of the reserved local namespace reject before
tool invocation.
tool invocation. The exact-argv command root declares `package main` but keeps
its non-`main` canonical identity in the unit, export, archive, compiler argv,
and linker argv; the bootstrap self-rebuild independently proves the same rule
for the real `w6a` and `w6l` command directories. A focused command-test row
proves distinct production, internal, external, and generated-main actions,
colocated external-production reuse, parser-only command markers, stage-equal
unit/export/archive bytes, both test binaries' runtime behavior, and pre-tool
rejection when another directory tries to import the command.
The exact-argv regression uses the real diamond
`base -> {left,right} -> root`. It proves one compile per node; no input for
@@ -3350,6 +3371,10 @@ The pinned official Go 1.26.5 tag (commit
and the command-global package cache returns the existing package pointer for
a later root or import of the resolved identity
([lines 757775](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L757-L775)).
Go keeps a command-line `Name == "main"` package as the selected command and
rejects an import from a different directory, while permitting the
same-directory test-loader edge
([lines 799805](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L799-L805)).
The package's parsed import list becomes its direct package dependencies,
rather than a transitive flattening
([lines 433440](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L433-L440),
@@ -3358,6 +3383,9 @@ The pinned official Go 1.26.5 tag (commit
pointer ([`action.go`, lines 202206](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L202-L206))
and returns the already-interned action for that key
([lines 437447](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L437-L447)).
A selected package whose independent `Name` is `main` receives a link action
([lines 450455](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L450-L455))
while retaining its ordinary compiled archive action.
A compile action depends on only `p.Internal.Imports`
([lines 628658](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L628-L658));
an executable link asks for that same cached root compile action