|
1 | 1 | # Windows Runtime-DLL Deployment & `compat.openblas` Windows Support (Design) |
2 | 2 |
|
3 | 3 | Date: 2026-06-29 |
4 | | -Status: **Phase A implemented in mcpp 0.0.73.** Phases B–D (release + recipe + |
5 | | -Windows CI) track in the same effort. Staged follow-up to the feature/capability |
6 | | -work (mcpp 0.0.72) and the `compat.openblas` package (mcpp-index #54). Scope: |
7 | | -`src/build/{plan,ninja_backend}.cppm` (mcpp); `pkgs/c/compat.openblas.lua`, |
8 | | -`.github/workflows/validate.yml` (mcpp-index). |
| 4 | +Status: **Implemented & shipped.** |
| 5 | +- **Phase A** (mcpp runtime-DLL deployment) — merged in mcpp **#185**, released as |
| 6 | + **v0.0.73**, mirrored to `xlings-res/mcpp` (GitHub + GitCode), indexed via |
| 7 | + `openxlings/xim-pkgindex` **#326** (`latest → 0.0.73`), `xlings install |
| 8 | + mcpp@0.0.73` verified, workspace bootstrap pin bumped. |
| 9 | +- **Phase C** (`compat.openblas` Windows recipe) + **Phase D** (Windows CI |
| 10 | + build-and-run) — mcpp-index **#55**; the `OpenBLAS-0.3.33-x64.zip` CN mirror is |
| 11 | + live on gitcode `mcpp-res/openblas` (byte-verified). |
| 12 | + |
| 13 | +Scope: `src/build/{plan,ninja_backend}.cppm` (mcpp); `pkgs/c/compat.openblas.lua`, |
| 14 | +`tests/smoke_compat_portable.sh`, `.github/workflows/validate.yml` (mcpp-index). |
9 | 15 |
|
10 | 16 | ### Implementation note (deviation from the original design) |
11 | 17 |
|
@@ -221,20 +227,33 @@ on the runner; correction is log-driven). |
221 | 227 |
|
222 | 228 | | Item | Local (Linux host) | CI (`windows-latest`) | |
223 | 229 | |---|---|---| |
224 | | -| recipe parse / schema / Linux deploy mechanism | yes (dummy-lib e2e) | — | |
225 | | -| clang-cl linking `libopenblas.lib` | no (no MSVC env) | yes | |
226 | | -| DLL deployed beside the exe + loaded + `cblas_dgemm` runs | no | yes — once the Windows smoke is bumped to ≥ 0.0.73 and extended to run+assert (Phase D) | |
| 230 | +| recipe parse / schema / Linux deploy mechanism | yes (dummy-lib e2e `84_runtime_dll_deploy.sh`) | — | |
| 231 | +| clang linking `libopenblas.lib` | no (no MSVC env) | **yes — confirmed** (`-Llib -llibopenblas`) | |
| 232 | +| DLL deployed beside the exe + loaded + `cblas_dgemm` runs | no | **yes — confirmed** (mcpp-index #55 smoke-windows: `mcpp run` + direct-exe launch from a neutral CWD both green) | |
227 | 233 |
|
228 | | -## 7. Open questions / risks |
| 234 | +## 7. Open questions / risks — resolved by CI |
229 | 235 |
|
230 | 236 | - **Whole-directory `*.dll` vs an explicit list.** OpenBLAS's `bin/` holds a |
231 | 237 | single DLL, so copying `*.dll` from each runtime library dir is sufficient and |
232 | 238 | simple (preferred — YAGNI). If a future package's `bin/` mixes unrelated DLLs, |
233 | | - an optional explicit list can narrow it later. |
234 | | -- **clang-cl link form and symbol decoration.** The exact flag to link |
235 | | - `libopenblas.lib` and the cdecl `cblas_*` symbol names must match what the |
236 | | - consumer references; only CI confirms this. |
237 | | -- **`mcpp.<os>` runtime parsing.** If the parser reads `[runtime]` only at global |
238 | | - scope, allowing `library_dirs` under `mcpp.windows` is a small parser addition |
239 | | - (alternatively declare it globally — harmless on Linux, which links statically |
240 | | - and ships no DLL). |
| 239 | + an optional explicit list can narrow it later. *(Shipped as whole-directory.)* |
| 240 | +- **clang link form and symbol decoration.** *Resolved:* mcpp links Windows with |
| 241 | + the clang MSVC driver, and `-Llib -llibopenblas` resolves to `lib/libopenblas.lib`; |
| 242 | + the cdecl `cblas_*` symbols matched and `cblas_dgemm` produced `[19 22; 43 50]` |
| 243 | + on the runner. |
| 244 | +- **`mcpp.<os>` runtime parsing.** *Resolved without a parser change:* the deploy |
| 245 | + is filtered by the `*.dll` extension (§"Implementation note"), so `[runtime] |
| 246 | + library_dirs` is declared per-OS under `mcpp.windows` via the existing per-OS |
| 247 | + textual merge — no new schema key. On Linux/macOS the static archive ships no |
| 248 | + DLL, so the declaration is inert. |
| 249 | + |
| 250 | +## 8. Validation footnote — Phase D test bug (caught & fixed by CI) |
| 251 | + |
| 252 | +The first mcpp-index #55 run's `smoke-windows` failed *not* in the feature but in |
| 253 | +the test: the new openblas smoke ran the produced `.exe` from a path `find target` |
| 254 | +returned **relative**, after `cd /` to a neutral CWD — so the launch resolved to a |
| 255 | +nonexistent path. The build had already linked the import lib, deployed |
| 256 | +`bin/libopenblas.dll`, and `mcpp run` had exited 0 (correct GEMM). Absolutising the |
| 257 | +exe path (pwd + basename) fixed the assertion; the re-run is green. The lesson is |
| 258 | +the value of the direct-exe launch from a neutral CWD: it is the only check that |
| 259 | +proves the DLL loads *beside the exe* rather than via `mcpp run`'s `PATH` prepend. |
0 commit comments