]> granicus.if.org Git - clang/commitdiff
Introduce -nostdlib++ flag to disable linking the C++ standard library.
authorNico Weber <nicolasweber@gmx.de>
Tue, 25 Jul 2017 18:02:57 +0000 (18:02 +0000)
committerNico Weber <nicolasweber@gmx.de>
Tue, 25 Jul 2017 18:02:57 +0000 (18:02 +0000)
Projects that want to statically link their own C++ standard library currently
need to pass -nostdlib or -nodefaultlibs, which also disables linking of the
builtins library, -lm, and so on. Alternatively, they could use `clang` instead
of `clang++`, but that already disables implicit addition of -lm on some
toolchains.

Add a dedicated flag -nostdlib++ that disables just linking of libc++ /
libstdc++. This is analogous to -nostdinc++.

https://reviews.llvm.org/D35780

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@308997 91177308-0d34-0410-b5e6-96231b3b80d8

23 files changed:
include/clang/Driver/Options.td
include/clang/Driver/ToolChain.h
lib/Driver/ToolChain.cpp
lib/Driver/ToolChains/Ananas.cpp
lib/Driver/ToolChains/BareMetal.cpp
lib/Driver/ToolChains/CloudABI.cpp
lib/Driver/ToolChains/CommonArgs.cpp
lib/Driver/ToolChains/CrossWindows.cpp
lib/Driver/ToolChains/Darwin.cpp
lib/Driver/ToolChains/DragonFly.cpp
lib/Driver/ToolChains/FreeBSD.cpp
lib/Driver/ToolChains/Fuchsia.cpp
lib/Driver/ToolChains/Gnu.cpp
lib/Driver/ToolChains/Hexagon.cpp
lib/Driver/ToolChains/MinGW.cpp
lib/Driver/ToolChains/Minix.cpp
lib/Driver/ToolChains/NaCl.cpp
lib/Driver/ToolChains/NetBSD.cpp
lib/Driver/ToolChains/OpenBSD.cpp
lib/Driver/ToolChains/PS4CPU.cpp
lib/Driver/ToolChains/Solaris.cpp
lib/Driver/ToolChains/WebAssembly.cpp
test/Driver/nostdlibxx.cpp [new file with mode: 0644]

index 875903417d19e0c6e6e629385568f27d3f1077de..ccf6dd63e551f9cedc35bfad5bd7283382dbfa9a 100644 (file)
@@ -2144,6 +2144,7 @@ def nostdlibinc : Flag<["-"], "nostdlibinc">;
 def nostdincxx : Flag<["-"], "nostdinc++">, Flags<[CC1Option]>,
   HelpText<"Disable standard #include directories for the C++ standard library">;
 def nostdlib : Flag<["-"], "nostdlib">;
+def nostdlibxx : Flag<["-"], "nostdlib++">;
 def object : Flag<["-"], "object">;
 def o : JoinedOrSeparate<["-"], "o">, Flags<[DriverOption, RenderAsInput, CC1Option, CC1AsOption]>,
   HelpText<"Write output to <file>">, MetaVarName<"<file>">;
index eb42f1260d92c7813f48918bd8becadefe5db6fb..c6da030fac476f377845fb6e8e16dc90a21c6018 100644 (file)
@@ -432,6 +432,10 @@ public:
   AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
                                llvm::opt::ArgStringList &CC1Args) const;
 
+  /// Returns if the C++ standard library should be linked in.
+  /// Note that e.g. -lm should still be linked even if this returns false.
+  bool ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const;
+
   /// AddCXXStdlibLibArgs - Add the system specific linker arguments to use
   /// for the given C++ standard library type.
   virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
index 2be7f0f69004c6fa4c7345bbcb702441912e8a96..b8dd37ca5776ceb53fdf2e10375fde8906dda4e2 100644 (file)
@@ -648,8 +648,16 @@ void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
   DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
 }
 
