Skip to content

Commit 0adb288

Browse files
authored
chore: pin mcpp 0.0.109, hoist the compat index redirect, fix compat.openssl (#125)
* chore: pin mcpp 0.0.109, hoist the compat index redirect, fix compat.openssl ## mcpp 0.0.109 (MCPP_VERSION + index.toml floor) 0.0.109 makes a bare dependency take BOTH halves of its wire address from the descriptor the identity gate accepted (mcpp#286). That is the client-side other half of the SPEC-001 short-name migration (#120): mcpp used to take the name from the descriptor and the namespace from the request, so a bare `gtest = "1.15.2"` addressed `mcpplibs:gtest`, a key no index has. It survived only on a hardcoded `compat.<short>` retry that the short names removed — leaving every bare request against this index broken on 0.0.108. min_mcpp moves with the pin so consumers get a client that can address the index they are handed. ## [indices]: hoisted to the workspace root The 13 members that consume `compat` no longer repeat `[indices] compat = { path = "../../.." }`; the root declares it once and they inherit it, with the relative path resolved against the workspace root (mcpp#224, 0.0.97). Exactly one entry, and `compat` specifically, because the table is keyed by NAMESPACE: * declared under a name no dependency asks for, the index is never registered and resolution silently falls through to the published remote index — the checkout under test is then not what is being tested; * declared under several namespaces it registers N separate project repos, and every lookup afterwards fails with an N-way ambiguity between what is physically one descriptor (mcpp#238 / xlings#374). Members needing another namespace keep their own declaration, which REPLACES the inherited table rather than merging — which is what holds each member to one project index repo. mcpp.toml and index.toml also join the workflow's paths filter; a change to either can break every member and neither gated a run before. ## compat.openssl `name`: `compat.openssl` -> `openssl`. It was the index's last legacy fully-qualified spelling (SPEC-001 §3.2). `./config` now passes `--libdir=lib`. Unset, OpenSSL derives the install libdir as `lib$target{multilib}` and `linux-x86_64` declares `multilib => "64"`, so the archives landed in $prefix/lib64 while `-Llib` and the post-build check looked at $prefix/lib. linux-aarch64 and both darwin64 targets declare no multilib and resolve to plain `lib` — which is how this validated on an arm64 Mac while being broken for every x86_64 Linux consumer. Reproduced against the published descriptor before fixing: the install tree came out as bin/ include/ lib64/ and install() failed its own archive check. Also: linux links `-l:libssl.a -l:libcrypto.a` (naming the archive rather than letting the driver resolve a name a shared object would win — one stray -L ahead of ours and the consumer picks up the host libssl.so.3) plus `-ldl -lpthread` for musl and pre-2.34 glibc; the build log moved into the install prefix, since the old spot was deleted mid-build by the very os.tryrm that preceded install; `RANLIB=/usr/bin/ranlib` is confined to macOS, the platform whose llvm-ranlib rejects `-c`; a redundant `os.cd` that would have broken the relative-srcroot fallback is gone; and install() probes for `perl` up front, since OpenSSL's ./config IS a Perl script and no xim:perl exists to declare. ## Two members for it `tests/examples/openssl` — direct dependency, inherits the root `compat` redirect, so the descriptor in this checkout is what gets built. Asserts both archives really link (SSL_CTX_new + EVP sha256) and the binary carries no dynamic ssl/crypto dependency. `tests/examples/asio-ssl` — the asio `ssl` feature end-to-end, a real TLS handshake over loopback. It declares no member-level [indices] on purpose: inheriting `compat` means asio resolves from the published index while its feature dep, compat.openssl, comes from this checkout — which is how an unmerged compat descriptor can be exercised through a published consumer. The test moved out of asio-module, where it had been guarded by MCPP_FEATURE_SSL. A feature's `defines` apply to the package's own TUs, not to consumers, so that file compiled to nothing and passed while asserting nothing — the reason the libdir bug reached main green. It now keys off HAVE_ASIO_SSL, which the member sets in its own cfg-gated cxxflags. ## Docs docs/package-types.md still taught `name = "compat.<lib>"`. README, the repository/schema doc (new "索引重定向" section, corrected `features` row) and the openssl design spec are updated to match what the code does. * fix(openssl): declare xim:make on macosx, and print the log tail on failure The macOS workspace job failed on both new members ~43s after the tarball landed — far too early for a compile, and with nothing to go on: install() writes everything to an on-disk log (xim's interface mode swallows subprocess stdout) and xlings surfaces the failure as a bare `E_INTERNAL: [openssl] failed:`. Two changes, one for the likely cause and one so the next failure says what it was. macosx now declares `deps = { "xim:make@latest" }`. The previous comment claimed it was unnecessary because "macOS ships GNU Make at /usr/bin/make" — it ships GNU Make **3.81**, the last GPLv2 release, frozen in 2006, and OpenSSL 3.x's generated Makefile does not build with it. That matches the timing exactly: ~30s of Perl Configure, then make failing on sight. compat.openblas already declares this dep on macosx. Each build step now runs through a helper that, on failure, names the step and prints the last 40 lines of the log. The log also opens with `make --version`, because 3.81-vs-4.x is precisely the distinction that is invisible after the fact. The tail is passed as one pre-formatted argument rather than a format string — build output contains `%` often enough that formatting it is its own failure mode. Verified on linux (cold): log opens with "GNU Make 4.3", openssl and asio-ssl members both pass. * fix(openssl): drop the macosx xim:make dep, pin Apple's cc, dump build logs in CI `xim:make` has no macOS build — xim-pkgindex's pkgs/m/make.lua declares only an `xpm.linux` block — so yesterday's macosx dep failed resolution outright with `E_INVALID_INPUT: package 'xim:make@latest' not found`, before install() ran. Reverted, with the finding written down. compat.openblas declares the same dep on macosx and is broken identically; nobody has noticed because that package is Windows-only in the test suite, so its macOS path is never taken. That leaves the original macOS failure — 43s after download, no message — still undiagnosed, so this stops guessing at it: * The workspace job gains an `if: failure()` step that finds every `mcpp_*_build.log` under the members and the registry and prints its tail. install()-driven packages build through their own Make/Configure system, xim's interface mode swallows that output, and xlings reports only `E_INTERNAL: [<pkg>] failed:` — so a platform-specific break otherwise costs one full CI round-trip per hypothesis. * The log now opens with make/cc/perl versions, not just make's. And one likely cause addressed while here: OpenSSL is configured and built outside mcpp's compile rules, so it inherits none of the resolved toolchain's flags — it just runs `cc`. On macOS the `cc` in PATH is xim's llvm, which has no macOS SDK wired up, so every compile would fail on <stdio.h>. macOS now builds with `CC=/usr/bin/cc`, Apple's driver, which finds the SDK itself (same spirit as the RANLIB pin, which is already macOS-only). resolve_make() also prefers a Homebrew gmake when one exists, since /usr/bin/make is GNU Make 3.81. If the SDK guess is wrong, the log tail now says what is. Verified on linux (cold): log opens with GNU Make 4.3 / gcc 16.1.0, openssl member passes. * fix(openssl): pass RANLIB as a make command-line assignment, not an env var The macOS build now gets all the way through configure and compile — the CC pin was the missing piece there — and dies in `make install_sw`, one line after copying libcrypto.a into place: install libcrypto.a -> .../3.5.1/lib/libcrypto.a llvm-ranlib: error: Invalid option: '-c' make: *** [install_dev] Error 1 which is precisely what the RANLIB override exists to prevent. OpenSSL's `darwin-common` sets `ranlib => "ranlib -c"` (Configurations/10-main.conf:1844) and PATH resolves `ranlib` to the toolchain's llvm-ranlib, which rejects `-c`. The override was not taking effect, and that is a regression I introduced when confining it to macOS: I moved it from `make RANLIB=… install_sw` to `RANLIB=… make install_sw`. The first is a command-line assignment and beats the Makefile's own definition; the second is only an environment variable, which a Makefile assignment overrides absent `make -e` — so it silently did nothing and the build failed exactly as if it were not there. Restored to the command-line form, with a comment saying why the position matters. Also confirmed from the same log that `--libdir=lib` does its job on macOS: the archive installs to `3.5.1/lib/`, not `lib64/`. Verified on linux (cold): openssl member passes.
1 parent 9bd385c commit 0adb288

33 files changed

Lines changed: 557 additions & 152 deletions

File tree

.github/workflows/validate.yml

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ name: validate
22

33
on:
44
pull_request:
5-
paths: ["pkgs/**/*.lua", "tests/**", "README.md", ".github/workflows/validate.yml"]
5+
# mcpp.toml and index.toml carry the workspace member list, the inherited
6+
# [indices] redirect and the client version floor — a change to any of them
7+
# can break every member, so they gate the run like the descriptors do.
8+
paths: ["pkgs/**/*.lua", "tests/**", "README.md", "mcpp.toml", "index.toml", ".github/workflows/validate.yml"]
69
push:
710
branches: [main]
811
schedule:
@@ -11,6 +14,21 @@ on:
1114
workflow_dispatch:
1215

1316
env:
17+
# 0.0.109: a bare dependency's wire address takes BOTH halves from the
18+
# descriptor the identity gate accepted (mcpp#286). This is the client-side
19+
# other half of the SPEC-001 migration below: mcpp used to take the NAME from
20+
# the descriptor and the NAMESPACE from the request, so a bare `gtest =
21+
# "1.15.2"` addressed `mcpplibs:gtest` — a key no index has. It only ever
22+
# worked because the pre-migration literal `package.name` read
23+
# "compat.gtest", which the hardcoded `compat.<short>` retry then caught.
24+
# Short names removed that coincidence and left every bare request against
25+
# this index broken on 0.0.108, which is why min_mcpp moves to 0.0.109.
26+
# Note this index cannot cover that spelling itself: the `[indices]` redirect
27+
# is keyed by the REQUEST's namespace, so a bare dependency resolves from the
28+
# published remote index rather than the checkout under test. Bare-name
29+
# resolution against a short-name index is upstream's e2e 165; what moving
30+
# the floor buys here is that consumers of THIS index get a client that can
31+
# address it.
1432
# 0.0.106: SPEC-001 package identity (mcpp#280). `package.name` is a SINGLE
1533
# ATOMIC SEGMENT — all hierarchy lives in `package.namespace` — and mcpp
1634
# addresses a package by the LITERAL name it read, so descriptors no longer
@@ -57,7 +75,7 @@ env:
5775
# 0.0.94 fixed feature-gated `sources` under `mcpp test` (mcpp#218); 0.0.91
5876
# added standard = "c++fly" to the resolver grammar, so c++fly descriptors
5977
# get the lint WARN below, not a hard grammar-parse rejection.
60-
MCPP_VERSION: "0.0.108"
78+
MCPP_VERSION: "0.0.109"
6179

6280
jobs:
6381
lint:
@@ -222,21 +240,21 @@ jobs:
222240
ext: tar.gz
223241
mcpp: bin/mcpp
224242
xlings: registry/bin/xlings
225-
mcpp_version: "0.0.108" # keep in sync with env.MCPP_VERSION
243+
mcpp_version: "0.0.109" # keep in sync with env.MCPP_VERSION
226244
- platform: macos
227245
os: macos-15
228246
suffix: macosx-arm64
229247
ext: tar.gz
230248
mcpp: bin/mcpp
231249
xlings: registry/bin/xlings
232-
mcpp_version: "0.0.108" # keep in sync with env.MCPP_VERSION
250+
mcpp_version: "0.0.109" # keep in sync with env.MCPP_VERSION
233251
- platform: windows
234252
os: windows-latest
235253
suffix: windows-x86_64
236254
ext: zip
237255
mcpp: bin/mcpp.exe
238256
xlings: registry/bin/xlings.exe
239-
mcpp_version: "0.0.108" # keep in sync with env.MCPP_VERSION
257+
mcpp_version: "0.0.109" # keep in sync with env.MCPP_VERSION
240258
env:
241259
MCPP_EFFECTIVE: ${{ matrix.mcpp_version }}
242260
steps:
@@ -375,3 +393,21 @@ jobs:
375393
exit $rc
376394
fi
377395
396+
# install()-driven packages (openssl, openblas) build through their own
397+
# Make/Configure system, whose output xim's interface mode swallows; a
398+
# failed hook surfaces only as `E_INTERNAL: [<pkg>] failed:`. Each writes
399+
# a log into its install prefix, so on failure surface those — otherwise
400+
# diagnosing a platform-specific build break costs a full CI round-trip
401+
# per guess.
402+
- name: Dump install() build logs on failure
403+
if: failure()
404+
shell: bash
405+
run: |
406+
found=0
407+
while IFS= read -r log; do
408+
found=1
409+
echo "::group::$log"
410+
tail -80 "$log"
411+
echo "::endgroup::"
412+
done < <(find tests/examples "$HOME/.mcpp/registry" -name 'mcpp_*_build.log' 2>/dev/null)
413+
[ "$found" = 1 ] || echo "no install() build logs found"

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ mcpp self config --mirror CN # 切换至国内镜像,默认使用 GLOBAL 上
3535
| 原生模块库(Form A) | [`mcpplibs.xpkg`](pkgs/x/xpkg.lua) · [`mcpplibs.tinyhttps`](pkgs/t/tinyhttps.lua) · [`tensorvia-cpu`](pkgs/t/tensorvia-cpu.lua) · [`ffmpeg`](pkgs/f/ffmpeg.lua)(模块层,源码经 `compat.ffmpeg` 直编) · [`opencv`](pkgs/o/opencv.lua)(单仓库:模块层与 OpenCV 5 全源码构建同在包内,索引侧只留本描述符) |
3636
| C 源码 compat(含 `features`) | [`compat.cjson`](pkgs/c/compat.cjson.lua) · [`compat.zlib`](pkgs/c/compat.zlib.lua) |
3737
| header-only(含 `features`) | [`compat.eigen`](pkgs/c/compat.eigen.lua) |
38-
| 外部构建系统(`install()` 从源码构建) | [`compat.openblas`](pkgs/c/compat.openblas.lua)(Make) |
38+
| 外部构建系统(`install()` 从源码构建) | [`compat.openblas`](pkgs/c/compat.openblas.lua)(Make) · [`compat.openssl`](pkgs/c/compat.openssl.lua)(Perl Configure + Make,静态 libssl/libcrypto) |
3939
| 全源码直编(config 快照 + 源列表,零外部构建系统) | [`compat.ffmpeg`](pkgs/c/compat.ffmpeg.lua)(2281 TU 含 NASM 汇编,28 个目录 glob 声明) |
4040
| C++23 module wrapper | [`nlohmann.json`](pkgs/n/nlohmann.json.lua) · [`marzer.tomlplusplus`](pkgs/m/marzer.tomlplusplus.lua) |
4141

@@ -59,8 +59,9 @@ mcpp self config --mirror CN # 切换至国内镜像,默认使用 GLOBAL 上
5959
- 字段规范见 [mcpp 扩展字段文档](https://github.com/mcpp-community/mcpp/blob/main/docs/04-schema-xpkg-extension.md)
6060

6161
> 提交 PR 后,`validate` 自动执行 lint 并按改动库选跑对应 workspace 成员(整个测试面是一个 mcpp
62-
> workspace,公开模块包 `imgui`/`ffmpeg`/`opencv`/`tinyhttps` 也是普通成员——各成员经 `[indices]`
63-
> 把所消费命名空间重定向到 checkout,零 shell 驱动);合并后,`deploy-site` 将其发布至在线浏览站。
62+
> workspace,公开模块包 `imgui`/`ffmpeg`/`opencv`/`tinyhttps` 也是普通成员——`compat` 的重定向声明在
63+
> workspace 根并由成员继承,消费其他命名空间的成员各自覆盖,零 shell 驱动);合并后,`deploy-site`
64+
> 将其发布至在线浏览站。
6465
6566
## 相关链接
6667

docs/package-types.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ A、B、C 三类共用的骨架(`package` 头与 `xpm`)如下:
1717
```lua
1818
package = {
1919
spec = "1",
20-
namespace = "compat", -- compat / nlohmann / mcpplibs 等,决定 import 前缀与依赖 key
21-
name = "compat.<lib>", -- 完整包名,决定 pkgs/<首字母>/ 的落点
20+
namespace = "compat", -- 点分层级路径;compat / nlohmann / mcpplibs 等,决定 import 前缀与依赖 key
21+
name = "<lib>", -- 单一原子段,不重复 namespace(SPEC-001 §3.2)
2222
description = "",
2323
licenses = {"MIT"}, -- SPDX
2424
repo = "https://…",
@@ -36,6 +36,10 @@ package = {
3636
}
3737
```
3838

39+
身份是 `(namespace, name)` 二元组:层级一律放 `namespace`,`name` 只写一段。文件名不参与解析,推荐
40+
`pkgs/<首字母>/<namespace>.<name>.lua`(命中 mcpp 的快路径)。详见
41+
[仓库结构与 schema](repository-and-schema.md#包身份namespace-name)
42+
3943
---
4044

4145
## A. C 源码 compat(`compat.cjson` / `compat.zlib`)
@@ -132,8 +136,9 @@ name = "<short>-example"
132136
version = "0.1.0"
133137
[toolchain]
134138
default = "gcc@16.1.0"
135-
[indices]
136-
compat = { path = "../../.." } # 指回仓根,以使用本地描述符
139+
# `compat` 由 workspace 根的 [indices] 继承,成员无需再写;
140+
# 消费其他命名空间时才在此声明,例如 `[indices] fmtlib = { path = "../../.." }`
141+
# —— 成员级声明会**替换**根级表而非与之合并(这正是保持单个项目索引 repo 的方式)。
137142
[dependencies.compat]
138143
<short> = "1.2.3" # 或:<short> = { version = "1.2.3", features = ["…"] }
139144
[targets.<short>-example]

docs/repository-and-schema.md

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44

55
```
66
pkgs/<x>/<name>.lua 描述符。<x> 取完整包名首字母(compat.* → c,nlohmann.json → n,imgui → i)
7-
mcpp.toml workspace 清单(members 列表)
7+
mcpp.toml workspace 清单(members 列表)+ 根级 [indices] compat = { path = "." },
8+
由成员继承(相对路径按 workspace 根解析,mcpp ≥ 0.0.97)
89
tests/examples/<member>/ 每库测试工程(workspace 成员;<member> 为包名去前缀,模块包为
9-
mcpp.toml <name>-module)。恰好一条 [indices] <ns> = { path = "../../.." }
10-
把所消费命名空间重定向到本 checkout(模块包用 default,
11-
mcpp ≥ 0.0.97;单条是硬约束——xlings 多项目级 repo 静默失败,
12-
mcpp#238,修复后再做根级集中化)。依赖按平台自门控
10+
mcpp.toml <name>-module)。消费 compat 的成员不写 [indices];消费其他
11+
命名空间的成员写恰好一条(模块包用 default),该声明**替换**
12+
根级表而非合并 —— 每个成员最多一个项目级索引 repo 是硬约束,
13+
详见下文「索引重定向」。依赖按平台自门控
1314
([target.'cfg(...)'])
1415
tests/*.cpp 行为断言(独立 main,退出码非 0 即失败)
1516
tests/check_mirror_urls.lua lint:GLOBAL+CN 表完整性,以及 CN 指向 mcpp-res
@@ -75,8 +76,27 @@ namespace = "mcpplibs", name = "capi.lua" -- ❌ 短名仍带点
7576
| `sources` | glob 列表,编入 lib 的源码 |
7677
| `cflags` / `cxxflags` / `ldflags` | 追加至对应规则 |
7778
| `targets` | `{ ["name"]={ kind="lib"/"bin", main=…, soname=… } }` |
78-
| `features` | `{ ["f"]={ sources={…} } }`,仅识别 sources |
79-
| `deps` | `{ ["ns.name"]="ver" }`,扁平或点号式 |
79+
| `features` | `{ ["f"]={ sources={…}, defines={…}, deps={…}, implies={…}, requires={…} } }`;`defines` 只作用于**包自身**的 TU,消费端若要按 feature 分支须自行声明(见 `tests/examples/openssl``openblas``[target.'cfg(…)'.build] cxxflags`) |
80+
| `deps` | `{ ["ns.name"]="ver" }`,扁平或点号式;feature 内同形 |
81+
82+
## 索引重定向(`[indices]`)
83+
84+
测试面要验证的是 **checkout 里的描述符**,而不是已发布的远程索引,这靠 `[indices]` 把命名空间重定向到本仓完成。
85+
86+
**根级继承**:workspace 根的 `mcpp.toml` 声明 `[indices] compat = { path = "." }`,相对路径按 **workspace 根**解析(mcpp ≥ 0.0.97,[mcpp#224](https://github.com/mcpp-community/mcpp/issues/224)),成员直接继承,不必各写一份 `path = "../../.."`
87+
88+
**为什么只有一条,而且是 `compat`**:
89+
90+
- 索引表**按命名空间取键**。声明在一个没有任何依赖会请求的名字下,该索引根本不会被注册,解析会静默回落到已发布的远程索引 —— 此时被测的根本不是这个 checkout。
91+
- 同一路径声明成多个命名空间确实都会注册,但会变成 N 个各自独立的项目 repo,之后任何查找都以 N 路歧义失败(物理上是同一个描述符;[mcpp#238](https://github.com/mcpp-community/mcpp/issues/238) / [xlings#374](https://github.com/openxlings/xlings/issues/374),在 xlings 0.4.69 后由静默 exit 1 变为响亮报错)。
92+
93+
所以根级只能承载一个命名空间,`compat` 是收益最大的那个(13 个成员 vs 其余合计 10 个)。
94+
95+
**成员级覆盖**:消费其他命名空间的成员自己声明 `[indices]`,该表**替换**继承来的根级表而非与之合并 —— 这正是每个成员只保留一个项目索引 repo 的机制。
96+
97+
**跨命名空间的取舍**:一个成员无法同时从本 checkout 解析两个命名空间。`tests/examples/asio-ssl` 有意利用了这一点:它不写成员级声明、继承根级 `compat`,于是 asio 本身走已发布的远程索引,而它的 `ssl` feature 依赖 `compat.openssl` 从本 checkout 解析 —— 这样**未合并的 compat 描述符可以通过一个已发布的消费者去验证**。反过来,本地 asio 描述符由 `tests/examples/asio-module` 覆盖。
98+
99+
**裸名依赖不适用**:重定向按**请求侧**的命名空间取键,而裸写的 `eigen = "5.0.1"` 是以默认命名空间发出的请求,即使最终落到 `compat` 描述符上,也会从远程索引解析。因此各成员一律使用限定写法;裸名解析本身由 mcpp 上游的 e2e 165 覆盖。
80100

81101
## index 版本契约(index.toml)
82102

@@ -101,7 +121,8 @@ mcpp 跑 `xpkg parse`(strict:未知键即失败),所以需要更新文法/键的
101121
- `mirror-cn-reachable`(始终运行):逐个 `curl` CN url,均须返回 200。
102122
- `workspace (linux|macos|windows)`:整个测试面就是一个 mcpp workspace,**唯一的构建/运行通道**——
103123
没有任何 shell 驱动的例外(公开模块包 imgui/ffmpeg/opencv/tinyhttps 也是普通成员,经成员级
104-
`[indices] default = { path = "../../.." }` 从 checkout 解析,mcpp ≥ 0.0.97)。
124+
`[indices] default = { path = "../../.." }` 从 checkout 解析,mcpp ≥ 0.0.97;消费 `compat`
125+
成员则继承根级声明,见上文「索引重定向」)。
105126
- 选择性成员测试:PR 时由 `git diff` 将改动文件映射到受影响成员
106127
(`pkgs/<x>/<lib>.lua` → mcpp.toml 引用 `<lib>` 的成员;`tests/examples/<m>/**` → 成员 `<m>`),
107128
`mcpp test -p <member>` 这些成员;workflow 本身、workspace 清单非成员部分、`tools/`
@@ -135,3 +156,5 @@ done
135156
| C++23 module(generated wrapper) | `pkgs/n/nlohmann.json.lua` | `tests/examples/nlohmann.json/` | 同上 / #48 |
136157
| header-only + source-gated feature | `pkgs/c/compat.eigen.lua` | `tests/examples/eigen/` | `.agents/docs/2026-06-28-add-eigen-plan.md` / #50 |
137158
| header-only(纯头) | `pkgs/c/compat.opengl.lua``compat.khrplatform.lua` || `.agents/docs/2026-06-03-gl-runtime-packages-plan.md` |
159+
| 外部构建系统(`install()` 驱动) | `pkgs/c/compat.openblas.lua`(Make)、`compat.openssl.lua`(Perl Configure + Make) | `tests/examples/openblas/``openssl/` | `docs/superpowers/specs/2026-07-26-openssl-asio-tls-design.md` / #124 |
160+
| feature 拉起依赖(跨包) | `pkgs/c/chriskohlhoff.asio.lua``ssl` feature → `compat.openssl` | `tests/examples/asio-ssl/` | 同上 |

docs/superpowers/specs/2026-07-26-openssl-asio-tls-design.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,38 @@
11
# Add OpenSSL package + Asio SSL support
22

3-
> Created: 2026-07-26 · Status: design
3+
> Created: 2026-07-26 · Status: design (superseded in part — see §0)
44
> Repo: `mcpplibs/mcpp-index` · Branch: `feat/add-openssl-asio-tls`
55
6+
## 0. Corrections after landing
7+
8+
The design below is kept as written; three of its claims did not survive
9+
contact with the implementation, and the descriptor now differs accordingly.
10+
11+
1. **`name = "compat.openssl"``name = "openssl"`.** SPEC-001 (mcpp 0.0.106)
12+
makes `name` a single atomic segment with all hierarchy in `namespace`; the
13+
fully-qualified spelling is only a compatible legacy form.
14+
15+
2. **`MCPP_FEATURE_SSL` is NOT propagated to consumer TUs.** A feature's
16+
`defines` apply to the package's own translation units. The original
17+
`tests/ssl.cpp` keyed its whole body off that macro and therefore compiled
18+
to nothing — it passed while asserting nothing. A consumer that branches on
19+
a feature declares its own macro (`tests/examples/asio-ssl` sets
20+
`HAVE_ASIO_SSL` in its `[target.'cfg(…)'.build] cxxflags`), which is the
21+
same shape the openblas member already used.
22+
23+
3. **`./config` needs an explicit `--libdir=lib`.** Unset, OpenSSL derives it
24+
as `lib$target{multilib}`, and `linux-x86_64` declares `multilib => "64"`
25+
so the archives install to `$prefix/lib64` while `-Llib` and the post-build
26+
check look at `$prefix/lib`. linux-aarch64 and both darwin64 targets declare
27+
no multilib, which is why the build validated on an arm64 Mac and was still
28+
broken for every x86_64 Linux consumer.
29+
30+
Also changed while landing: linux links `-l:libssl.a -l:libcrypto.a` (naming
31+
the archive rather than letting the driver resolve a name that a shared object
32+
would win) plus `-ldl -lpthread`; the build log moved into the install prefix
33+
so it survives a failed build; `RANLIB` is pinned only on macOS, which is the
34+
platform that needs it; and `install()` probes for `perl` up front.
35+
636
## 1. Motivation
737

838
The mcpp ecosystem needs TLS support. `chriskohlhoff.asio@1.38.1` (C++23

index.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@
77
# "floor first, new grammar after" rollout rule mechanically.
88
[index]
99
spec = "1"
10-
min_mcpp = "0.0.108"
11-
latest_mcpp = "0.0.108"
10+
min_mcpp = "0.0.109"
11+
latest_mcpp = "0.0.109"

0 commit comments

Comments
 (0)