[Driver] Support libc++ in MSVC

This implements support for using libc++ headers in MSVC toolchain.
We only support libc++ headers that are part of the toolchain, and
not headers installed elsewhere on the system.

Differential Revision: https://reviews.llvm.org/D101479
This commit is contained in:
Petr Hosek 2022-08-18 03:33:34 +00:00
parent e33599371e
commit a4230319f7
8 changed files with 45 additions and 4 deletions

View File

@ -4017,12 +4017,12 @@ def noprofilelib : Flag<["-"], "noprofilelib">;
def noseglinkedit : Flag<["-"], "noseglinkedit">;
def nostartfiles : Flag<["-"], "nostartfiles">, Group<Link_Group>;
def nostdinc : Flag<["-"], "nostdinc">, Flags<[CoreOption]>;
def nostdlibinc : Flag<["-"], "nostdlibinc">;
def nostdincxx : Flag<["-"], "nostdinc++">, Flags<[CC1Option]>,
def nostdlibinc : Flag<["-"], "nostdlibinc">, Flags<[CoreOption]>;
def nostdincxx : Flag<["-"], "nostdinc++">, Flags<[CC1Option, CoreOption]>,
HelpText<"Disable standard #include directories for the C++ standard library">,
MarshallingInfoNegativeFlag<HeaderSearchOpts<"UseStandardCXXIncludes">>;
def nostdlib : Flag<["-"], "nostdlib">, Group<Link_Group>;
def nostdlibxx : Flag<["-"], "nostdlib++">;
def nostdlibxx : Flag<["-"], "nostdlib++">, Group<Link_Group>;
def object : Flag<["-"], "object">;
def o : JoinedOrSeparate<["-"], "o">, Flags<[NoXarchOption, RenderAsInput,
CC1Option, CC1AsOption, FC1Option, FlangOption]>,

View File

@ -153,6 +153,11 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (!C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
for (const auto &LibPath : Args.getAllArgValues(options::OPT_L))
CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath));
// Add library directories for standard library shipped with the toolchain.
for (const auto &LibPath : TC.getFilePaths()) {
if (TC.getVFS().exists(LibPath))
CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath));
}
CmdArgs.push_back("-nologo");
@ -741,7 +746,36 @@ 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_nostdlibinc) ||
DriverArgs.hasArg(options::OPT_nostdincxx))
return;
switch (GetCXXStdlibType(DriverArgs)) {
case ToolChain::CST_Libcxx: {
SmallString<128> P(getDriver().Dir);
llvm::sys::path::append(P, "..", "include");
std::string Version = detectLibcxxVersion(P);
if (Version.empty())
return;
// First add the per-target include path if it exists.
SmallString<128> TargetDir(P);
llvm::sys::path::append(TargetDir, getTripleString(), "c++", Version);
if (getVFS().exists(TargetDir))
addSystemInclude(DriverArgs, CC1Args, TargetDir);
// Second add the generic one.
SmallString<128> Dir(P);
llvm::sys::path::append(Dir, "c++", Version);
addSystemInclude(DriverArgs, CC1Args, Dir);
break;
}
default:
// TODO: Shall we report an error for other C++ standard libraries?
break;
}
}
VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,

View File

@ -0,0 +1,7 @@
// RUN: %clangxx -### %s 2>&1 -stdlib=libc++ -fuse-ld=lld \
// RUN: --target=x86_64-pc-windows-msvc \
// RUN: -ccc-install-dir %S/Inputs/msvc_libcxx_tree/usr/bin \
// RUN: | FileCheck %s -check-prefix MSVC-LIBCXX
// MSVC-LIBCXX: "-internal-isystem" "{{.*[/\\]}}include{{/|\\\\}}x86_64-pc-windows-msvc{{/|\\\\}}c++{{/|\\\\}}v1"
// MSVC-LIBCXX: "-internal-isystem" "{{.*[/\\]}}include{{/|\\\\}}c++{{/|\\\\}}v1"
// MSVC-LIBCXX: "-libpath:{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-pc-windows-msvc"