Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion .agents/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ superseded_by: 2026-09-07-....md # when status is superseded
---
```

324 records.
325 records.

## By subject

Expand All @@ -30,6 +30,7 @@ Records that declare one. Everything else is listed by date below.

### design

- [`mcpp run` hands the terminal to the program, and the follow-ups of #761, #763 and #765 (#766)](2026-10-05-run-terminal-handoff-and-766-follow-ups-design.md) — landed
- [PR CI acceleration and the toolchain specification (#756, #757, #669)](2026-10-02-pr-ci-acceleration-and-the-toolchain-specification-design.md) — active
- [工具与工具链的来源:声明、编程决定、可观察](2026-10-01-tool-and-toolchain-sources-design.md) — landed
- [A pack's build reported as a build, and a unit's compile independent of the member selection: triage and design (#753, #751)](2026-10-01-pack-drive-and-selection-independent-compile-design.md) — landed
Expand Down Expand Up @@ -115,6 +116,7 @@ Records that declare one. Everything else is listed by date below.

### 2026-10

- [`mcpp run` hands the terminal to the program, and the follow-ups of #761, #763 and #765 (#766)](2026-10-05-run-terminal-handoff-and-766-follow-ups-design.md) — landed
- [PR CI acceleration and the toolchain specification (#756, #757, #669)](2026-10-02-pr-ci-acceleration-and-the-toolchain-specification-design.md) — active
- [工具与工具链的来源:声明、编程决定、可观察](2026-10-01-tool-and-toolchain-sources-design.md) — landed
- [A pack's build reported as a build, and a unit's compile independent of the member selection: triage and design (#753, #751)](2026-10-01-pack-drive-and-selection-independent-compile-design.md) — landed
Expand Down
71 changes: 71 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,77 @@
> Each `## [<version>]` section is that release's notes. Entries are written in English
> from 2026.9.28.3 on; earlier entries remain as written.

## [2026.10.5.1] - 2026-10-05

This release gives the program that `mcpp run` starts the terminal, and closes
the follow-ups of 2026.10.3.1's three fixes (#761, #763, #765) recorded in
mcpp#766: the shared dependencies of statics placed in a program's own image,
`exports` on the MSVC ABI, and the walk and boundary of build-program glob
inputs. The key added by #763 is renamed before its first release
(`windows_auto_export`). No default toolchain changes.

### Fixed

- **`mcpp run` hands the terminal to the program.** The program started by
`mcpp run`, `mcpp run -q --release` or a named runner ran in a process group
of its own, which on a terminal is a background group: its first read of the
terminal stopped it with `SIGTTIN`, and Ctrl-C reached mcpp, which killed the
program instead of letting its handler run. On Linux and macOS mcpp now
replaces itself with the program once the build is done (`execve`). The
program reads the terminal, receives Ctrl-C, Ctrl-\ and Ctrl-Z, and runs with
the process id the shell started, so a `timeout` or a closed terminal reaches
it directly and nothing of mcpp remains. On Windows the program runs in mcpp's
console and process group, and mcpp ignores Ctrl-C while it waits. A program
that ends by a signal is seen by the caller as ending by that signal, as in a
direct run; before, mcpp exited with `128+n`. Notices concerning the whole
command (`tip:` lines) are printed before the `Running` line. E2E 883 drives
`mcpp run` through a pseudo-terminal.
- **A program links the shared dependencies of the statics placed in its own
image.** A workspace member's executable, or an artifact, links the objects of
a static package that is placed in its own package's shared image, and now
also links that package's shared dependencies; before, the link failed with an
undefined reference. A program does not link the objects of a static placed in
another package's image, which that image's library supplies.
- **`exports` takes effect on the MSVC ABI.** The `.def` of a DLL holds the
discovered symbols that match a pattern; before, the patterns were ignored on
PE. Source declarations (`__declspec(dllexport)`, `/EXPORT:`, the same in
LLVM bitcode) still decide the export set when present, and `exports` beside
them is reported as a warning. A DLL that exports nothing and is linked by a
program of the same build fails at its `.def` step with a message naming it,
rather than at the consumer as a missing import library.
- **Build-program glob inputs use the walk of `sources` globs.** Directory
symlinks are followed with the cycle guard, and the same directories are
excluded. A pattern whose literal prefix passes through an excluded directory
is reported as a warning, since it can never re-run the program.

