Skip to content

Commit c8453c1

Browse files
committed
Merge branch '630/wt-c' into 630/engine-batch
2 parents 90accbb + 1d610bf commit c8453c1

12 files changed

Lines changed: 1148 additions & 101 deletions

docs/10-pack-and-release.md

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,19 @@ Linux either.
482482
A `kind = "lib"` / `"shared"` target packs normally on macOS — a library package
483483
never runs the artifact. This restriction is only for programs.
484484

485+
The dependency closure can now be **read** rather than run — `mcpp.pack.binfmt`
486+
walks a Mach-O's load commands (`LC_LOAD_DYLIB` and its weak/re-export/upward
487+
siblings for names, `LC_RPATH` for search entries) the same way it already
488+
reads a PE's import table, and resolves `@executable_path`, `@loader_path` and
489+
`@rpath` the way `dyld` would, without loading anything. `mcpp pack` does not
490+
call it yet: bundling a resolved dylib beside the program needs an editor for
491+
`LC_RPATH` (a load command has no free space to grow into), and that editor is
492+
designed once resolution is measured on a real macOS build, not before. Until
493+
then a Mach-O program still stages without its closure — see [Producing a
494+
distributable](30-build-mcpp.md#producing-a-distributable-pack_format--stage_dir-20269111)
495+
for what a dispatched format (`.app`, `.ipa`) can already do with a tree that
496+
has a program and no closure.
497+
485498
## Configuration
486499

487500
Packaging behavior is configured via the `[pack]` section in `mcpp.toml`. The
@@ -513,11 +526,12 @@ The `static` mode additionally requires a musl toolchain configured under
513526

514527
## Planned Support
515528

516-
macOS **program** bundling (the Mach-O dependency closure, via `otool -L` /
517-
`LC_LOAD_DYLIB`, and `install_name_tool` for relocation) is still on the
518-
roadmap; until it lands `mcpp pack <program>` refuses on that format rather than
519-
producing something that only looks like a bundle. Windows DLL bundling beyond
520-
the current `.zip` is also on the roadmap.
529+
macOS **program** bundling is still on the roadmap. The closure is read now
530+
(`mcpp.pack.binfmt`'s Mach-O load-command walk — no `otool` needed), but
531+
bundling a resolved dylib beside the program and rewriting `LC_RPATH` for it
532+
is not; until that lands `mcpp pack <program>` still refuses on that format
533+
rather than producing something that only looks like a bundle. Windows DLL
534+
bundling beyond the current `.zip` is also on the roadmap.
521535

522536
Distribution formats such as `.deb`, `.rpm`, AppImage and `.msi` are **not** on
523537
this list, and that is a decision rather than an omission: they live in

docs/30-build-mcpp.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,17 @@ changes, and a closure that grew a dependency's shared library while the
709709
program's own bytes did not would leave the previous distributable in place,
710710
reported as up to date.
711711

712+
**The manifest's first line is `closure = walked` or `closure = not-walked`.**
713+
`mcpp pack` stages the program and its declared runtime
714+
files before it asks whether this host can resolve the artifact's dependency
715+
closure, so the tree can exist without one — a Mach-O program today, or a
716+
non-PE artifact packed from a Windows host. `--format tar` and `--format dir`
717+
still fail the command in that case, since the archive IS the closure; a
718+
dispatched format receives the tree regardless, with a second manifest line,
719+
`reason = <why>`, naming the mechanism that was unavailable. A provider that
720+
needs the closure reads the field rather than inferring a gap from an empty
721+
`lib/`.
722+
712723
Commands are an **argv, not a shell string** (no shell is assumed — Windows has
713724
none to rely on), and the only interpolations are a closed set:
714725

docs/zh/10-pack-and-release.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,17 @@ mcpp pack --target x86_64-windows-gnu # 在 Linux 宿主上
408408
`kind = "lib"` / `"shared"` 目标在 macOS 上照常打包 —— 库打包从不运行产物。
409409
这条限制只针对程序。
410410

411+
依赖闭包现在可以被**读出来**而不必运行了 —— `mcpp.pack.binfmt` 走一遍 Mach-O 的
412+
load command(`LC_LOAD_DYLIB` 及其 weak/re-export/upward 三个变体给出名字,
413+
`LC_RPATH` 给出搜索项),读法与它读 PE 导入表一样;并按 `dyld` 的规则解析
414+
`@executable_path``@loader_path``@rpath`,全程不加载任何东西。`mcpp pack`
415+
还没有调用它:把解析到的 dylib 拷到程序旁边、再重写它的 `LC_RPATH`,需要一个
416+
load command 编辑器(一条 load command 里没有空间可以塞进更长的路径),这个编辑器
417+
要等在真实的 macOS 构建上量过解析结果之后才设计,而不是先设计。在那之前,Mach-O
418+
程序仍然是"暂存但没有闭包"——一个被分发出去的格式(`.app``.ipa`)已经能拿这样一棵
419+
"有程序、没闭包"的树做什么,见
420+
[产出可分发物](30-build-mcpp.md#产出可分发物pack_format-与-stage_dir20269111)
421+
411422
## 配置项
412423

413424
打包行为通过 `mcpp.toml` 中的 `[pack]` 节配置,常用字段如下:
@@ -435,10 +446,11 @@ force_bundle = ["libfoo.so"] # 即使命中 PEP 600 名单也强制打包
435446

436447
## 待支持
437448

438-
macOS **程序** bundling(Mach-O 依赖闭包,走 `otool -L` / `LC_LOAD_DYLIB`,
439-
重定位走 `install_name_tool`)仍在规划中;在它落地之前,`mcpp pack <程序>`
440-
会在该格式上拒绝,而不是产出一个只是看起来像 bundle 的东西。当前 `.zip`
441-
之外的 Windows DLL 分发,同样在规划中。
449+
macOS **程序** bundling 仍在规划中。闭包现在已经能读出来了(`mcpp.pack.binfmt`
450+
走一遍 Mach-O 的 load command,不需要 `otool`),但把解析到的 dylib 拷到程序旁边、
451+
再重写它的 `LC_RPATH` 还没做;在这落地之前,`mcpp pack <程序>` 仍会在该格式上拒绝,
452+
而不是产出一个只是看起来像 bundle 的东西。当前 `.zip` 之外的 Windows DLL 分发,
453+
同样在规划中。
442454

443455
`.deb``.rpm`、AppImage、`.msi` 这些分发格式**不在**这份清单上,而这是一个决定而不是
444456
一处遗漏:它们住在包里,经 `--format <name>` 到达用户,理由见上一节。`[pack]` 的内建

docs/zh/30-build-mcpp.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,14 @@ mcpp 会写出 `<暂存树>.stage-manifest` —— 一个兄弟文件,永不是
606606
依赖的共享库、同时程序自己的字节并没有变的情况,会把上一次的可分发物原地留下,并报告为
607607
已是最新。
608608

609+
**这份 manifest 的第一行是 `closure = walked``closure = not-walked`**
610+
`mcpp pack` 会先暂存程序本身与它声明过的运行期文件,再去问这台宿主机能不能解析该产物的
611+
依赖闭包 —— 所以这棵树可以在没有闭包的情况下存在:今天是一个 Mach-O 程序,或者在
612+
Windows 宿主上打包一个非 PE 产物。`--format tar``--format dir` 在这种情况下仍然让
613+
命令失败,因为归档本身就是闭包;一个被分发出去的格式无论如何都会拿到这棵树,manifest 上
614+
多出第二行 `reason = <原因>`,点名是哪种机制在这台宿主上不可用。需要闭包的提供方读这个
615+
字段,而不是从一个空的 `lib/` 里去猜测缺口。
616+
609617
命令是 **argv 而不是 shell 字符串**(不假设存在 shell —— Windows 没有能依赖的那个),
610618
插值只有封闭的一组:
611619

0 commit comments

Comments
 (0)