Skip to content

Commit 8ee2933

Browse files
committed
feat: Clang on Windows — find MSVC STL std.ixx for import std support
When Clang targets x86_64-pc-windows-msvc, it uses MSVC STL (not libc++). Add fallback search for Visual Studio's std.ixx in the modules/ directory. Also add .exe suffix for clang-scan-deps and llvm-ar on Windows.
1 parent 17b083e commit 8ee2933

1 file changed

Lines changed: 39 additions & 1 deletion

File tree

src/toolchain/clang.cppm

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,44 @@ std::optional<std::filesystem::path> find_libcxx_std_module_source(
136136
}
137137

138138
void enrich_toolchain(Toolchain& tc, const std::string& envPrefix) {
139-
tc.stdlibId = "libc++";
139+
// Clang targeting MSVC uses MSVC STL, not libc++.
140+
bool msvTarget = tc.targetTriple.find("msvc") != std::string::npos;
141+
tc.stdlibId = msvTarget ? "msvc-stl" : "libc++";
140142
tc.stdlibVersion = tc.version.empty() ? "unknown" : tc.version;
141143
tc.linkRuntimeDirs = mcpp::toolchain::discover_link_runtime_dirs(
142144
tc.binaryPath, tc.targetTriple);
145+
143146
if (auto p = find_libcxx_std_module_source(tc.binaryPath, envPrefix)) {
144147
tc.stdModuleSource = *p;
145148
tc.hasImportStd = true;
146149
}
150+
151+
#if defined(_WIN32)
152+
// Fallback: if libc++ std.cppm not found, look for MSVC STL's std.ixx.
153+
// This happens when Clang targets x86_64-pc-windows-msvc.
154+
if (!tc.hasImportStd && msvTarget) {
155+
// Search Visual Studio installations for std.ixx
156+
// Typical path: C:\Program Files\Microsoft Visual Studio\2022\*\VC\Tools\MSVC\*\modules\std.ixx
157+
std::error_code ec;
158+
std::filesystem::path vsBase = "C:\\Program Files\\Microsoft Visual Studio\\2022";
159+
if (std::filesystem::exists(vsBase, ec)) {
160+
for (auto& edition : std::filesystem::directory_iterator(vsBase, ec)) {
161+
auto vcTools = edition.path() / "VC" / "Tools" / "MSVC";
162+
if (!std::filesystem::exists(vcTools, ec)) continue;
163+
for (auto& ver : std::filesystem::directory_iterator(vcTools, ec)) {
164+
auto stdIxx = ver.path() / "modules" / "std.ixx";
165+
if (std::filesystem::exists(stdIxx, ec)) {
166+
tc.stdModuleSource = stdIxx;
167+
tc.hasImportStd = true;
168+
break;
169+
}
170+
}
171+
if (tc.hasImportStd) break;
172+
}
173+
}
174+
}
175+
#endif
176+
147177
if (tc.hasImportStd) {
148178
if (auto p = find_libcxx_std_compat_source(tc.binaryPath, envPrefix)) {
149179
tc.stdCompatSource = *p;
@@ -186,13 +216,21 @@ std::vector<std::string> std_module_build_commands(const Toolchain& tc,
186216
}
187217

188218
std::filesystem::path archive_tool(const Toolchain& tc) {
219+
#if defined(_WIN32)
220+
auto llvmAr = tc.binaryPath.parent_path() / "llvm-ar.exe";
221+
#else
189222
auto llvmAr = tc.binaryPath.parent_path() / "llvm-ar";
223+
#endif
190224
if (std::filesystem::exists(llvmAr)) return llvmAr;
191225
return {};
192226
}
193227

194228
std::optional<std::filesystem::path> find_scan_deps(const Toolchain& tc) {
229+
#if defined(_WIN32)
230+
auto p = tc.binaryPath.parent_path() / "clang-scan-deps.exe";
231+
#else
195232
auto p = tc.binaryPath.parent_path() / "clang-scan-deps";
233+
#endif
196234
if (std::filesystem::exists(p)) return p;
197235
return std::nullopt;
198236
}

0 commit comments

Comments
 (0)