From a4230319f7af786f4d947f39a870f339b32a6fe7 Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Thu, 18 Aug 2022 03:33:34 +0000 Subject: [PATCH] [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 --- clang/include/clang/Driver/Options.td | 6 ++-- clang/lib/Driver/ToolChains/MSVC.cpp | 36 ++++++++++++++++++- .../Inputs/msvc_libcxx_tree/usr/bin/.keep | 0 .../msvc_libcxx_tree/usr/include/c++/v1/.keep | 0 .../x86_64-pc-windows-msvc/c++/v1/.keep | 0 .../Inputs/msvc_libcxx_tree/usr/lib/.keep | 0 .../usr/lib/x86_64-pc-windows-msvc/.keep | 0 clang/test/Driver/msvc-libcxx.cpp | 7 ++++ 8 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 clang/test/Driver/Inputs/msvc_libcxx_tree/usr/bin/.keep create mode 100644 clang/test/Driver/Inputs/msvc_libcxx_tree/usr/include/c++/v1/.keep create mode 100644 clang/test/Driver/Inputs/msvc_libcxx_tree/usr/include/x86_64-pc-windows-msvc/c++/v1/.keep create mode 100644 clang/test/Driver/Inputs/msvc_libcxx_tree/usr/lib/.keep create mode 100644 clang/test/Driver/Inputs/msvc_libcxx_tree/usr/lib/x86_64-pc-windows-msvc/.keep create mode 100644 clang/test/Driver/msvc-libcxx.cpp diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 8c9901d086ee..216560cfc86e 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4017,12 +4017,12 @@ def noprofilelib : Flag<["-"], "noprofilelib">; def noseglinkedit : Flag<["-"], "noseglinkedit">; def nostartfiles : Flag<["-"], "nostartfiles">, 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>; def nostdlib : Flag<["-"], "nostdlib">, Group; -def nostdlibxx : Flag<["-"], "nostdlib++">; +def nostdlibxx : Flag<["-"], "nostdlib++">, Group; def object : Flag<["-"], "object">; def o : JoinedOrSeparate<["-"], "o">, Flags<[NoXarchOption, RenderAsInput, CC1Option, CC1AsOption, FC1Option, FlangOption]>, diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index 14ebe38ee191..e8d6178fdfa1 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -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, diff --git a/clang/test/Driver/Inputs/msvc_libcxx_tree/usr/bin/.keep b/clang/test/Driver/Inputs/msvc_libcxx_tree/usr/bin/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/msvc_libcxx_tree/usr/include/c++/v1/.keep b/clang/test/Driver/Inputs/msvc_libcxx_tree/usr/include/c++/v1/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/msvc_libcxx_tree/usr/include/x86_64-pc-windows-msvc/c++/v1/.keep b/clang/test/Driver/Inputs/msvc_libcxx_tree/usr/include/x86_64-pc-windows-msvc/c++/v1/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/msvc_libcxx_tree/usr/lib/.keep b/clang/test/Driver/Inputs/msvc_libcxx_tree/usr/lib/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/msvc_libcxx_tree/usr/lib/x86_64-pc-windows-msvc/.keep b/clang/test/Driver/Inputs/msvc_libcxx_tree/usr/lib/x86_64-pc-windows-msvc/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/msvc-libcxx.cpp b/clang/test/Driver/msvc-libcxx.cpp new file mode 100644 index 000000000000..c209ec9aca24 --- /dev/null +++ b/clang/test/Driver/msvc-libcxx.cpp @@ -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"