### Changed

- **`[targets.<n>] auto_export` is renamed `windows_auto_export`.** The key
added by #763 affects only MSVC-ABI DLLs, and SPEC-004 §5.3 now states that a
key with an effect on one platform carries that platform's prefix. The key was
not in a release, so no alias is kept. `windows_auto_export = false` together
with `exports` is refused when an MSVC-ABI target is planned.
- **Glob inputs that leave the package.** An absolute `rerun_if_changed_glob`
pattern is matched against absolute paths. A pattern that leaves the package,
by `..` or as an absolute path, is an error in a registry or git dependency,
whose tree is the package store's; it is honoured for the project, a path
dependency and a workspace member.
- **The `.def` step runs its LLVM tools concurrently**, one compiler and one
`llvm-nm` invocation per bitcode object, up to eight at a time.

### Specifications

- SPEC-004 v1.11: §5.3, platform-scoped keys carry the platform's prefix. The
field admission criteria are referred to docs/90.
- SPEC-009 v0.2: §10.5 gate G7, E2E 881 passes with a candidate LLVM release on
the MSVC-ABI rows.

### Repository CI

- `tests/e2e/run_all.sh` bounds each test on hosts without GNU `timeout`
(the macOS runners) with `tests/e2e/_timeout.py`, which ends the test's whole
process tree. One hung test no longer consumes the shard's step budget.

## [2026.10.3.1] - 2026-10-03

This release is identical to 2026.10.2.1 in code; the bump exists to publish a
Expand Down
61 changes: 41 additions & 20 deletions docs/04-mcpp-toml.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,12 @@ the loader opens and the import library the linker consumes, with the export
list generated from the objects on the MSVC ABI (which exports nothing without
`__declspec(dllexport)` or a `.def`). See `tests/e2e/08`, `257` and `259`.

A package with a `shared` target and `bin` targets links each executable from
its own objects, as a separate program: the executable does not load the
package's own shared library. A program that loads a package's shared library
is a program of another package, for example another member of the same
workspace ([07 — Workspaces](07-workspace.md)).

#### `kind = "app"` — the thing a user launches (mcpp 2026.9.12.3+)

```toml
Expand Down Expand Up @@ -265,8 +271,8 @@ exports = "abi/mydriver.exports" # or inline: exports = ["vk_icd*"]

Omitting `exports` leaves ELF and Mach-O's native visibility rules in effect.
On the MSVC ABI, mcpp discovers exportable external definitions unless an input
already declares exports or `auto_export = false` disables discovery. `exports`
narrows the linker's published set.
already declares exports or `windows_auto_export = false` disables discovery.
`exports` narrows the linker's published set.

Two projects need the narrowing. A **runtime with a stable ABI** publishes a
reviewed set and nothing else, so that what is not in the set stays free to
Expand All @@ -284,7 +290,7 @@ One statement, three renderings:
|---|---|
| ELF | a version script, `-Wl,--version-script=` |
| Mach-O | `-Wl,-exported_symbols_list` (the leading underscore is supplied by the engine) |
| PE | the `.def`, replacing the auto-generated all-exports one |
| PE (MSVC ABI) | the `.def`: the discovered symbols that match a pattern |

**It does not change compile-time visibility, and that is deliberate.** The
narrowing is a link-time property on all three formats, so one key has one
Expand All @@ -301,30 +307,45 @@ A `soname` is meaningful on `kind = "lib"` too — see
[`dependency_linkage`](#dependency_linkage--static-or-shared-is-the-consumers-decision)
below, where the form a library takes becomes the consumer's decision.

#### `auto_export` — native export control on the MSVC ABI (unreleased)
On the MSVC ABI the three sources of a DLL's export set apply in this order:

1. **Declarations in the sources.** When any object declares exports
(`__declspec(dllexport)`, `#pragma comment(linker, "/EXPORT:...")`, or the
same in LLVM bitcode), the DLL publishes exactly those. `exports` beside such
a declaration has no effect, and the build states this as a warning that
names the object.
2. **`exports`.** Otherwise the discovered symbols whose name matches a pattern
are published. A pattern matches the linker's name of the symbol:
undecorated on 32-bit x86, and MSVC-mangled for C++. A pattern written for a
C name is therefore portable across the three formats; one written for a
mangled C++ name is not.
3. **Discovery.** Otherwise every exportable definition is published.

