Skip to content

Commit 116f532

Browse files
authored
feat(toolchain): native MSVC cl.exe build backend + graph-global dialect flags (#210) — 0.0.90 (#213)
* docs(agents): 0.0.90 single-PR implementation plan (full post-089 roadmap) * fix(build): dialect-class flags reach the std BMI prebuild and the whole module graph (#210) [build].cxxflags like -freflection change what libstdc++ headers DECLARE (<meta> is gated on __cpp_impl_reflection) — they are module-graph dialect, same nature as -std=. They now ride -std='s channels: the global $cxxflags (every TU incl. dependency modules — fixes the fmt.gcm-class secondary failure), the std/std.compat prebuild command, and scans. Known-list auto-promotion (reflection/contracts/char8_t/_GLIBCXX_USE_CXX11_ABI) + explicit [build] dialect_cxxflags escape hatch. The fingerprint already keyed these flags — only the command construction was missing them. Also: cppStandardFlag is now spelled per-dialect (std_flag_for — msvc /std:c++20 | /std:c++latest), groundwork for the native MSVC backend. Verified: issue #210's exact repro prints 'x 2 / y 3' via import std on gcc@16.1.0; e2e 98 covers both variants + std-module.json assertion. * feat(toolchain): native MSVC cl.exe build backend (C1-C7) - C1 env model: find_windows_sdk() + build_env_for_cl() synthesize INCLUDE/LIB/PATH/VSLANG=1033 from the detected VC tools + SDK (no vcvarsall run); enrich_toolchain_from_cl fills tc.envOverrides; missing SDK keeps detection working and fails the BUILD with guidance (replaces the 0.0.88 'not yet supported' gate — the gate is gone). - C2 emission: SeparateLinker rules (link.exe /OUT + rspfile — cmd's 8191 limit), lib.exe archives, /DLL+/IMPLIB shared, deps=msvc via /showIncludes, /interface /TP for .cppm module units, /std: mapping (std_flag_for), /MD|/MT CRT model, /Od, /nologo /EHsc /utf-8 baseline, .obj object extension end to end (plan objExt + std staging names). - C3 std/std.compat staging: single-cl commands (/ifcOutput), ifc.cache layout, registry-dispatched staged paths (clang hardcoding removed), stdmod executes with the toolchain env (capture_with_env). - C4 scanning: /scanDependencies as the third builtin P1689 producer (provider capability + ninja scan rule); dyndep ifc-parameterized as-is. - C8 fast path: '@env' multi-var encoding in the build cache env slot so incremental msvc builds re-create INCLUDE/LIB for ninja. - cd /d in std stage commands (cmd.exe won't change drive without it; D: workspace + C: BMI cache is the real CI layout). Zero-diff gate re-verified for GCC and LLVM vs the 0.0.89 release binary. * feat: e2e 99 msvc native build, 95 gate-flip, mingw polish, 0.0.90 version/docs - e2e 99 (requires: msvc): default msvc → modules build/run → import std → incremental; 95's build-gate assertion flips to a real build+run; the ci-windows MSVC step now drives 99. - mingw: windows-only guard with a clear message (was 'invalid xpkg target xim:mingw-gcc@'); e2e 97 objdump path unhardcoded; doctor gains Windows SDK + mingw sections. - release.yml publish-ecosystem timeout 20→30 (backstop for the fixed mirror script's worst case). - version 0.0.90 + CHANGELOG + docs/03 MSVC build section.
1 parent bd80e53 commit 116f532

27 files changed

Lines changed: 896 additions & 104 deletions
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# 0.0.90 单 PR 实施计划(post-089 路线图全量)
2+
3+
> 2026-07-13 · 执行 `2026-07-13-post-089-roadmap-and-std-dialect-flags-design.md`
4+
> **全部内容**于一个 PR。步骤是顺序实施的里程碑(每步本地 build+test 过),不拆 PR。
5+
6+
## 步骤
7+
8+
**S1 — D1 方言旗标(#210)**
9+
manifest 解析 `[build] dialect_cxxflags`;`extract_dialect_flags(cxxflags)`
10+
(known-list:reflection/contracts/char8_t/`-D_GLIBCXX_USE_CXX11_ABI=`;
11+
fno-exceptions/rtti 首版不入);`BuildPlan.dialectFlags`;注入:flags.cppm 全局
12+
`$cxxflags`(cxx_std_flag 旁)、`ensure_built` 新形参 → gcc/clang/msvc std 命令、
13+
metadata 自然失效。单测 + e2e `98_reflection_import_std.sh`(两变体,flag 探测 SKIP)。
14+
15+
**S2 — A 债务**
16+
stdmod `shellEsc``shq`;std/scan 命令的 `env …` 前缀 → argv+env(执行层带
17+
tc.envOverrides + runtime dirs);build_program/p1689 的 is_clang → caps/dialect。
18+
19+
**S3 — C1 环境模型**
20+
msvc.cppm:`find_windows_sdk()`(注册表→Windows Kits 目录扫描,取最高版本)+
21+
`build_env(inst, sdk)` → INCLUDE/LIB/PATH(+`VSLANG=1033`);`enrich_toolchain_from_cl`
22+
`tc.envOverrides`;SDK 缺失=检测时警告、构建时硬错误。doctor msvc 段加 SDK 行。
23+
24+
**S4 — 对象/标准旗标方言化(C2 前置)**
25+
`object_filename_for` 接 objExt(.o/.m.o ↔ .obj/.m.obj);ninja std staging
26+
`obj/std.o` 名参数化;`cppStandardFlag` 由 dialect.stdPrefix 产出
27+
(msvc:>c++20 → `/std:c++latest`,20→`/std:c++20`);defines/`/D` 走 dialect;
28+
CRT:`/MD` 默认、linkage=static → `/MT`
29+
30+
**S5 — C2/C5 msvc 规则发射**
31+
ninja_backend:LinkStyle::SeparateLinker 时 `cxx_link` = `$ld /nologo /OUT:$out @rsp`
32+
(rspfile/rspfile_content),`cxx_shared` = `/DLL /IMPLIB:`,`cxx_archive` =
33+
dial.archiveCmd(lib.exe @rsp);compile 规则 `deps = msvc` + `/showIncludes`;
34+
CompileFlags 增 `ldBinary`(link.exe,cl 同目录);registry archive_tool msvc →
35+
lib.exe;flags.cppm msvc ld 分支(dep runtime dirs → /LIBPATH,user ldflags 透传)。
36+
37+
**S6 — C3 std/std.compat staging**
38+
msvc.cppm `std_module_build_commands`(cl /c std.ixx /ifcOutput /Fo:)+
39+
std.compat.ixx 同法;`std_bmi_path`/`staged_std_bmi_path`/compat 变体 registry 分发
40+
(flags.cppm 的 clang 硬编码 staging 调用一并解除);stdmod:objectPath 扩展名
41+
per-dialect、msvc 分支走新命令、执行带 envOverrides;`hasImportStd` 已由 0.0.88 检测。
42+
43+
**S7 — C4 .ifc 管线 + /scanDependencies**
44+
ninja `cxx_module` msvc 形态(moduleOutputPrefix=` /ifcOutput ` 已就绪;确认
45+
`/Fo:` 同行共存);`/ifcSearchDir`(bmiSearchPrefix,已就绪);cxx_scan msvc 变体
46+
`cl /scanDependencies $out /std:… /c $in`;provider msvc `has_builtin_p1689_scan=true`;
47+
dyndep DyndepOptions(ifc.cache/.ifc)零改动。
48+
49+
**S8 — C7 删门 + fast-path env**
50+
删 prepare.cppm MSVC 构建门;BuildResult/fast-path 缓存的单对 runtime env 推广为
51+
env 列表(持久化 tc.envOverrides,否则 msvc 增量构建丢 INCLUDE/LIB)。
52+
53+
**S9 — MinGW 打磨 + 基建**
54+
lifecycle:mingw 在非 Windows 明确报 windows-only;e2e 97 objdump 路径 glob;
55+
doctor mingw 段;release.yml publish-ecosystem timeout 20→30。
56+
57+
**S10 — 测试与 CI 面**
58+
e2e `99_msvc_native_build.sh`(requires: msvc):default msvc → new → build → run →
59+
多模块 → import std → 增量;**95 号改造**:门断言(“not yet supported”)翻转为构建
60+
成功断言;ci-windows.yml MSVC 步骤同步改为 build+run 矩阵(llvm+mingw+msvc);
61+
单测:dialect 提取器、SDK 路径解析纯函数、std: 映射、msvc std 命令拼装。
62+
63+
**S11 — 版本与文档**
64+
0.0.90(mcpp.toml/fingerprint.cppm/CHANGELOG);docs/03-toolchains.md MSVC 节
65+
撤 “not yet supported”、补构建说明;#210 关联说明。
66+
67+
**S12 — 流程**
68+
临时分支(仅 ci-windows+release.yml)迭代绿 → 真 PR(全 CI)→ --admin 合入 →
69+
tag v0.0.90 → release(修复版 mirror 的实战验收,publish-ecosystem 应全自动)→
70+
`xlings install mcpp@0.0.90` 验证 → bootstrap pin → 总汇报。
71+
72+
## 风险与回退
73+
- MSVC 模块管线在真实 CI 的未知坑(cl 版本细节、/showIncludes 本地化、rsp 转义):
74+
全部集中在 S5-S7,靠临时分支 CI 循环消化;门在 S8 才删,之前任何一步可安全暂停。
75+
- e2e 98 的 -freflection 依赖 gcc16 驱动接受度:探测 SKIP 兜底。
76+
- fast-path 缓存格式变更(S8):版本化格式头,老缓存自然失效重建。

.github/workflows/ci-windows.yml

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -254,17 +254,11 @@ jobs:
254254
"$MCPP_SELF" self doctor 2>&1 | tee doctor.txt || true
255255
grep -qi "msvc" doctor.txt
256256
257-
# native cl.exe builds are gated with one owned message
258-
"$MCPP_SELF" new hello_msvc && cd hello_msvc
259-
set +e
260-
bout=$("$MCPP_SELF" build 2>&1); brc=$?
261-
set -e
262-
echo "$bout"
263-
test $brc -ne 0
264-
grep -q "not yet supported" <<<"$bout"
257+
# native cl.exe build: full e2e (modules, import std, incremental)
258+
cd "$GITHUB_WORKSPACE"
259+
MCPP="$MCPP_SELF" bash tests/e2e/99_msvc_native_build.sh
265260
266261
# restore the LLVM default for the remaining steps
267-
cd "$GITHUB_WORKSPACE"
268262
"$MCPP_SELF" toolchain default llvm@20.1.7
269263
270264
- name: "Toolchain: LLVM — build mcpp (self-host)"

.github/workflows/release.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -708,8 +708,10 @@ jobs:
708708
needs: [build-release, build-linux-aarch64, build-macos, build-windows]
709709
runs-on: ubuntu-latest
710710
# A4 hardening: a single stuck upload once held this job >1h (6h default
711-
# ceiling). The mirror script now has per-file timeouts, so 20min is ample.
712-
timeout-minutes: 20
711+
# ceiling). The mirror script has per-file timeouts and (post-0.0.89)
712+
# batch-upload + ranged-GET verification — normal runs are minutes; 30
713+
# is the generous backstop (20 was hit by the old per-asset verify loop).
714+
timeout-minutes: 30
713715
env:
714716
XLINGS_RES_TOKEN: ${{ secrets.XLINGS_RES_TOKEN }}
715717
GITCODE_TOKEN: ${{ secrets.GITCODE_TOKEN }}

CHANGELOG.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,42 @@
33
> 本文件追踪 `mcpp-community/mcpp` 公开仓的版本演进。
44
> 格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)
55
6+
## [0.0.90] — 2026-07-13
7+
8+
### 新增
9+
10+
- **MSVC 原生构建后端(cl.exe)落地,0.0.88 的构建门移除**。选定 `msvc@system`
11+
`mcpp build/run` 直接用系统 MSVC 编译链接:
12+
- 环境模型:`find_windows_sdk()` + 从检测到的 VC tools/SDK 直接合成
13+
INCLUDE/LIB/PATH(+`VSLANG=1033`),不跑 vcvarsall;SDK 缺失时检测/选择仍可用,
14+
构建报带指引的明确错误;doctor 新增 SDK 与 mingw 检查行。
15+
- 模块管线:std/std.compat.ixx 单命令 staging(`/ifcOutput` → ifc.cache),
16+
命名模块 `.cppm``/interface /TP` 编译、`/ifcSearchDir` 消费;
17+
`/scanDependencies` 作为第三个编译器内建 P1689 扫描驱动接入 dyndep。
18+
- 链接:link.exe/lib.exe(SeparateLinker)+ 响应文件(绕 cmd 8191 限制),
19+
DLL=`/DLL /IMPLIB:`;`deps=msvc`(/showIncludes)头文件依赖;`/MD|/MT` CRT
20+
随 linkage;`/std:c++20|c++latest` 映射;`.obj` 扩展名全链路。
21+
- fast-path 增量:构建缓存 env 槽新增 `@env` 多变量编码,增量构建重建
22+
INCLUDE/LIB 环境。e2e 99(模块/import std/增量)+ 95 改造为真实构建断言。
23+
- **`[build] dialect_cxxflags` + 方言旗标全图化(issue #210 修复)**
24+
`-freflection` 等"改变标准库头声明集"的 flag 现随 `-std=` 的通道到达:
25+
全局 cxxflags(项目+依赖所有 TU)、std/std.compat BMI 预构建命令、P1689 扫描。
26+
known-list 自动提升(reflection/contracts/char8_t/`_GLIBCXX_USE_CXX11_ABI`)+
27+
显式 `dialect_cxxflags` 逃生舱;指纹早已包含这些 flag,修的是命令构造。
28+
实证:#210 的最小复现(gcc16 + `import std;` + `std::meta`)输出 `x 2/y 3`;
29+
e2e 98 含依赖模块变体。
30+
31+
### 修复与优化
32+
33+
- mingw 在非 Windows 主机的 `toolchain install/default` 现在明确报
34+
windows-only(此前是 `invalid xpkg target 'xim:mingw-gcc@'`)。
35+
- std 模块 staging 命令在 Windows 用 `cd /d`(跨盘;工作区 D: + 缓存 C: 的
36+
真实 CI 布局)。
37+
- release 的 publish-ecosystem:镜像脚本改为批量上传+带耐心的 ranged-GET 验证、
38+
**验证超时不再删除资产**(0.0.89 因逐资产"18s 即删重传"+全量 GET 探测触顶
39+
20min 被杀);timeout 兜底 20→30。
40+
- stdmod 执行层支持工具链声明环境(capture_with_env);shell 引用平台化。
41+
642
## [0.0.89] — 2026-07-13
743

844
### 新增

docs/03-toolchains.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,14 @@ windows = "msvc@system"
132132
newest installed VC tools, but errors if the detected version doesn't match
133133
the prefix.
134134

135-
> [!NOTE]
136-
> Selection and detection are supported today; **building with native MSVC
137-
> (cl.exe) is not yet supported**`mcpp build` fails with a clear message
138-
> naming the detected version. For building on Windows use the MSVC-ABI Clang
139-
> toolchain: `mcpp toolchain default llvm@20.1.7` (it borrows the MSVC STL
140-
> from the same detected installation).
135+
Since 0.0.90, **native cl.exe builds work**: mcpp synthesizes the
136+
INCLUDE/LIB environment from the detected VC tools + Windows SDK (no
137+
`vcvarsall` involved), stages `std.ixx`/`std.compat.ixx` as `.ifc` BMIs,
138+
compiles `.cppm` module units via `/interface /TP /ifcOutput`, scans with
139+
`/scanDependencies`, and links with `link.exe`/`lib.exe` through response
140+
files. `[build] linkage = "static"` selects the `/MT` CRT. A missing Windows
141+
SDK fails the build with installation guidance (`mcpp self doctor` reports
142+
SDK status).
141143

142144
## Project-Level Version Pinning
143145

mcpp.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mcpp"
3-
version = "0.0.89"
3+
version = "0.0.90"
44
description = "Modern C++ build & package management tool"
55
license = "Apache-2.0"
66
authors = ["mcpp-community"]

src/build/execute.cppm

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,8 +335,22 @@ export std::optional<int> try_fast_build(const std::filesystem::path& projectRoo
335335
if (verbose) argv.push_back("-v");
336336

337337
std::vector<std::pair<std::string, std::string>> childEnv;
338-
if (runtimeEnvKey != "-" && !runtimeEnvValue.empty())
338+
if (runtimeEnvKey == "@env") {
339+
// Multi-var encoding (MSVC INCLUDE/LIB/PATH/VSLANG + optional runtime
340+
// pair): \x1f-separated k=v records in the single value slot.
341+
std::string_view rest = runtimeEnvValue;
342+
while (!rest.empty()) {
343+
auto sep = rest.find('\x1f');
344+
auto rec = rest.substr(0, sep);
345+
if (auto eq = rec.find('='); eq != std::string_view::npos && eq > 0)
346+
childEnv.emplace_back(std::string(rec.substr(0, eq)),
347+
std::string(rec.substr(eq + 1)));
348+
if (sep == std::string_view::npos) break;
349+
rest.remove_prefix(sep + 1);
350+
}
351+
} else if (runtimeEnvKey != "-" && !runtimeEnvValue.empty()) {
339352
childEnv.emplace_back(runtimeEnvKey, runtimeEnvValue);
353+
}
340354

341355
auto t0 = std::chrono::steady_clock::now();
342356
// capture_exec merges stderr into the captured output (replacing `2>&1`),

src/build/flags.cppm

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ struct CompileFlags {
2727
std::string cxx; // full cxxflags string
2828
std::string cc; // full cflags string
2929
std::string ld; // ldflags string
30-
std::filesystem::path cxxBinary; // g++ / clang++
31-
std::filesystem::path ccBinary; // gcc / clang (derived)
32-
std::filesystem::path arBinary; // ar path (may be empty → use PATH)
30+
std::filesystem::path cxxBinary; // g++ / clang++ / cl.exe
31+
std::filesystem::path ccBinary; // gcc / clang (derived; cl.exe = same)
32+
std::filesystem::path arBinary; // ar / llvm-ar / lib.exe (empty → PATH)
33+
std::filesystem::path ldBinary; // link.exe (SeparateLinker dialects only)
3334
std::string sysroot; // --sysroot=... (for ninja ldflags)
3435
std::string bFlag; // -B<binutils> (for ninja ldflags)
3536
bool staticStdlib = true;
@@ -142,15 +143,17 @@ CompileFlags compute_flags(const BuildPlan& plan) {
142143
f.cxxBinary = plan.toolchain.binaryPath;
143144
f.ccBinary = mcpp::toolchain::derive_c_compiler(plan.toolchain);
144145

145-
// PIC?
146+
const bool isMsvcDialect = (d.id == "msvc");
147+
148+
// PIC? (GNU-only concept; PE code is position independent by design.)
146149
bool need_pic = false;
147150
for (auto& lu : plan.linkUnits) {
148151
if (lu.kind == LinkUnit::SharedLibrary) {
149152
need_pic = true;
150153
break;
151154
}
152155
}
153-
std::string pic_flag = need_pic ? " -fPIC" : "";
156+
std::string pic_flag = (need_pic && !isMsvcDialect) ? " -fPIC" : "";
154157

155158
// Include dirs
156159
std::string include_flags;
@@ -235,9 +238,21 @@ CompileFlags compute_flags(const BuildPlan& plan) {
235238
// unless the profile pins -O0.
236239
auto& prof = plan.manifest.buildConfig;
237240
std::string opt_flag = isMuslTc && prof.optLevel != "0"
238-
? " -Og" : std::format(" {}{}", d.optPrefix, prof.optLevel);
241+
? " -Og"
242+
: (isMsvcDialect && prof.optLevel == "0")
243+
? " /Od" // MSVC's no-opt spelling (there is no /O0)
244+
: std::format(" {}{}", d.optPrefix, prof.optLevel);
239245
if (prof.debug) opt_flag += std::format(" {}", d.debugFlags);
240-
if (prof.lto) opt_flag += " -flto";
246+
if (prof.lto && !isMsvcDialect) opt_flag += " -flto";
247+
248+
// MSVC baseline: /nologo /EHsc /utf-8 (dialect alwaysFlags) + the CRT
249+
// model — /MD default, /MT under static linkage (portable-by-default is
250+
// impossible on MSVC-ABI; /MT at least removes the vcruntime DLL dep).
251+
std::string msvc_base;
252+
if (isMsvcDialect) {
253+
msvc_base = std::format(" {}", d.alwaysFlags);
254+
msvc_base += (plan.manifest.buildConfig.linkage == "static") ? " /MT" : " /MD";
255+
}
241256

242257
// User link flags
243258
std::string user_ldflags;
@@ -264,9 +279,8 @@ CompileFlags compute_flags(const BuildPlan& plan) {
264279
}
265280
std::string std_compat_module_flag;
266281
if (!traits.stdCompatBmiUsePrefix.empty() && !plan.stdCompatBmiPath.empty()) {
267-
// NOTE: staging path is Clang's today; registry-dispatch when the
268-
// MSVC backend lands (std.compat.ixx staging).
269-
auto compatDst = mcpp::toolchain::clang::staged_std_compat_bmi_path(plan.outputDir);
282+
auto compatDst = mcpp::toolchain::staged_std_compat_bmi_path(
283+
plan.toolchain, plan.outputDir);
270284
std_compat_module_flag = std::string(traits.stdCompatBmiUsePrefix)
271285
+ escape_path(compatDst);
272286
}
@@ -287,11 +301,20 @@ CompileFlags compute_flags(const BuildPlan& plan) {
287301
std::string cxx_std_flag =
288302
plan.cppStandardFlag.empty()
289303
? std::format("{}c++23", d.stdPrefix) : plan.cppStandardFlag;
290-
f.cxx = std::format("{}{}{}{}{}{}{}{}{}{}", cxx_std_flag, module_flag, std_module_flag,
304+
// plan.dialectFlags rides right behind -std= (issue #210): module-graph-
305+
// global dialect flags reach every TU (deps included) via this global
306+
// cxxflags string, exactly like the standard flag itself.
307+
f.cxx = std::format("{}{}{}{}{}{}{}{}{}{}{}{}", cxx_std_flag, plan.dialectFlags,
308+
msvc_base, module_flag, std_module_flag,
291309
std_compat_module_flag, prebuilt_module_flag,
292310
opt_flag, pic_flag, compile_toolchain_flags, b_flag, include_flags);
293-
f.cc = std::format("{}{}{}{}{}{}{}", d.stdPrefix, c_std, opt_flag, pic_flag,
294-
compile_toolchain_flags, b_flag, include_flags);
311+
// MSVC compiles C with cl.exe too; /std: for C uses cN spellings — skip
312+
// the C standard flag there (cl defaults are fine for the C entry TUs).
313+
f.cc = isMsvcDialect
314+
? std::format("{}{}{}{}{}", msvc_base, opt_flag, compile_toolchain_flags,
315+
b_flag, include_flags)
316+
: std::format("{}{}{}{}{}{}{}", d.stdPrefix, c_std, opt_flag, pic_flag,
317+
compile_toolchain_flags, b_flag, include_flags);
295318

296319
// Link flags
297320
f.staticStdlib = plan.manifest.buildConfig.staticStdlib;
@@ -339,6 +362,18 @@ CompileFlags compute_flags(const BuildPlan& plan) {
339362
if (prof.strip) link_extra += " -s";
340363

341364
if constexpr (mcpp::platform::is_windows) {
365+
if (isMsvcDialect) {
366+
// Native cl.exe: link.exe does the link (SeparateLinker). Search
367+
// paths for dependency runtime import libs via /LIBPATH; user
368+
// ldflags pass through verbatim; GNU link_extra (-flto/-s) does
369+
// not apply.
370+
f.ldBinary = mcpp::toolchain::link_tool(plan.toolchain);
371+
std::string libpaths;
372+
for (auto& dir : plan.depRuntimeLibraryDirs)
373+
libpaths += " /LIBPATH:" + escape_path(dir);
374+
f.ld = libpaths + user_ldflags;
375+
return f;
376+
}
342377
// PE link: no rpath/loader/payload model. MSVC-ABI Clang needs
343378
// nothing extra (MSVC STL/SDK via the driver); MinGW adds the static
344379
// libstdc++/libgcc pair (static_stdlib above) and -B so its own

0 commit comments

Comments
 (0)