+bool ToolChain::ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const {
+  return getDriver().CCCIsCXX() &&
+         !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
+                      options::OPT_nostdlibxx);
+}
+
 void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
                                     ArgStringList &CmdArgs) const {
+  assert(!Args.hasArg(options::OPT_nostdlibxx) &&
+         "should not have called this");
   CXXStdlibType Type = GetCXXStdlibType(Args);
 
   switch (Type) {
index a67e1d2378f5d69b18c4c8af01ea06d587747bef..ee072cc03e7ca3c1f97afbaaf7e301731a89d3f3 100644 (file)
@@ -91,11 +91,10 @@ void ananas::Linker::ConstructJob(Compilation &C, const JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (D.CCCIsCXX())
-      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+  if (ToolChain.ShouldLinkCXXStdlib(Args))
+    ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
     CmdArgs.push_back("-lc");
-  }
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
index 5dc6dfad927b66033c8769ad55f57f7504fec575..529a2093cf7526ee9e79f114e7fa3aeec4df4636 100644 (file)
@@ -192,10 +192,9 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
                             options::OPT_e, options::OPT_s, options::OPT_t,
                             options::OPT_Z_Flag, options::OPT_r});
 
+  if (TC.ShouldLinkCXXStdlib(Args))
+    TC.AddCXXStdlibLibArgs(Args, CmdArgs);
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (C.getDriver().CCCIsCXX())
-      TC.AddCXXStdlibLibArgs(Args, CmdArgs);
-
     CmdArgs.push_back("-lc");
     CmdArgs.push_back("-lm");
 
index 0f6c712c5d28ea7b231a637c3e4b6d108bb251f4..cdf807f7f91ff7fecbf3f3463be66b7435055daf 100644 (file)
@@ -80,9 +80,9 @@ void cloudabi::Linker::ConstructJob(Compilation &C, const JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
+  if (ToolChain.ShouldLinkCXXStdlib(Args))
+    ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (D.CCCIsCXX())
-      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
     CmdArgs.push_back("-lc");
     CmdArgs.push_back("-lcompiler_rt");
   }
index 00bd60bc24bbabaeefbbfb3f4df9e5ec38f2a7ed..aea36cd0eeb3e90632ba6927e7d44bbc7582c767 100644 (file)
@@ -600,10 +600,12 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
 static void addLibFuzzerRuntime(const ToolChain &TC,
                                 const ArgList &Args,
                                 ArgStringList &CmdArgs) {
-    StringRef ParentDir = llvm::sys::path::parent_path(TC.getDriver().InstalledDir);
-    SmallString<128> P(ParentDir);
-    llvm::sys::path::append(P, "lib", "libLLVMFuzzer.a");
-    CmdArgs.push_back(Args.MakeArgString(P));
+  StringRef ParentDir =
+      llvm::sys::path::parent_path(TC.getDriver().InstalledDir);
+  SmallString<128> P(ParentDir);
+  llvm::sys::path::append(P, "lib", "libLLVMFuzzer.a");
+  CmdArgs.push_back(Args.MakeArgString(P));
+  if (!Args.hasArg(clang::driver::options::OPT_nostdlibxx))
     TC.AddCXXStdlibLibArgs(Args, CmdArgs);
 }
 
index 7d0c438b1360a90d0045088c3a55b7dbad5092d1..ac00a3eba83b5ea308d022797d7d3ad4f03e184b 100644 (file)
@@ -160,8 +160,7 @@ void tools::CrossWindows::Linker::ConstructJob(
   TC.AddFilePathLibArgs(Args, CmdArgs);
   AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
 
-  if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib) &&
-      !Args.hasArg(options::OPT_nodefaultlibs)) {
+  if (TC.ShouldLinkCXXStdlib(Args)) {
     bool StaticCXX = Args.hasArg(options::OPT_static_libstdcxx) &&
                      !Args.hasArg(options::OPT_static);
     if (StaticCXX)
index 27428709d5ddcc0eb2804e66a41d9df488bc11b9..bd8516c47c5210d50bf426b13e1396bffff0eb41 100644 (file)
@@ -549,10 +549,9 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
         Args.MakeArgString(Twine("-threads=") + llvm::to_string(Parallelism)));
   }
 
+  if (getToolChain().ShouldLinkCXXStdlib(Args))
+    getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (getToolChain().getDriver().CCCIsCXX())
-      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
-
     // link_ssp spec is empty.
 
     // Let the tool chain choose which runtime library to link.
