@@ -90,6 +90,16 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
9090 CmdArgs.push_back (" -defaultlib:oldnames" );
9191 }
9292
93+ auto SysRoot = TC.getDriver ().SysRoot ;
94+ if (!SysRoot.empty ()) {
95+ // If we have --sysroot, then we ignore all other setings
96+ // libpath is $SYSROOT/lib and $SYSROOT/lib/${ARCH}-unknown-windows-msvc
97+ const std::string MultiarchTriple =
98+ TC.getMultiarchTriple (TC.getDriver (), TC.getTriple (), SysRoot);
99+ std::string SysRootLib = " -libpath:" + SysRoot + " /lib" ;
100+ CmdArgs.push_back (Args.MakeArgString (SysRootLib + ' /' + MultiarchTriple));
101+ CmdArgs.push_back (Args.MakeArgString (SysRootLib));
102+ } else {
93103 // If the VC environment hasn't been configured (perhaps because the user
94104 // did not run vcvarsall), try to build a consistent link environment. If
95105 // the environment variable is set however, assume the user knows what
@@ -133,6 +143,7 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
133143 CmdArgs.push_back (
134144 Args.MakeArgString (std::string (" -libpath:" ) + WindowsSdkLibPath));
135145 }
146+ }
136147
137148 if (!C.getDriver ().IsCLMode () && Args.hasArg (options::OPT_L))
138149 for (const auto &LibPath : Args.getAllArgValues (options::OPT_L))
@@ -430,6 +441,12 @@ MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
430441 RocmInstallation(D, Triple, Args) {
431442 getProgramPaths ().push_back (getDriver ().Dir );
432443
444+ auto SysRoot = getDriver ().SysRoot ;
445+ if (!SysRoot.empty ()) {
446+ // We have sysroot so we ignore all VCTools settings
447+ return ;
448+ }
449+
433450 std::optional<llvm::StringRef> VCToolsDir, VCToolsVersion;
434451 if (Arg *A = Args.getLastArg (options::OPT__SLASH_vctoolsdir))
435452 VCToolsDir = A->getValue ();
@@ -647,6 +664,17 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
647664 " include" );
648665 }
649666
667+ auto SysRoot = getDriver ().SysRoot ;
668+ if (!SysRoot.empty ()) {
669+ const Driver &D = getDriver ();
670+ const std::string MultiarchTriple =
671+ getMultiarchTriple (D, getTriple (), SysRoot);
672+ addSystemInclude (DriverArgs, CC1Args,
673+ SysRoot + " /include/" + MultiarchTriple);
674+ addSystemInclude (DriverArgs, CC1Args, SysRoot + " /include" );
675+ return ;
676+ }
677+
650678 // Add %INCLUDE%-like directories from the -imsvc flag.
651679 for (const auto &Path : DriverArgs.getAllArgValues (options::OPT__SLASH_imsvc))
652680 addSystemInclude (DriverArgs, CC1Args, Path);
@@ -775,7 +803,22 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
775803
776804void MSVCToolChain::AddClangCXXStdlibIncludeArgs (const ArgList &DriverArgs,
777805 ArgStringList &CC1Args) const {
778- // FIXME: There should probably be logic here to find libc++ on Windows.
806+ if (DriverArgs.hasArg (options::OPT_nostdinc, options::OPT_nostdlibinc,
807+ options::OPT_nostdincxx))
808+ return ;
809+ if (getDriver ().SysRoot .empty ())
810+ return ;
811+ switch (GetCXXStdlibType (DriverArgs)) {
812+ case ToolChain::CST_Stl:
813+ addStlIncludePaths (DriverArgs, CC1Args);
814+ break ;
815+ case ToolChain::CST_Libstdcxx:
816+ addLibStdCXXIncludePaths (DriverArgs, CC1Args);
817+ break ;
818+ case ToolChain::CST_Libcxx:
819+ addLibCxxIncludePaths (DriverArgs, CC1Args);
820+ break ;
821+ }
779822}
780823
781824VersionTuple MSVCToolChain::computeMSVCVersion (const Driver *D,
@@ -1027,3 +1070,86 @@ void MSVCToolChain::addClangTargetOptions(
10271070 if (Arg *A = DriverArgs.getLastArgNoClaim (options::OPT_marm64x))
10281071 A->ignoreTargetSpecific ();
10291072}
1073+
1074+ void MSVCToolChain::addStlIncludePaths (
1075+ const llvm::opt::ArgList &DriverArgs,
1076+ llvm::opt::ArgStringList &CC1Args) const {
1077+ const Driver &D = getDriver ();
1078+ std::string SysRoot = computeSysRoot ();
1079+ std::string LibPath = SysRoot + " /include" ;
1080+ const std::string MultiarchTriple =
1081+ getMultiarchTriple (D, getTriple (), SysRoot);
1082+
1083+ std::string TargetDir = LibPath + " /" + MultiarchTriple + " /c++/stl" ;
1084+ addSystemInclude (DriverArgs, CC1Args, TargetDir);
1085+
1086+ // Second add the generic one.
1087+ addSystemInclude (DriverArgs, CC1Args, LibPath + " /c++/stl" );
1088+ }
1089+
1090+ void MSVCToolChain::addLibCxxIncludePaths (
1091+ const llvm::opt::ArgList &DriverArgs,
1092+ llvm::opt::ArgStringList &CC1Args) const {
1093+ const Driver &D = getDriver ();
1094+ std::string SysRoot = computeSysRoot ();
1095+ std::string LibPath = SysRoot + " /include" ;
1096+ const std::string MultiarchTriple =
1097+ getMultiarchTriple (D, getTriple (), SysRoot);
1098+
1099+ std::string Version = detectLibcxxVersion (LibPath);
1100+ if (Version.empty ())
1101+ return ;
1102+
1103+ std::string TargetDir = LibPath + " /" + MultiarchTriple + " /c++/" + Version;
1104+ addSystemInclude (DriverArgs, CC1Args, TargetDir);
1105+
1106+ // Second add the generic one.
1107+ addSystemInclude (DriverArgs, CC1Args, LibPath + " /c++/" + Version);
1108+ }
1109+
1110+ void MSVCToolChain::addLibStdCXXIncludePaths (
1111+ const llvm::opt::ArgList &DriverArgs,
1112+ llvm::opt::ArgStringList &CC1Args) const {
1113+ // We cannot use GCCInstallationDetector here as the sysroot usually does
1114+ // not contain a full GCC installation.
1115+ // Instead, we search the given sysroot for /usr/include/xx, similar
1116+ // to how we do it for libc++.
1117+ const Driver &D = getDriver ();
1118+ std::string SysRoot = computeSysRoot ();
1119+ std::string LibPath = SysRoot + " /include" ;
1120+ const std::string MultiarchTriple =
1121+ getMultiarchTriple (D, getTriple (), SysRoot);
1122+
1123+ // This is similar to detectLibcxxVersion()
1124+ std::string Version;
1125+ {
1126+ std::error_code EC;
1127+ Generic_GCC::GCCVersion MaxVersion =
1128+ Generic_GCC::GCCVersion::Parse (" 0.0.0" );
1129+ SmallString<128 > Path (LibPath);
1130+ llvm::sys::path::append (Path, " c++" );
1131+ for (llvm::vfs::directory_iterator LI = getVFS ().dir_begin (Path, EC), LE;
1132+ !EC && LI != LE; LI = LI.increment (EC)) {
1133+ StringRef VersionText = llvm::sys::path::filename (LI->path ());
1134+ if (VersionText[0 ] != ' v' ) {
1135+ auto Version = Generic_GCC::GCCVersion::Parse (VersionText);
1136+ if (Version > MaxVersion)
1137+ MaxVersion = Version;
1138+ }
1139+ }
1140+ if (MaxVersion.Major > 0 )
1141+ Version = MaxVersion.Text ;
1142+ }
1143+
1144+ if (Version.empty ())
1145+ return ;
1146+
1147+ std::string TargetDir = LibPath + " /c++/" + Version + " /" + MultiarchTriple;
1148+ addSystemInclude (DriverArgs, CC1Args, TargetDir);
1149+
1150+ // Second add the generic one.
1151+ addSystemInclude (DriverArgs, CC1Args, LibPath + " /c++/" + Version);
1152+ // Third the backward one.
1153+ addSystemInclude (DriverArgs, CC1Args,
1154+ LibPath + " /c++/" + Version + " /backward" );
1155+ }
0 commit comments