-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[clang] Support --sysroot= for ${arch}-windows-msvc targets #96417
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write If you have received no comments on your PR for a week, you can request a review If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-backend-systemz @llvm/pr-subscribers-clang-driver Author: cqwrteur (trcrsired) ChangesI think it is possible to use the same rule for msvc targets with --target= and --sysroot= See Repository: C++ standard library headers: With -stdlib=libc++, headers should be located in include/c++/v1 Libraries For example. on x86_64-windows-msvc, it should find libs in lib/x86_64-windows-msvc Full diff: https://github.com/llvm/llvm-project/pull/96417.diff 5 Files Affected:
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/test/Driver/msvc-sysroot.cpp b/clang/test/Driver/msvc-sysroot.cpp
new file mode 100644
index 0000000000000..9e58729ec57e9
--- /dev/null
+++ b/clang/test/Driver/msvc-sysroot.cpp
@@ -0,0 +1,11 @@
+// RUN: %clangxx --target=x86_64-unknown-windows-msvc -### --sysroot=%S -fuse-ld=lld %s 2>&1 | FileCheck --check-prefix=COMPILE %s
+// COMPILE: clang{{.*}}" "-cc1"
+// COMPILE: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/x86_64-unknown-windows-msvc/c++/stl"
+// COMPILE: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/stl"
+
+// RUN: %clangxx --target=aarch64-unknown-windows-msvc -### --sysroot=%S -fuse-ld=lld %s 2>&1 | FileCheck --check-prefix=COMPILE %s
+// COMPILE: clang{{.*}}" "-cc1"
+// COMPILE: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/aarch64-unknown-windows-msvc/c++/stl"
+// COMPILE: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/stl"
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've read half the patch so far, but wanted to ask before continuing: would it be possible (and simpler) to extend the /winsysroot support somehow to also handle --sysroot?
(It would also be easier to review if the unrelated formatting changes were removed or split to a separate PR.)
no. i do not use clang-cl. /winsysroot is not sysroot. /winsysroot is for clang-cl. not clang itself sysroot is what the usually the clang and GCC means. That is not a semantics for msvc. I have checked the code first clang does not support /winsysroot, second they have very different meanings which make them incompatible. Just use --sysroot because --sysroot matches the behavior of other platforms, including GNU variants of windows targets like x86_64-windows-gnu. BTW using --sysroot gives the same semantics for build systems like build tools cmake or xmake. |
I have avoided formatting as much as possible. However, the llvm CI does not pass if I do not format it. |
I didn't mean that you should use |
They couldn't. They mean different things.
Other toggles only work when --sysroot is null. This is a completely different setting than winsysroot and many other settings such as environmental variables. winsysroot still references environmental variable, which are completely different behavior. I suggest deprecating winsysroot completely.
|
@zmodem Looks like clang-formatting makes you harder to review the code, I will try to use the upstream code and avoiding formatting. |
d716838
to
e3f96da
Compare
@zmodem Can you review it again? I have removed the formatting part here. Although I disagree with -stdlib=msstl thing. Can you check any other part that is problematic first? Ty |
What's the practical difference here, between just providing the libc++ includes in a path that is searched before the main MSVC include directory? (One difference that comes to mind is that it doesn't accidentally use an STL header if libc++ doesn't provide a corresponding one.) It's worth remembering that libc++ in MSVC mode practically still is layered on top of STL/vcruntime for some of the lower level bits. |
FWIW, http://github.com/mstorsjo/msvc-wine/ also provides a non-rust solution to the same, which also provides a lowercased/symlink forest variant of includes/libraries. |
It works really well. The only slight downside is that the case handling for WinRT headers is still a bit patchy, though that's not really a problem since we'll prefer the generated headers from cppwinrt, with WinSDK as a fallback. But sysroot is also more convenient for cppwinrt in this case, since we can just output cppwinrt to sysroot/include without having to manually add another search path. (The same applies to winsysroot, but the location of the winrt directory in winsysroot is obviously more complicated than sysroot/include.) |
You're half right. When the STL adds a header before libc++ does, |
it does not make sense when you oppose a third party developer for providing a sysroot when you are literally doing the same by referencing another 3rd party project which is xwin. Real advantages? I do not want to use clang-cl since it is hard for my cross build scripts to run. full stop. Btw relying on wine is another thing i think is no-go. Apple silicon mac still does not support wine natively for example. Tons of platforms do not support wine (like all targets of riscv and loongarch). You cannot expect people to cross compile windows applications by emulating a windows environment, that is not even cross compiling. The entire debate is just not constructive in my opinion when sysroot =include, lib, share,bin are literally every other platform, including mingw, cygwin and wasm doing. Why would you try to create inconsistent variant? |
Do we have any microsoft developers in this LLVM project? I am willing to negoiate with them to transfer thw windows-msvc-sysroot ownership to them to let them maintain the project. |
Well, we built Clearly, just as their are folks porting MSVC codebases to Linux, there will be users porting autotools builds to Windows, and I don't see any reason to value their use case less than that of the MSVC-migrating users. So, that's the use case for using the
To try to steelman the objections I'm hearing, it's basically that having two ways to do things leads to confusion and makes it hard to find the supported, well-lit-paths for cross-compilation. When you have too many options, you get unopinionated guides that overwhelm users with choice and confusion. Recent examples that come to mind for me are the Arch wiki installation guide and the LLVM Getting Started page. I acknowledge these are real downsides, but I think the value of a If I had to pick a best approach to recommend, I like the idea of implementing case-insensitive header search, and wiring that into a |
If the llvm is making the decision to merge the PR, i am willing to change the name of stl to msstl and it would find headers in include/c++/msstl. |
I think in the perfect world, microsoft should themselves just adopt the standard sysroot behavior for msvc. I am willing to have a discussion with microsoft developers myself. |
Before we merge this, I feel we should have very clear documentation on both existing functionality—that is, Merely redirecting to some OSS project that could be abandoned is not sufficient in my opinion. To be entirely honest I don't see how this will be any different to the current complexity especially in a cross-compile scenario, because WinKits/VC is—as mentioned above—not redistributable. We are merely moving from 'use xwin or msvc-wine' or 'use a case-insensitive FS' to 'use this Python script'. The end user still needs to manually set up a sysroot in more than one non-trivial step. Compare this to targeting Alpine Linux from glibc Linux, or targeting MinGW from anything else, where it's a matter of |
Why would it get abandoned? I am here to maintain it. Why would i abandon my own project? By the way i have said i am willing to transfer the windows-msvc-sysroot to Microsoft. No one is asking you to use python script bro. You can just put the files together by yourself. And why would you use sudo pacman -S mingw-w64-gcc? I really do not think you know how to cross compile windows programs tbh. I just feel the entire discussion by you and some others here are not constructive at all since you do not even have a basic understanding of how to build cross toolchain to begin with. sysroot/include They are common idoims for anyone who know how to build cross toolchain for GCC or LLVM to know. If you do not know how to put those files together, then you do not know how to build any target's cross toolchain. |
There are a lot of unfounded accusations with which I will not engage. There are practical reasons for why an organisation will not take on a dependency or stewardship of a certain project, but they are also irrelevant. My points about pacman was to demonstrate how easy setting up a MinGW cross-compile toolchain is. It is literally two commands on most Linux systems: download the sysroot and the compiler (both from the package manager), compile. Done. All I am saying is—please write some documentation, and enhance the existing documentation for In particular, I would like to see:
I hope this is considered, because I feel there's no point in providing a feature without any documentation. Once this is merged this entire issue and thread will disappear from search engines, and it will become a black hole. |
Unlike LLVM, x86_64-w64-mingw32-gcc bundles its sysroot within itself. Ok. I will try to add documentations to LLVM. |
Just to be clear - nobody here has suggested using wine for anything here. My repo http://github.com/mstorsjo/msvc-wine/ contains pure python/shell/perl scripts for downloading and unpacking MSVC. No wine needed. It also contains shell script wrappers for transparently using MSVC as if it was a native tool, using wine - but that's optional, you can use it just for downloading and getting MSVC libraries for use with Clang/LLVM without any use of wine anywhere. The repo name predates the downloader/unpacker. |
still i do not see what is your objection to GNU style --sysroot for clang since that is what it designed for. |
f583626
to
324120b
Compare
324120b
to
edf6b40
Compare
Hello everyone, I have completed all the necessary updates:
Note: The -stdlib=msstl flag also applies to MinGW. It's possible that the mingw-w64 project could explore integration with Microsoft's STL. Additionally, ntdll.dll is now consistently linked alongside kernel32.dll. All supported Windows versions are NT-based, and even legacy systems like Windows 95 include ntdll.dll. |
3536350
to
4b5c87d
Compare
4b5c87d
to
1be554d
Compare
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 Avoid clang-formatting in MSVC.cpp Add some comments to ToolChain avoid indent the if block Add back space before winsysroot line use instead of arch in the comment remove FIXME for libc++ since we have added the logic here Remove MSVC.h formatting Remove default cases in WebAssembly add back the empty line before the Sysroot line fix msvc-sysroot typo for libc++ loongarch Fix : missing in CST_Stl case 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 Avoid clang-formatting in MSVC.cpp Add some comments to ToolChain avoid indent the if block Add back space before winsysroot line use instead of arch in the comment remove FIXME for libc++ since we have added the logic here Remove MSVC.h formatting Remove default cases in WebAssembly add back the empty line before the Sysroot line fix msvc-sysroot typo for libc++ loongarch Fix : missing in CST_Stl case [clang] update msvc-sysroot.cpp tep to test arm64ec and arm64x [clang] Add arm64ec -windows-msvc support for msvc sysroot by finding libs in the aarch64-unknown-windows-msvc subdir MSVC target needs to include Gnu.h to support libstdc++ [clang] fix formatting issues for MSVC sysroot PR [clang] 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 Avoid clang-formatting in MSVC.cpp Add some comments to ToolChain avoid indent the if block Add back space before winsysroot line use instead of arch in the comment remove FIXME for libc++ since we have added the logic here Remove MSVC.h formatting Remove default cases in WebAssembly add back the empty line before the Sysroot line fix msvc-sysroot typo for libc++ loongarch Fix : missing in CST_Stl case 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 Avoid clang-formatting in MSVC.cpp Add some comments to ToolChain avoid indent the if block Add back space before winsysroot line use instead of arch in the comment remove FIXME for libc++ since we have added the logic here Remove MSVC.h formatting Remove default cases in WebAssembly add back the empty line before the Sysroot line fix msvc-sysroot typo for libc++ loongarch Fix : missing in CST_Stl case [clang] update msvc-sysroot.cpp tep to test arm64ec and arm64x [clang] Add arm64ec -windows-msvc support for msvc sysroot by finding libs in the aarch64-unknown-windows-msvc subdir MSVC target needs to include Gnu.h to support libstdc++ [clang] fix formatting issues for MSVC sysroot PR [clang] Driver.cpp's formatting issue [clang] Driver itself needs to be passed into CxxModulePathEvaluate [clang] Fix Driver discards const qualifiers [clang] Fix remaining unhandled msstl and also add msstl to mingw We also always -lntdll since gcc with mcf alrady does that. Even on windows 9x the linker would still discard -lntdll and ntdll.dll does exist on windows 95 [clang] Darwin still did not handle msstl
1be554d
to
568f4f2
Compare
@mortbopet I have removed the change of MinGW.cpp for adding -lntdll. Can i have a look? If everyone agrees here, then please merge it. I have seperated -lntdll into a seperate PR which is #162997 |
hi? Can any reviewer here review the PR? it has been a week of no response |
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
Headers
Windows + CRT Headers Include Directory: include
C++ standard library headers:
With -stdlib=stl, headers should be located in include/c++/stl
(To change: -stdlib=msstl, headers should be located in include/c++/msstl)
With -stdlib=libc++, headers should be located in include/c++/v1
With -stdlib=libstdc++, headers should be located in include/c++/16.0.0 (GCC version)
Libraries
Libraries should be placed in lib/$TRIPLET
Bins
Bins should be placed in bin/$TRIPLET
For example. on x86_64-unknown-windows-msvc, it should find libs in lib/x86_64-unknown-windows-msvc