index bd2c7fc6c4bd2b24899404f7c4257aa0a4d35cc5..648469e4cec5135fdd6a69fdba7034ac49674f14 100644 (file)
@@ -127,7 +127,8 @@ void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA,
     }
 
     if (D.CCCIsCXX()) {
-      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (getToolChain().ShouldLinkCXXStdlib(Args))
+        getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
       CmdArgs.push_back("-lm");
     }
 
index c6626e922eef836a88433ee0ed36525f3f3bb92a..2f066cf0cc89093f15bd4df00cfa65385300d5dc 100644 (file)
@@ -240,7 +240,8 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     addOpenMPRuntime(CmdArgs, ToolChain, Args);
     if (D.CCCIsCXX()) {
-      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (ToolChain.ShouldLinkCXXStdlib(Args))
+        ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
       if (Args.hasArg(options::OPT_pg))
         CmdArgs.push_back("-lm_p");
       else
index 78053aafd16e581fe740540e29d4adbabf31b644..b87d9f0be7a34bb750410c296e88ed6d99c3b09b 100644 (file)
@@ -107,13 +107,15 @@ void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA,
       CmdArgs.push_back("-Bdynamic");
 
     if (D.CCCIsCXX()) {
-      bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
-                                 !Args.hasArg(options::OPT_static);
-      if (OnlyLibstdcxxStatic)
-        CmdArgs.push_back("-Bstatic");
-      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-      if (OnlyLibstdcxxStatic)
-        CmdArgs.push_back("-Bdynamic");
+      if (ToolChain.ShouldLinkCXXStdlib(Args)) {
+        bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
+                                   !Args.hasArg(options::OPT_static);
+        if (OnlyLibstdcxxStatic)
+          CmdArgs.push_back("-Bstatic");
+        ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+        if (OnlyLibstdcxxStatic)
+          CmdArgs.push_back("-Bdynamic");
+      }
       CmdArgs.push_back("-lm");
     }
 
index bc26ee1de46d2070868e529c118ad8ff64b01d69..6902c0abb1eaf8fa09427dd40ccac4f33fce5191 100644 (file)
@@ -560,13 +560,15 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
 
   if (D.CCCIsCXX() &&
       !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
-                               !Args.hasArg(options::OPT_static);
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bstatic");
-    ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bdynamic");
+    if (ToolChain.ShouldLinkCXXStdlib(Args)) {
+      bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
+                                 !Args.hasArg(options::OPT_static);
+      if (OnlyLibstdcxxStatic)
+        CmdArgs.push_back("-Bstatic");
+      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (OnlyLibstdcxxStatic)
+        CmdArgs.push_back("-Bdynamic");
+    }
     CmdArgs.push_back("-lm");
   }
   // Silence warnings when linking C code with a C++ '-stdlib' argument.
index 9bf1590e6a37e0f8b25b7c1622372eec9cb9c81a..4f62b1f61a0c2d40428d0fbbf89fc251cbdfcebc 100644 (file)
@@ -248,7 +248,8 @@ constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
   //----------------------------------------------------------------------------
   if (IncStdLib && IncDefLibs) {
     if (D.CCCIsCXX()) {
-      HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (HTC.ShouldLinkCXXStdlib(Args))
+        HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
       CmdArgs.push_back("-lm");
     }
 
index 7550bab486f1b3ba1df9f93879a1fead16ddd62a..1c5eeb37254f8488059b448ddf3ed2f806388529 100644 (file)
@@ -185,8 +185,7 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
 
   // TODO: Add profile stuff here
 
-  if (D.CCCIsCXX() &&
-      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+  if (TC.ShouldLinkCXXStdlib(Args)) {
     bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
                                !Args.hasArg(options::OPT_static);
     if (OnlyLibstdcxxStatic)
index 2e8939c4015024be5a9dbfff4f9595986c6c5d43..39e6f90b6ef02a47f68bae5d50457ff1f925bb3a 100644 (file)
@@ -72,7 +72,8 @@ void tools::minix::Linker::ConstructJob(Compilation &C, const JobAction &JA,
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     if (D.CCCIsCXX()) {
-      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (getToolChain().ShouldLinkCXXStdlib(Args))
+        getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
       CmdArgs.push_back("-lm");
     }
   }
index 5eb5c74f1310c8c2f6fa1286137c3eabb2b01e98..128478d638719e81b2a7f0205a8dcc5715317951 100644 (file)
@@ -133,13 +133,15 @@ void nacltools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
 
   if (D.CCCIsCXX() &&
       !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    bool OnlyLibstdcxxStatic =
-        Args.hasArg(options::OPT_static_libstdcxx) && !IsStatic;
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bstatic");
-    ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bdynamic");
+    if (ToolChain.ShouldLinkCXXStdlib(Args)) {
+      bool OnlyLibstdcxxStatic =
+          Args.hasArg(options::OPT_static_libstdcxx) && !IsStatic;
+      if (OnlyLibstdcxxStatic)
+        CmdArgs.push_back("-Bstatic");
+      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (OnlyLibstdcxxStatic)
+        CmdArgs.push_back("-Bdynamic");
+    }
     CmdArgs.push_back("-lm");
   }
 
index e89ee377e7db6a536e1bbf230be5c504592f0834..acc56278f3d0b76a453b9e9fd88f87fd4f541067 100644 (file)
@@ -278,7 +278,8 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     addOpenMPRuntime(CmdArgs, getToolChain(), Args);
     if (D.CCCIsCXX()) {
-      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (getToolChain().ShouldLinkCXXStdlib(Args))
+        getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
       CmdArgs.push_back("-lm");
     }
     if (NeedsSanitizerDeps)
index c5f266ec8fdca5114b9e7a76547daa7bd59c26c5..7b77784d301256d4baf3750abf3aad59df2096d1 100644 (file)
@@ -177,7 +177,8 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     if (D.CCCIsCXX()) {
-      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (getToolChain().ShouldLinkCXXStdlib(Args))
+        getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
       if (Args.hasArg(options::OPT_pg))
         CmdArgs.push_back("-lm_p");
       else
index c1b8c3d660779e690682b86072c8f27610d9190e..b37fe7d1f9b910d4790b987b1e22189d1bfb7a52 100644 (file)
@@ -227,7 +227,8 @@ static void ConstructGoldLinkJob(const Tool &T, Compilation &C,
     // libraries for both C and C++ compilations.
     CmdArgs.push_back("-lkernel");
     if (D.CCCIsCXX()) {
-      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (ToolChain.ShouldLinkCXXStdlib(Args))
+        ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
       if (Args.hasArg(options::OPT_pg))
         CmdArgs.push_back("-lm_p");
       else
index de98d11b2dc7beb6055beb90508232f71c7486b9..9fe6e9d520d09cc403390178af04f047e583ad3b 100644 (file)
@@ -100,7 +100,7 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (getToolChain().getDriver().CCCIsCXX())
+    if (getToolChain().ShouldLinkCXXStdlib(Args))
       getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
     CmdArgs.push_back("-lgcc_s");
     CmdArgs.push_back("-lc");
index 058bc42323e2f371a813c86d1a2f5a6ad728e775..88a3f1b5745c0e4db077d30df8021e110af0135a 100644 (file)
@@ -38,7 +38,6 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA,
                                 const char *LinkingOutput) const {
 
   const ToolChain &ToolChain = getToolChain();
-  const Driver &D = ToolChain.getDriver();
   const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath());
   ArgStringList CmdArgs;
   CmdArgs.push_back("-flavor");
@@ -77,7 +76,7 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA,
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (D.CCCIsCXX())
+    if (ToolChain.ShouldLinkCXXStdlib(Args))
       ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
 
     if (Args.hasArg(options::OPT_pthread))
diff --git a/test/Driver/nostdlibxx.cpp b/test/Driver/nostdlibxx.cpp
new file mode 100644 (file)
index 0000000..02bd62d
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: %clangxx -target i686-pc-linux-gnu -### -nostdlib++ %s 2> %t
+// RUN: FileCheck < %t %s
+
+// We should still have -lm and the C standard libraries, but not -lstdc++.
+
+// CHECK-NOT: -lstdc++
+// CHECK-NOT: -lc++
+// CHECK: -lm