A DLL that publishes nothing has no import library. When a program of the same
build links such a DLL, its `.def` step fails and names the DLL; a DLL that no
program links, such as a resource-only DLL, builds.

The key and LLVM bitcode discovery require an unreleased source build; they are
not available in mcpp 2026.10.3.1. A target that supplies its own export control
can omit the automatic export-discovery step:
#### `windows_auto_export` — export discovery on the MSVC ABI (mcpp 2026.10.5.1+)

```toml
[targets.plugin]
kind = "shared"
auto_export = false
windows_auto_export = false
```

The boolean defaults to `true` and applies only to PE shared libraries on the
MSVC ABI, including clang and clang-cl. It applies when a library target is
built as a dependency too. It has no effect on static libraries, executables,
ELF, Mach-O or MinGW. Native `__declspec(dllexport)`, linker flags and explicit
`exports` lists remain effective when discovery is disabled.

With discovery enabled, any input's explicit export intent suppresses automatic
exports for the whole DLL. COFF directives are checked first. LLVM bitcode is
inspected with the selected LLVM compiler, including `dllexport` declarations
and linker-option metadata. Only an unannotated DLL needs candidate enumeration;
bitcode candidates come from `llvm-nm` beside that compiler. Both FullLTO and
ThinLTO inputs can be mixed with ordinary COFF objects.
The boolean defaults to `true`. `false` removes the discovery step, and the
DLL publishes what its sources and `[build] ldflags` declare. It applies to PE
shared libraries on the MSVC ABI, including clang and clang-cl, also when the
target is built as a dependency, and renders nothing on static libraries,
executables, ELF, Mach-O and MinGW.

`windows_auto_export = false` together with `exports` is refused when an
MSVC-ABI target is planned, since `exports` narrows the discovered symbols; the
same manifest builds on ELF and Mach-O.

Discovery reads COFF objects directly and LLVM bitcode (FullLTO and ThinLTO,
alone or mixed with COFF objects) with the selected LLVM compiler and the
`llvm-nm` beside it.

#### `windows_subsystem` and `windows_entry` — a Windows GUI executable (mcpp 2026.9.12.2+)

Expand Down
28 changes: 28 additions & 0 deletions docs/09-commands-by-scenario.md
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,34 @@ test` and `mcpp pack` keep their statuses. A program, or a runner
failed build; [50 — Machine-Readable Output](50-machine-output.md) §6 gives the
bands.

### The program and the terminal *(2026.10.5.1+)*

The program `mcpp run` starts owns the terminal as it would if the shell had
started it: it reads the terminal's input, and Ctrl-C, Ctrl-\ and Ctrl-Z reach
the program, which decides what they mean. The same holds for a runner and for
the named runners (`--runner`).

- On Linux and macOS, `mcpp` is replaced by the program once the build is done.
The program runs with the process id the shell started, and nothing of `mcpp`
remains: a `timeout` or a closed terminal reaches the program directly.
- A program that ends by a signal is seen by the caller as ending by that
signal, as in a direct run: a shell reports `128+n`, and Python's
`subprocess` reports `-n`.
- On Windows, the program runs in the same console and process group, and
`mcpp` returns its exit code.
- A notice concerning the whole command (a `tip:` line, for example an index
that requires a newer mcpp) is printed before the `Running` line, since no
output of `mcpp` follows the program.

```console
$ mcpp run -q
> hello
read: hello
> ^C # the program's SIGINT handler runs
$ echo $?
3 # the status the handler returned
```

## Validating a descriptor before publishing

`mcpp xpkg parse` reads a descriptor with the resolver's own grammar, so what
Expand Down
6 changes: 4 additions & 2 deletions docs/12-binary-distribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -390,8 +390,10 @@ makes mcpp write an empty `EXPORTS` section. Adding a list on top would export t
same names twice (`LNK4197`) and export everything else besides, replacing a
chosen public surface with all of it. Bitcode's `dllexport` storage class and
linker-option metadata express the same intent. Export intent is checked before
candidate enumeration. The per-target [`auto_export`](04-mcpp-toml.md#auto_export--native-export-control-on-the-msvc-abi-unreleased)
key disables discovery entirely (unreleased source builds).
candidate enumeration. The per-target
[`windows_auto_export`](04-mcpp-toml.md#windows_auto_export--export-discovery-on-the-msvc-abi-mcpp-20261051)
key disables discovery, and [`exports`](04-mcpp-toml.md#exports--the-artifacts-published-symbol-set-mcpp-2026965)
narrows what it finds.

Past 65535 exportable symbols mcpp refuses rather than truncating. A truncated
export table links cleanly and then fails at whichever consumer needed the symbol
Expand Down
26 changes: 21 additions & 5 deletions docs/30-build-mcpp.md
Original file line number Diff line number Diff line change
Expand Up @@ -560,10 +560,10 @@ int main() {
```

