From 1b363a46f7845c67019f432f429f96cf64a99f4e Mon Sep 17 00:00:00 2001 From: Jonas Hahnfeld Date: Fri, 12 Feb 2016 07:48:37 +0000 Subject: [PATCH] [CMake] Add option to switch default C++ stdlib With this option one can optionally override the architecture dependent default library to use if no -stdlib= is provided on compiler invocation. Differential Revision: http://reviews.llvm.org/D15920 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@260662 91177308-0d34-0410-b5e6-96231b3b80d8 --- CMakeLists.txt | 9 ++++++++ include/clang/Config/config.h.cmake | 3 +++ include/clang/Config/config.h.in | 3 +++ include/clang/Driver/ToolChain.h | 4 ++++ lib/Driver/ToolChain.cpp | 35 +++++++++++++++++++++-------- lib/Driver/ToolChains.cpp | 30 +++++++++---------------- lib/Driver/ToolChains.h | 3 ++- 7 files changed, 58 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 96f771b215..8a93f92127 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -197,6 +197,15 @@ set(GCC_INSTALL_PREFIX "" CACHE PATH "Directory where gcc is installed." ) set(DEFAULT_SYSROOT "" CACHE PATH "Default to all compiler invocations for --sysroot=." ) +set(CLANG_DEFAULT_CXX_STDLIB "" CACHE STRING + "Default C++ stdlib to use (empty for architecture default, \"libstdc++\" or \"libc++\"") +if (NOT(CLANG_DEFAULT_CXX_STDLIB STREQUAL "" OR + CLANG_DEFAULT_CXX_STDLIB STREQUAL "libstdc++" OR + CLANG_DEFAULT_CXX_STDLIB STREQUAL "libc++")) + message(WARNING "Resetting default C++ stdlib to use architecture default") + set(CLANG_DEFAULT_CXX_STDLIB "") +endif() + set(CLANG_DEFAULT_OPENMP_RUNTIME "libomp" CACHE STRING "Default OpenMP runtime used by -fopenmp.") diff --git a/include/clang/Config/config.h.cmake b/include/clang/Config/config.h.cmake index b7486f34da..8917065da1 100644 --- a/include/clang/Config/config.h.cmake +++ b/include/clang/Config/config.h.cmake @@ -8,6 +8,9 @@ /* Bug report URL. */ #define BUG_REPORT_URL "${BUG_REPORT_URL}" +/* Default C++ stdlib to use. */ +#define CLANG_DEFAULT_CXX_STDLIB "${CLANG_DEFAULT_CXX_STDLIB}" + /* Default OpenMP runtime used by -fopenmp. */ #define CLANG_DEFAULT_OPENMP_RUNTIME "${CLANG_DEFAULT_OPENMP_RUNTIME}" diff --git a/include/clang/Config/config.h.in b/include/clang/Config/config.h.in index 91983f6430..c09784cda5 100644 --- a/include/clang/Config/config.h.in +++ b/include/clang/Config/config.h.in @@ -8,6 +8,9 @@ /* Bug report URL. */ #undef BUG_REPORT_URL +/* Default C++ stdlib to use. */ +#undef CLANG_DEFAULT_CXX_STDLIB + /* Default OpenMP runtime used by -fopenmp. */ #undef CLANG_DEFAULT_OPENMP_RUNTIME diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h index 1778680983..da0c40e8ad 100644 --- a/include/clang/Driver/ToolChain.h +++ b/include/clang/Driver/ToolChain.h @@ -256,6 +256,10 @@ public: return ToolChain::RLT_Libgcc; } + virtual CXXStdlibType GetDefaultCXXStdlibType() const { + return ToolChain::CST_Libstdcxx; + } + virtual std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, bool Shared = false) const; diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp index cbbd485a9b..6158612b27 100644 --- a/lib/Driver/ToolChain.cpp +++ b/lib/Driver/ToolChain.cpp @@ -9,6 +9,7 @@ #include "Tools.h" #include "clang/Basic/ObjCRuntime.h" +#include "clang/Config/config.h" #include "clang/Driver/Action.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" @@ -533,18 +534,34 @@ ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType( return GetDefaultRuntimeLibType(); } +static bool ParseCXXStdlibType(const StringRef& Name, + ToolChain::CXXStdlibType& Type) { + if (Name == "libc++") + Type = ToolChain::CST_Libcxx; + else if (Name == "libstdc++") + Type = ToolChain::CST_Libstdcxx; + else + return false; + + return true; +} + ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{ - if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { - StringRef Value = A->getValue(); - if (Value == "libc++") - return ToolChain::CST_Libcxx; - if (Value == "libstdc++") - return ToolChain::CST_Libstdcxx; - getDriver().Diag(diag::err_drv_invalid_stdlib_name) - << A->getAsString(Args); + ToolChain::CXXStdlibType Type; + bool HasValidType = false; + + const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); + if (A) { + HasValidType = ParseCXXStdlibType(A->getValue(), Type); + if (!HasValidType) + getDriver().Diag(diag::err_drv_invalid_stdlib_name) + << A->getAsString(Args); } - return ToolChain::CST_Libstdcxx; + if (!HasValidType && !ParseCXXStdlibType(CLANG_DEFAULT_CXX_STDLIB, Type)) + Type = GetDefaultCXXStdlibType(); + + return Type; } /// \brief Utility function to add a system include directory to CC1 arguments. diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index b8f55756aa..a357863b8f 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -65,6 +65,16 @@ types::ID MachO::LookupTypeForExtension(const char *Ext) const { bool MachO::HasNativeLLVMSupport() const { return true; } +ToolChain::CXXStdlibType Darwin::GetDefaultCXXStdlibType() const { + // Default to use libc++ on OS X 10.9+ and iOS 7+. + if ((isTargetMacOS() && !isMacosxVersionLT(10, 9)) || + (isTargetIOSBased() && !isIPhoneOSVersionLT(7, 0)) || + isTargetWatchOSBased()) + return ToolChain::CST_Libcxx; + + return ToolChain::CST_Libstdcxx; +} + /// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0. ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const { if (isTargetWatchOSBased()) @@ -1020,7 +1030,6 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, const char *BoundArch) const { // First get the generic Apple args, before moving onto Darwin-specific ones. DerivedArgList *DAL = MachO::TranslateArgs(Args, BoundArch); - const OptTable &Opts = getDriver().getOpts(); // If no architecture is bound, none of the translations here are relevant. if (!BoundArch) @@ -1051,14 +1060,6 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, } } - // Default to use libc++ on OS X 10.9+ and iOS 7+. - if (((isTargetMacOS() && !isMacosxVersionLT(10, 9)) || - (isTargetIOSBased() && !isIPhoneOSVersionLT(7, 0)) || - isTargetWatchOSBased()) && - !Args.getLastArg(options::OPT_stdlib_EQ)) - DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_stdlib_EQ), - "libc++"); - // Validate the C++ standard library choice. CXXStdlibType Type = GetCXXStdlibType(*DAL); if (Type == ToolChain::CST_Libcxx) { @@ -3027,16 +3028,7 @@ Tool *Bitrig::buildAssembler() const { Tool *Bitrig::buildLinker() const { return new tools::bitrig::Linker(*this); } -ToolChain::CXXStdlibType Bitrig::GetCXXStdlibType(const ArgList &Args) const { - if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { - StringRef Value = A->getValue(); - if (Value == "libstdc++") - return ToolChain::CST_Libstdcxx; - if (Value == "libc++") - return ToolChain::CST_Libcxx; - - getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args); - } +ToolChain::CXXStdlibType Bitrig::GetDefaultCXXStdlibType() const { return ToolChain::CST_Libcxx; } diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index d9c87b9021..127f37f549 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -512,6 +512,7 @@ public: TranslateArgs(const llvm::opt::DerivedArgList &Args, const char *BoundArch) const override; + CXXStdlibType GetDefaultCXXStdlibType() const override; ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override; bool hasBlocksRuntime() const override; @@ -699,7 +700,7 @@ public: bool IsMathErrnoDefault() const override { return false; } bool IsObjCNonFragileABIDefault() const override { return true; } - CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; + CXXStdlibType GetDefaultCXXStdlibType() const override; void AddClangCXXStdlibIncludeArgs( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; -- 2.40.0