[clang] [clang] Support --sysroot= for ${arch}-windows-msvc targets (PR #96417)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 26 17:02:42 PDT 2024
https://github.com/trcrsired updated https://github.com/llvm/llvm-project/pull/96417
>From 3a1790211a993908d6a9ab3cca1fa6eb2421e710 Mon Sep 17 00:00:00 2001
From: trcrsired <uwgghhbcad at gmail.com>
Date: Sun, 23 Jun 2024 00:07:19 -0400
Subject: [PATCH] Support --sysroot= for ${arch}-windows-msvc targets
I think it is possible to use the same rule for msvc targets with
--target= and --sysroot=
See Repository:
https://github.com/trcrsired/windows-msvc-sysroot
Add sysroot support for msvc
MSVC.cpp needs getDriver before using D
add stl in parser for -stdlib=
Add Vcruntime to runtime list and unwind list
MSVC add default runtime lib type and default unwind lib type
add a msvc sysroot test
use %S instead of /foo
Fix test for msvc-sysroot
Also add a pesudo implementation for WebAssembly and
maybe Microsoft STL could be ported to more targets in the future
Fix the toggle of wasm that prevents -stdlib=stl passed into
---
clang/include/clang/Driver/ToolChain.h | 9 +-
clang/lib/Driver/ToolChain.cpp | 9 +
clang/lib/Driver/ToolChains/MSVC.cpp | 248 +++++++++++++++-----
clang/lib/Driver/ToolChains/MSVC.h | 24 +-
clang/lib/Driver/ToolChains/WebAssembly.cpp | 29 +++
clang/lib/Driver/ToolChains/WebAssembly.h | 2 +
clang/test/Driver/msvc-sysroot.cpp | 81 +++++++
clang/test/Driver/wasm-toolchain.cpp | 12 +
8 files changed, 345 insertions(+), 69 deletions(-)
create mode 100644 clang/test/Driver/msvc-sysroot.cpp
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index 1f93bd612e9b0..04535a98dd69c 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -95,18 +95,21 @@ class ToolChain {
enum CXXStdlibType {
CST_Libcxx,
- CST_Libstdcxx
+ CST_Libstdcxx,
+ CST_Stl,
};
enum RuntimeLibType {
RLT_CompilerRT,
- RLT_Libgcc
+ RLT_Libgcc,
+ RLT_Vcruntime
};
enum UnwindLibType {
UNW_None,
UNW_CompilerRT,
- UNW_Libgcc
+ UNW_Libgcc,
+ UNW_Vcruntime
};
enum class UnwindTableLevel {
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 40ab2e91125d1..b3ed8fc6de36d 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -1091,6 +1091,8 @@ ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
runtimeLibType = ToolChain::RLT_CompilerRT;
else if (LibName == "libgcc")
runtimeLibType = ToolChain::RLT_Libgcc;
+ else if (LibName == "vcruntime")
+ runtimeLibType = ToolChain::RLT_Vcruntime;
else if (LibName == "platform")
runtimeLibType = GetDefaultRuntimeLibType();
else {
@@ -1129,6 +1131,8 @@ ToolChain::UnwindLibType ToolChain::GetUnwindLibType(
unwindLibType = ToolChain::UNW_CompilerRT;
} else if (LibName == "libgcc")
unwindLibType = ToolChain::UNW_Libgcc;
+ else if (LibName == "vcruntime")
+ unwindLibType = ToolChain::UNW_Vcruntime;
else {
if (A)
getDriver().Diag(diag::err_drv_invalid_unwindlib_name)
@@ -1152,6 +1156,8 @@ ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
cxxStdlibType = ToolChain::CST_Libcxx;
else if (LibName == "libstdc++")
cxxStdlibType = ToolChain::CST_Libstdcxx;
+ else if (LibName == "stl")
+ cxxStdlibType = ToolChain::CST_Stl;
else if (LibName == "platform")
cxxStdlibType = GetDefaultCXXStdlibType();
else {
@@ -1290,6 +1296,9 @@ void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
case ToolChain::CST_Libstdcxx:
CmdArgs.push_back("-lstdc++");
break;
+
+ default:
+ break;
}
}
diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp
index ca266e3e1d1d3..bf1b6d3b9bc84 100644
--- a/clang/lib/Driver/ToolChains/MSVC.cpp
+++ b/clang/lib/Driver/ToolChains/MSVC.cpp
@@ -31,12 +31,12 @@
#include <cstdio>
#ifdef _WIN32
- #define WIN32_LEAN_AND_MEAN
- #define NOGDI
- #ifndef NOMINMAX
- #define NOMINMAX
- #endif
- #include <windows.h>
+#define WIN32_LEAN_AND_MEAN
+#define NOGDI
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#include <windows.h>
#endif
using namespace clang::driver;
@@ -95,43 +95,52 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// the environment variable is set however, assume the user knows what
// they're doing. If the user passes /vctoolsdir or /winsdkdir, trust that
// over env vars.
- if (const Arg *A = Args.getLastArg(options::OPT__SLASH_diasdkdir,
- options::OPT__SLASH_winsysroot)) {
- // cl.exe doesn't find the DIA SDK automatically, so this too requires
- // explicit flags and doesn't automatically look in "DIA SDK" relative
- // to the path we found for VCToolChainPath.
- llvm::SmallString<128> DIAPath(A->getValue());
- if (A->getOption().getID() == options::OPT__SLASH_winsysroot)
- llvm::sys::path::append(DIAPath, "DIA SDK");
-
- // The DIA SDK always uses the legacy vc arch, even in new MSVC versions.
- llvm::sys::path::append(DIAPath, "lib",
- llvm::archToLegacyVCArch(TC.getArch()));
- CmdArgs.push_back(Args.MakeArgString(Twine("-libpath:") + DIAPath));
- }
- if (!llvm::sys::Process::GetEnv("LIB") ||
- Args.getLastArg(options::OPT__SLASH_vctoolsdir,
- options::OPT__SLASH_winsysroot)) {
- CmdArgs.push_back(Args.MakeArgString(
- Twine("-libpath:") +
- TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib)));
- CmdArgs.push_back(Args.MakeArgString(
- Twine("-libpath:") +
- TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib, "atlmfc")));
- }
- if (!llvm::sys::Process::GetEnv("LIB") ||
- Args.getLastArg(options::OPT__SLASH_winsdkdir,
- options::OPT__SLASH_winsysroot)) {
- if (TC.useUniversalCRT()) {
- std::string UniversalCRTLibPath;
- if (TC.getUniversalCRTLibraryPath(Args, UniversalCRTLibPath))
+ auto SysRoot = TC.getDriver().SysRoot;
+ if (SysRoot.empty()) {
+ if (const Arg *A = Args.getLastArg(options::OPT__SLASH_diasdkdir,
+ options::OPT__SLASH_winsysroot)) {
+ // cl.exe doesn't find the DIA SDK automatically, so this too requires
+ // explicit flags and doesn't automatically look in "DIA SDK" relative
+ // to the path we found for VCToolChainPath.
+ llvm::SmallString<128> DIAPath(A->getValue());
+ if (A->getOption().getID() == options::OPT__SLASH_winsysroot)
+ llvm::sys::path::append(DIAPath, "DIA SDK");
+
+ // The DIA SDK always uses the legacy vc arch, even in new MSVC versions.
+ llvm::sys::path::append(DIAPath, "lib",
+ llvm::archToLegacyVCArch(TC.getArch()));
+ CmdArgs.push_back(Args.MakeArgString(Twine("-libpath:") + DIAPath));
+ }
+ if (!llvm::sys::Process::GetEnv("LIB") ||
+ Args.getLastArg(options::OPT__SLASH_vctoolsdir,
+ options::OPT__SLASH_winsysroot)) {
+ CmdArgs.push_back(Args.MakeArgString(
+ Twine("-libpath:") +
+ TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib)));
+ CmdArgs.push_back(Args.MakeArgString(
+ Twine("-libpath:") +
+ TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib, "atlmfc")));
+ }
+ if (!llvm::sys::Process::GetEnv("LIB") ||
+ Args.getLastArg(options::OPT__SLASH_winsdkdir,
+ options::OPT__SLASH_winsysroot)) {
+ if (TC.useUniversalCRT()) {
+ std::string UniversalCRTLibPath;
+ if (TC.getUniversalCRTLibraryPath(Args, UniversalCRTLibPath))
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine("-libpath:") + UniversalCRTLibPath));
+ }
+ std::string WindowsSdkLibPath;
+ if (TC.getWindowsSDKLibraryPath(Args, WindowsSdkLibPath))
CmdArgs.push_back(
- Args.MakeArgString(Twine("-libpath:") + UniversalCRTLibPath));
+ Args.MakeArgString(std::string("-libpath:") + WindowsSdkLibPath));
}
- std::string WindowsSdkLibPath;
- if (TC.getWindowsSDKLibraryPath(Args, WindowsSdkLibPath))
- CmdArgs.push_back(
- Args.MakeArgString(std::string("-libpath:") + WindowsSdkLibPath));
+ } else {
+ const std::string MultiarchTriple =
+ TC.getMultiarchTriple(TC.getDriver(), TC.getTriple(), SysRoot);
+ std::string SysRootLib = "-libpath:" + SysRoot + "/lib";
+ CmdArgs.push_back(Args.MakeArgString(SysRootLib + '/' + MultiarchTriple));
+ CmdArgs.push_back(Args.MakeArgString(SysRootLib));
}
if (!C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
@@ -207,13 +216,14 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
// Make sure the dynamic runtime thunk is not optimized out at link time
// to ensure proper SEH handling.
- CmdArgs.push_back(Args.MakeArgString(
- TC.getArch() == llvm::Triple::x86
- ? "-include:___asan_seh_interceptor"
- : "-include:__asan_seh_interceptor"));
+ CmdArgs.push_back(
+ Args.MakeArgString(TC.getArch() == llvm::Triple::x86
+ ? "-include:___asan_seh_interceptor"
+ : "-include:__asan_seh_interceptor"));
// Make sure the linker consider all object files from the dynamic runtime
// thunk.
- CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
+ CmdArgs.push_back(Args.MakeArgString(
+ std::string("-wholearchive:") +
TC.getCompilerRT(Args, "asan_dynamic_runtime_thunk")));
} else if (DLL) {
CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
@@ -224,7 +234,7 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// This is necessary because instrumented dlls need access to all the
// interface exported by the static lib in the main executable.
CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
- TC.getCompilerRT(Args, Lib)));
+ TC.getCompilerRT(Args, Lib)));
}
}
}
@@ -430,6 +440,11 @@ MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
RocmInstallation(D, Triple, Args) {
getProgramPaths().push_back(getDriver().Dir);
+ auto SysRoot = getDriver().SysRoot;
+ if (!SysRoot.empty()) {
+ return;
+ }
+
std::optional<llvm::StringRef> VCToolsDir, VCToolsVersion;
if (Arg *A = Args.getLastArg(options::OPT__SLASH_vctoolsdir))
VCToolsDir = A->getValue();
@@ -602,8 +617,8 @@ static VersionTuple getMSVCVersionFromExe(const std::string &BinDir) {
if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
return Version;
- const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
- nullptr);
+ const DWORD VersionSize =
+ ::GetFileVersionInfoSizeW(ClExeWide.c_str(), nullptr);
if (VersionSize == 0)
return Version;
@@ -620,7 +635,7 @@ static VersionTuple getMSVCVersionFromExe(const std::string &BinDir) {
return Version;
const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
- const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF;
+ const unsigned Minor = (FileInfo->dwFileVersionMS) & 0xFFFF;
const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
Version = VersionTuple(Major, Minor, Micro);
@@ -647,6 +662,17 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
"include");
}
+ auto SysRoot = getDriver().SysRoot;
+ if (!SysRoot.empty()) {
+ const Driver &D = getDriver();
+ const std::string MultiarchTriple =
+ getMultiarchTriple(D, getTriple(), SysRoot);
+ addSystemInclude(DriverArgs, CC1Args,
+ SysRoot + "/include/" + MultiarchTriple);
+ addSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
+ return;
+ }
+
// Add %INCLUDE%-like directories from the -imsvc flag.
for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
addSystemInclude(DriverArgs, CC1Args, Path);
@@ -763,12 +789,11 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
// As a fallback, select default install paths.
// FIXME: Don't guess drives and paths like this on Windows.
const StringRef Paths[] = {
- "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
- "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
- "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
- "C:/Program Files/Microsoft Visual Studio 8/VC/include",
- "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
- };
+ "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
+ "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
+ "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
+ "C:/Program Files/Microsoft Visual Studio 8/VC/include",
+ "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"};
addSystemIncludes(DriverArgs, CC1Args, Paths);
#endif
}
@@ -776,6 +801,24 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
// FIXME: There should probably be logic here to find libc++ on Windows.
+ if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
+ options::OPT_nostdincxx))
+ return;
+ if (getDriver().SysRoot.empty())
+ return;
+ switch (GetCXXStdlibType(DriverArgs)) {
+ case ToolChain::CST_Stl:
+ addStlIncludePaths(DriverArgs, CC1Args);
+ break;
+ case ToolChain::CST_Libstdcxx:
+ addLibStdCXXIncludePaths(DriverArgs, CC1Args);
+ break;
+ case ToolChain::CST_Libcxx:
+ addLibCxxIncludePaths(DriverArgs, CC1Args);
+ break;
+ default:
+ break;
+ }
}
VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
@@ -877,7 +920,8 @@ static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
break;
case '1':
- DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
+ DAL.AddFlagArg(A,
+ Opts.getOption(options::OPT_finline_hint_functions));
break;
case '2':
case '3':
@@ -912,11 +956,10 @@ static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
}
if (SupportsForcingFramePointer) {
if (OmitFramePointer)
- DAL.AddFlagArg(A,
- Opts.getOption(options::OPT_fomit_frame_pointer));
+ DAL.AddFlagArg(A, Opts.getOption(options::OPT_fomit_frame_pointer));
else
- DAL.AddFlagArg(
- A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
+ DAL.AddFlagArg(A,
+ Opts.getOption(options::OPT_fno_omit_frame_pointer));
} else {
// Don't warn about /Oy- in x86-64 builds (where
// SupportsForcingFramePointer is false). The flag having no effect
@@ -1027,3 +1070,86 @@ void MSVCToolChain::addClangTargetOptions(
if (Arg *A = DriverArgs.getLastArgNoClaim(options::OPT_marm64x))
A->ignoreTargetSpecific();
}
+
+void MSVCToolChain::addStlIncludePaths(
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const {
+ const Driver &D = getDriver();
+ std::string SysRoot = computeSysRoot();
+ std::string LibPath = SysRoot + "/include";
+ const std::string MultiarchTriple =
+ getMultiarchTriple(D, getTriple(), SysRoot);
+
+ std::string TargetDir = LibPath + "/" + MultiarchTriple + "/c++/stl";
+ addSystemInclude(DriverArgs, CC1Args, TargetDir);
+
+ // Second add the generic one.
+ addSystemInclude(DriverArgs, CC1Args, LibPath + "/c++/stl");
+}
+
+void MSVCToolChain::addLibCxxIncludePaths(
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const {
+ const Driver &D = getDriver();
+ std::string SysRoot = computeSysRoot();
+ std::string LibPath = SysRoot + "/include";
+ const std::string MultiarchTriple =
+ getMultiarchTriple(D, getTriple(), SysRoot);
+
+ std::string Version = detectLibcxxVersion(LibPath);
+ if (Version.empty())
+ return;
+
+ std::string TargetDir = LibPath + "/" + MultiarchTriple + "/c++/" + Version;
+ addSystemInclude(DriverArgs, CC1Args, TargetDir);
+
+ // Second add the generic one.
+ addSystemInclude(DriverArgs, CC1Args, LibPath + "/c++/" + Version);
+}
+
+void MSVCToolChain::addLibStdCXXIncludePaths(
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const {
+ // We cannot use GCCInstallationDetector here as the sysroot usually does
+ // not contain a full GCC installation.
+ // Instead, we search the given sysroot for /usr/include/xx, similar
+ // to how we do it for libc++.
+ const Driver &D = getDriver();
+ std::string SysRoot = computeSysRoot();
+ std::string LibPath = SysRoot + "/include";
+ const std::string MultiarchTriple =
+ getMultiarchTriple(D, getTriple(), SysRoot);
+
+ // This is similar to detectLibcxxVersion()
+ std::string Version;
+ {
+ std::error_code EC;
+ Generic_GCC::GCCVersion MaxVersion =
+ Generic_GCC::GCCVersion::Parse("0.0.0");
+ SmallString<128> Path(LibPath);
+ llvm::sys::path::append(Path, "c++");
+ for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(Path, EC), LE;
+ !EC && LI != LE; LI = LI.increment(EC)) {
+ StringRef VersionText = llvm::sys::path::filename(LI->path());
+ if (VersionText[0] != 'v') {
+ auto Version = Generic_GCC::GCCVersion::Parse(VersionText);
+ if (Version > MaxVersion)
+ MaxVersion = Version;
+ }
+ }
+ if (MaxVersion.Major > 0)
+ Version = MaxVersion.Text;
+ }
+
+ if (Version.empty())
+ return;
+
+ std::string TargetDir = LibPath + "/c++/" + Version + "/" + MultiarchTriple;
+ addSystemInclude(DriverArgs, CC1Args, TargetDir);
+
+ // Second add the generic one.
+ addSystemInclude(DriverArgs, CC1Args, LibPath + "/c++/" + Version);
+ // Third the backward one.
+ addSystemInclude(DriverArgs, CC1Args,
+ LibPath + "/c++/" + Version + "/backward");
+}
diff --git a/clang/lib/Driver/ToolChains/MSVC.h b/clang/lib/Driver/ToolChains/MSVC.h
index 3950a8ed38e8b..609ce1c738751 100644
--- a/clang/lib/Driver/ToolChains/MSVC.h
+++ b/clang/lib/Driver/ToolChains/MSVC.h
@@ -71,9 +71,7 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain {
return llvm::DebuggerKind::Default;
}
- unsigned GetDefaultDwarfVersion() const override {
- return 4;
- }
+ unsigned GetDefaultDwarfVersion() const override { return 4; }
std::string getSubDirectoryPath(llvm::SubDirectoryType Type,
llvm::StringRef SubdirParent = "") const;
@@ -100,8 +98,8 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain {
void AddHIPRuntimeLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;
- bool getWindowsSDKLibraryPath(
- const llvm::opt::ArgList &Args, std::string &path) const;
+ bool getWindowsSDKLibraryPath(const llvm::opt::ArgList &Args,
+ std::string &path) const;
bool getUniversalCRTLibraryPath(const llvm::opt::ArgList &Args,
std::string &path) const;
bool useUniversalCRT() const;
@@ -132,7 +130,23 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain {
Tool *buildLinker() const override;
Tool *buildAssembler() const override;
+
private:
+ CXXStdlibType GetDefaultCXXStdlibType() const override {
+ return ToolChain::CST_Stl;
+ }
+ RuntimeLibType GetDefaultRuntimeLibType() const override {
+ return ToolChain::RLT_Vcruntime;
+ }
+ UnwindLibType GetDefaultUnwindLibType() const override {
+ return ToolChain::UNW_Vcruntime;
+ }
+ void addStlIncludePaths(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const;
+ void addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const;
+ void addLibStdCXXIncludePaths(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const;
std::optional<llvm::StringRef> WinSdkDir, WinSdkVersion, WinSysRoot;
std::string VCToolChainPath;
llvm::ToolsetLayout VSLayout = llvm::ToolsetLayout::OlderVS;
diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 60bd97e0ee987..0c839e6916b21 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -460,6 +460,8 @@ WebAssembly::GetCXXStdlibType(const ArgList &Args) const {
return ToolChain::CST_Libcxx;
else if (Value == "libstdc++")
return ToolChain::CST_Libstdcxx;
+ else if (Value == "stl")
+ return ToolChain::CST_Stl;
else
getDriver().Diag(diag::err_drv_invalid_stdlib_name)
<< A->getAsString(Args);
@@ -518,6 +520,11 @@ void WebAssembly::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
case ToolChain::CST_Libstdcxx:
addLibStdCXXIncludePaths(DriverArgs, CC1Args);
break;
+ case ToolChain::CST_Stl:
+ addStlIncludePaths(DriverArgs, CC1Args);
+ break;
+ default:
+ break;
}
}
@@ -534,6 +541,8 @@ void WebAssembly::AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
case ToolChain::CST_Libstdcxx:
CmdArgs.push_back("-lstdc++");
break;
+ default:
+ break;
}
}
@@ -552,6 +561,26 @@ Tool *WebAssembly::buildLinker() const {
return new tools::wasm::Linker(*this);
}
+void WebAssembly::addStlIncludePaths(
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const {
+ const Driver &D = getDriver();
+ std::string SysRoot = computeSysRoot();
+ std::string LibPath = SysRoot + "/include";
+ const std::string MultiarchTriple =
+ getMultiarchTriple(D, getTriple(), SysRoot);
+ bool IsKnownOs = (getTriple().getOS() != llvm::Triple::UnknownOS);
+
+ // First add the per-target include path if the OS is known.
+ if (IsKnownOs) {
+ std::string TargetDir = LibPath + "/" + MultiarchTriple + "/c++/stl";
+ addSystemInclude(DriverArgs, CC1Args, TargetDir);
+ }
+
+ // Second add the generic one.
+ addSystemInclude(DriverArgs, CC1Args, LibPath + "/c++/stl");
+}
+
void WebAssembly::addLibCxxIncludePaths(
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
diff --git a/clang/lib/Driver/ToolChains/WebAssembly.h b/clang/lib/Driver/ToolChains/WebAssembly.h
index 76e0ca39bd748..7470b5ed9db0f 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.h
+++ b/clang/lib/Driver/ToolChains/WebAssembly.h
@@ -79,6 +79,8 @@ class LLVM_LIBRARY_VISIBILITY WebAssembly final : public ToolChain {
const llvm::Triple &TargetTriple,
StringRef SysRoot) const override;
+ void addStlIncludePaths(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const;
void addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const;
void addLibStdCXXIncludePaths(const llvm::opt::ArgList &DriverArgs,
diff --git a/clang/test/Driver/msvc-sysroot.cpp b/clang/test/Driver/msvc-sysroot.cpp
new file mode 100644
index 0000000000000..983e530f09955
--- /dev/null
+++ b/clang/test/Driver/msvc-sysroot.cpp
@@ -0,0 +1,81 @@
+// RUN: %clangxx --target=x86_64-unknown-windows-msvc -### \
+// RUN: --sysroot=%S -fuse-ld=lld %s 2>&1 \
+// RUN: | FileCheck --check-prefix=COMPILE_X86_64_STL %s
+// COMPILE_X86_64_STL: clang{{.*}}" "-cc1"
+// COMPILE_X86_64_STL: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_X86_64_STL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/x86_64-unknown-windows-msvc/c++/stl"
+// COMPILE_X86_64_STL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/stl"
+// COMPILE_X86_64_STL: lld-link{{.*}}" "-libpath:[[SYSROOT:[^"]+]]/lib/x86_64-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib"
+
+// RUN: %clangxx --target=x86_64-unknown-windows-msvc -### \
+// RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree/usr -stdlib=libc++ -fuse-ld=lld %s 2>&1 \
+// RUN: | FileCheck --check-prefix=COMPILE_X86_64_LIBCXX %s
+// COMPILE_X86_64_LIBCXX: clang{{.*}}" "-cc1"
+// COMPILE_X86_64_LIBCXX: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_X86_64_LIBCXX: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/x86_64-unknown-windows-msvc/c++/v1"
+// COMPILE_X86_64_LIBCXX: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/v1"
+// COMPILE_X86_64_LIBCXX: lld-link{{.*}}" "-libpath:[[SYSROOT:[^"]+]]/lib/x86_64-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib"
+
+// RUN: %clangxx -### --target=x86_64-unknown-windows-msvc --stdlib=libstdc++ %s 2>&1 \
+// RUN: -fuse-ld=lld --sysroot=%S/Inputs/basic_linux_libstdcxx_libcxxv2_tree/usr \
+// RUN: | FileCheck -check-prefix=COMPILE_X86_64_LIBSTDCXX %s
+// COMPILE_X86_64_LIBSTDCXX: "-cc1"
+// COMPILE_X86_64_LIBSTDCXX: "-resource-dir" "[[RESOURCE_DIR:[^"]*]]"
+// COMPILE_X86_64_LIBSTDCXX: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_X86_64_LIBSTDCXX: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/4.8/x86_64-unknown-windows-msvc"
+// COMPILE_X86_64_LIBSTDCXX: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/4.8"
+// COMPILE_X86_64_LIBSTDCXX: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/4.8/backward"
+// COMPILE_X86_64_LIBSTDCXX: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include"
+// COMPILE_X86_64_LIBSTDCXX: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/x86_64-unknown-windows-msvc"
+// COMPILE_X86_64_LIBSTDCXX: "-internal-isystem" "[[SYSROOT:[^"]+]]/include"
+// COMPILE_X86_64_LIBSTDCXX: lld-link{{.*}}" "-libpath:[[SYSROOT:[^"]+]]/lib/x86_64-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib"
+
+// RUN: %clangxx --target=aarch64-unknown-windows-msvc -### \
+// RUN: --sysroot=%S -fuse-ld=lld %s 2>&1 \
+// RUN: | FileCheck --check-prefix=COMPILE_AARCH64_STL %s
+// COMPILE_AARCH64_STL: clang{{.*}}" "-cc1"
+// COMPILE_AARCH64_STL: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_AARCH64_STL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/aarch64-unknown-windows-msvc/c++/stl"
+// COMPILE_AARCH64_STL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/stl"
+// COMPILE_AARCH64_STL: lld-link{{.*}}" "-libpath:[[SYSROOT:[^"]+]]/lib/aarch64-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib"
+
+// RUN: %clangxx --target=loongarch64-unknown-windows-msvc -stdlib=stl -### \
+// RUN: --sysroot=%S -fuse-ld=lld %s 2>&1 \
+// RUN: | FileCheck --check-prefix=COMPILE_LOONGARCH64_STL %s
+// COMPILE_LOONGARCH64_STL: clang{{.*}}" "-cc1"
+// COMPILE_LOONGARCH64_STL: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_LOONGARCH64_STL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/loongarch64-unknown-windows-msvc/c++/stl"
+// COMPILE_LOONGARCH64_STL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/stl"
+// COMPILE_LOONGARCH64_STL: lld-link{{.*}}" "-libpath:[[SYSROOT:[^"]+]]/lib/loongarch64-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib"
+
+// RUN: %clangxx --target=x86_64-unknown-windows-msvc -stdlib=stl -### \
+// RUN: --sysroot=%S %s 2>&1 \
+// RUN: | FileCheck --check-prefix=COMPILE_X86_64_STL_LINK %s
+// COMPILE_X86_64_STL_LINK: clang{{.*}}" "-cc1"
+// COMPILE_X86_64_STL_LINK: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_X86_64_STL_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/x86_64-unknown-windows-msvc/c++/stl"
+// COMPILE_X86_64_STL_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/stl"
+// COMPILE_X86_64_STL_LINK: link.exe{{.*}}" "-libpath:[[SYSROOT:[^"]+]]/lib/x86_64-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib"
+
+// RUN: %clangxx --target=loongarch64-unknown-windows-msvc -stdlib=libc++ -### \
+// RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree/usr %s 2>&1 \
+// RUN: | FileCheck --check-prefix=COMPILE_LOONGARCH64_STL_LINK %s
+// COMPILE_LOONGARCH64_STL_LINK: clang{{.*}}" "-cc1"
+// COMPILE_LOONGARCH64_STL_LINK: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_LOONGARCH64_STL_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/loongarch64-unknown-windows-msvc/c++/v1"
+// COMPILE_LOONGARCH64_STL_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/v1"
+// COMPILE_LOONGARCH64_STL_LINK: link.exe{{.*}}" "-libpath:[[SYSROOT:[^"]+]]/lib/loongarch64-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib"
+
+// RUN: %clangxx --target=riscv64-unknown-windows-msvc -### --stdlib=libstdc++ %s 2>&1 \
+// RUN: --sysroot=%S/Inputs/basic_linux_libstdcxx_libcxxv2_tree/usr \
+// RUN: | FileCheck -check-prefix=COMPILE_RISCV64_LIBSTDCXX_LINK %s
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-cc1"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-resource-dir" "[[RESOURCE_DIR:[^"]*]]"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/4.8/riscv64-unknown-windows-msvc"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/4.8"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/4.8/backward"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/riscv64-unknown-windows-msvc"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: link.exe{{.*}}" "-libpath:[[SYSROOT:[^"]+]]/lib/riscv64-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib"
diff --git a/clang/test/Driver/wasm-toolchain.cpp b/clang/test/Driver/wasm-toolchain.cpp
index ba1c55b33edca..203e3d0d99a3e 100644
--- a/clang/test/Driver/wasm-toolchain.cpp
+++ b/clang/test/Driver/wasm-toolchain.cpp
@@ -86,3 +86,15 @@
// COMPILE_STDCXX: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include"
// COMPILE_STDCXX: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/wasm32-wasi"
// COMPILE_STDCXX: "-internal-isystem" "[[SYSROOT:[^"]+]]/include"
+
+// RUN: %clangxx -### --target=wasm32-wasi --stdlib=stl %s 2>&1 \
+// RUN: --sysroot=%S \
+// RUN: | FileCheck -check-prefix=COMPILE_STL %s
+// COMPILE_STL: "-cc1"
+// COMPILE_STL: "-resource-dir" "[[RESOURCE_DIR:[^"]*]]"
+// COMPILE_STL: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_STL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/wasm32-wasi/c++/stl"
+// COMPILE_STL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/stl"
+// COMPILE_STL: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include"
+// COMPILE_STL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/wasm32-wasi"
+// COMPILE_STL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include"
\ No newline at end of file
More information about the cfe-commits
mailing list