The pattern is relative to the manifest directory and uses the same `*` / `**`
grammar as `sources = [...]`. A literal directory prefix can leave the package:
`../inputs/**/*.in` watches a sibling directory, including its creation after
the first build. Output and `.git` directories remain excluded, and directory
symlinks are not followed. Its fingerprint is the **sorted set of matching
grammar as `sources = [...]`, over the same walk: directory symlinks are
followed, a symlink cycle is entered once, and directories named `.git`,
`.mcpp` or `target`, the build's output directory and registered submodules
are not entered (2026.10.5.1+). Its fingerprint is the **sorted set of matching
paths** and nothing else:

- **not contents** — a file whose bytes matter is an ordinary
Expand All @@ -572,7 +572,23 @@ paths** and nothing else:
builds and `rsync`, and size is a weaker signal than the hash above.

The build output tree and `.git` are never part of the set, so a wide pattern
cannot make the program re-run forever against its own outputs.
cannot make the program re-run forever against its own outputs. A pattern
whose literal prefix passes through an excluded directory (`target/**/*.in`,
`.git/HEAD`) can never match, and the build states this as a warning naming
the pattern; one file's contents are watched with `rerun_if_changed`.

**Inputs outside the package** (2026.10.5.1+). A pattern may leave the package
when the package is the project, a path dependency or a workspace member:

| Pattern | Watches |
|---|---|
| `../inputs/**/*.in` | a sibling directory, including its creation after the first build |
| `/srv/data/**/*.csv` | an absolute directory, matched against absolute paths |

In a registry or git dependency, a pattern that leaves the package, by `..` or
as an absolute path, is an error naming the package and the pattern. A wide
literal prefix (`../../**`) walks its whole tree on every fast-path check, so a
specific prefix keeps the check short.

**Every declared input is compared on the fast path too** (2026.9.5.4+). A
project whose sources are all older than `build.ninja` takes a fast path that
Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ token in front of a reader to the chapter that owns it.
| | chapter | | chapter |
|---|---|---|---|
| `[package]`, `[targets.<n>]`, `[build]`, `[lib]` | [04](04-mcpp-toml.md) | `[profile.<n>]`, `[resources]`, `[runtime]` | [04](04-mcpp-toml.md) |
| `[targets.<n>] auto_export` | [04](04-mcpp-toml.md) | `[targets.<n>] exports` | [04](04-mcpp-toml.md) |
| `[targets.<n>] windows_auto_export` | [04](04-mcpp-toml.md) | `[targets.<n>] exports` | [04](04-mcpp-toml.md) |
| `[dependencies]`, `[dev-dependencies]`, `[build-dependencies]` | [05](05-dependencies.md) | `scan_overrides`, `module_extensions` | [04](04-mcpp-toml.md) |
| `[features]`, `[feature-deps.<f>]`, `provides` / `requires` | [06](06-features-and-capabilities.md) | `[workspace]` | [07](07-workspace.md) |
| `[toolchain]`, `cxx_runtime` | [20](20-toolchains.md) | `[target.<sel>]`, `cfg(…)` | [22](22-target-side.md) |
Expand Down
4 changes: 2 additions & 2 deletions docs/specs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@
| [SPEC-001](package-identity.md) | 包身份(`package.namespace` / `package.name`)、`[dependencies]` 选择器与匹配机制 | 评审中 v1.1 | 2026-08-03 | mcpp >= 0.0.106 |
| [SPEC-002](target-side.md) | 目标侧模型与能力声明(`mcpp:` 保留命名空间、五层、三条规则) | 评审中 v1.0 | 2026-08-24 | mcpp >= 2026.8.24.2 |
| [SPEC-003](exit-codes.md) | 退出码契约(分类、语义、稳定性承诺) | 评审中 v1.0 | 2026-09-01 | mcpp >= 2026.9.1.1 |
| [SPEC-004](manifest-semantics.md) | `mcpp.toml` 的平面划分、条件化形状、解析轴与命名规约 | 草案 v1.10 | 2026-09-28 | 条件化形状 mcpp >= 2026.8.29.1;目标轴 mcpp >= 2026.9.6.4;`linkage` 默认值 mcpp >= 2026.9.15.2;链接 flag 的词读法 mcpp >= 2026.9.26.2;条件化的 `dialect_cxxflags` 与 `-p` 的包身份 mcpp >= 2026.9.28.1;条件表按具体程度生效 mcpp >= 2026.9.28.2 |
| [SPEC-004](manifest-semantics.md) | `mcpp.toml` 的平面划分、条件化形状、解析轴与命名规约 | 草案 v1.11 | 2026-10-05 | 条件化形状 mcpp >= 2026.8.29.1;目标轴 mcpp >= 2026.9.6.4;`linkage` 默认值 mcpp >= 2026.9.15.2;链接 flag 的词读法 mcpp >= 2026.9.26.2;条件化的 `dialect_cxxflags` 与 `-p` 的包身份 mcpp >= 2026.9.28.1;条件表按具体程度生效 mcpp >= 2026.9.28.2;平台前缀规约 mcpp >= 2026.10.5.1 |
| [SPEC-005](build-database.md) | 构建数据库:`mcpp emit build-database` 的内容、取值规则与不写工程目录的保证 | 评审中 v1.6 | 2026-09-29 | mcpp >= 2026.9.15.1;v1.3 条款 mcpp >= 2026.9.26.2;v1.4 条款 mcpp >= 2026.9.27.1;v1.5 条款 mcpp >= 2026.9.28.1;v1.6 条款 mcpp >= 2026.9.29.5 |
| [SPEC-006](toolchain-management.md) | 工具链管理:身份、来源、选择与载荷契约 | 草案 v0.6 | 2026-10-02 | 逐条标注;已实现条款 mcpp >= 2026.9.24.1;§3.7 mcpp >= 2026.9.28.1;§3.7.1 mcpp >= 2026.9.28.2;§2.2.1 与 §3.3 的非缺省来源 mcpp >= 2026.10.1.3 |
| [SPEC-007](build-plugins.md) | 构建插件:配置、施工与校验的分工,运行时与规划期的义务 | 草案 v0.6 | 2026-09-28 | 逐条标注;mcpp >= 2026.9.26.2;v0.3 条款 mcpp >= 2026.9.27.1;v0.4 条款 mcpp >= 2026.9.28.1;v0.5 条款 mcpp >= 2026.9.28.2;v0.6(§9)mcpp >= 2026.9.28.3 |
| [SPEC-008](library-interface.md) | 库的接口:公开模块、发布闭包与两种形态的一致 | 草案 v0.1 | 2026-09-28 | 第一阶段(只警告)mcpp >= 2026.9.28.3 |
| [SPEC-009](toolchain-maintenance.md) | 工具链的支持与维护:版本线、默认值、来源、移动与退役 | 草案 v0.1 | 2026-10-02 | 逐条标注;本版只有规范,多数条款未实现 |
| [SPEC-009](toolchain-maintenance.md) | 工具链的支持与维护:版本线、默认值、来源、移动与退役 | 草案 v0.2 | 2026-10-05 | 逐条标注;本版只有规范,多数条款未实现 |

## 文档约定

Expand Down
Loading
Loading