phosek created this revision.
Herald added subscribers: cfe-commits, jfb, srhines, emaste.

Existing drivers already include -lm as C++ library dependency, but
that alone is not sufficient when statically linking the C++ library.
To handle that case, we introduce a new method addCXXStdlibLinkDeps
which should automatically include all C++ library dependencies.


Repository:
  rC Clang

https://reviews.llvm.org/D54724

Files:
  clang/lib/Driver/ToolChains/CommonArgs.cpp
  clang/lib/Driver/ToolChains/CommonArgs.h
  clang/lib/Driver/ToolChains/DragonFly.cpp
  clang/lib/Driver/ToolChains/FreeBSD.cpp
  clang/lib/Driver/ToolChains/Fuchsia.cpp
  clang/lib/Driver/ToolChains/Gnu.cpp
  clang/lib/Driver/ToolChains/Hexagon.cpp
  clang/lib/Driver/ToolChains/OpenBSD.cpp
  clang/lib/Driver/ToolChains/PS4CPU.cpp
  clang/test/Driver/fuchsia.cpp
  clang/test/Driver/linux-ld.c

Index: clang/test/Driver/linux-ld.c
===================================================================
--- clang/test/Driver/linux-ld.c
+++ clang/test/Driver/linux-ld.c
@@ -572,6 +572,22 @@
 // CHECK-BASIC-LIBCXX-C-LINK: "--sysroot=[[SYSROOT]]"
 // CHECK-BASIC-LIBCXX-C-LINK: "-L[[SYSROOT]]/usr/bin/../lib"
 //
+// Test that we include necessary dependencies when statically linking libc++.
+// RUN: %clangxx -no-canonical-prefixes -x c++ %s -### -o %t.o 2>&1 \
+// RUN:     -target x86_64-unknown-linux-gnu \
+// RUN:     -stdlib=libc++ \
+// RUN:     -static-libstdc++ \
+// RUN:     -ccc-install-dir %S/Inputs/basic_linux_tree/usr/bin \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/basic_linux_libcxx_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BASIC-LIBCXX-STATIC %s
+// CHECK-BASIC-LIBCXX-STATIC: "-Bstatic"
+// CHECK-BASIC-LIBCXX-STATIC: "-lc++"
+// CHECK-BASIC-LIBCXX-STATIC: "-Bdynamic"
+// CHECK-BASIC-LIBCXX-STATIC: "-lpthread"
+// CHECK-BASIC-LIBCXX-STATIC: "-ldl"
+// CHECK-BASIC-LIBCXX-STATIC: "-lm"
+//
 // Test a very broken version of multiarch that shipped in Ubuntu 11.04.
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=i386-unknown-linux \
Index: clang/test/Driver/fuchsia.cpp
===================================================================
--- clang/test/Driver/fuchsia.cpp
+++ clang/test/Driver/fuchsia.cpp
@@ -41,5 +41,7 @@
 // CHECK-STATIC: "-lc++"
 // CHECK-STATIC: "-Bdynamic"
 // CHECK-STATIC: "-lm"
+// CHECK-STATIC: "-lpthread"
+// CHECK-STATIC: "-ldl"
 // CHECK-STATIC: "--pop-state"
 // CHECK-STATIC: "-lc"
Index: clang/lib/Driver/ToolChains/PS4CPU.cpp
===================================================================
--- clang/lib/Driver/ToolChains/PS4CPU.cpp
+++ clang/lib/Driver/ToolChains/PS4CPU.cpp
@@ -21,6 +21,7 @@
 #include <cstdlib> // ::getenv
 
 using namespace clang::driver;
+using namespace clang::driver::tools;
 using namespace clang;
 using namespace llvm::opt;
 
@@ -238,10 +239,7 @@
     if (D.CCCIsCXX()) {
       if (ToolChain.ShouldLinkCXXStdlib(Args))
         ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-      if (Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back("-lm_p");
-      else
-        CmdArgs.push_back("-lm");
+      addCXXStdlibLinkDeps(ToolChain, Args, CmdArgs);
     }
     // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
     // the default system libraries. Just mimic this for now.
Index: clang/lib/Driver/ToolChains/OpenBSD.cpp
===================================================================
--- clang/lib/Driver/ToolChains/OpenBSD.cpp
+++ clang/lib/Driver/ToolChains/OpenBSD.cpp
@@ -183,10 +183,7 @@
     if (D.CCCIsCXX()) {
       if (ToolChain.ShouldLinkCXXStdlib(Args))
         ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-      if (Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back("-lm_p");
-      else
-        CmdArgs.push_back("-lm");
+      addCXXStdlibLinkDeps(ToolChain, Args, CmdArgs);
     }
     if (NeedsSanitizerDeps) {
       CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins", false));
Index: clang/lib/Driver/ToolChains/Hexagon.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Hexagon.cpp
+++ clang/lib/Driver/ToolChains/Hexagon.cpp
@@ -332,7 +332,7 @@
     if (D.CCCIsCXX()) {
       if (HTC.ShouldLinkCXXStdlib(Args))
         HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
-      CmdArgs.push_back("-lm");
+      addCXXStdlibLinkDeps(HTC, Args, CmdArgs);
     }
 
     CmdArgs.push_back("--start-group");
Index: clang/lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Gnu.cpp
+++ clang/lib/Driver/ToolChains/Gnu.cpp
@@ -482,6 +482,7 @@
       ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
       if (OnlyLibstdcxxStatic)
         CmdArgs.push_back("-Bdynamic");
+      addCXXStdlibLinkDeps(ToolChain, Args, CmdArgs);
     }
     CmdArgs.push_back("-lm");
   }
Index: clang/lib/Driver/ToolChains/Fuchsia.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Fuchsia.cpp
+++ clang/lib/Driver/ToolChains/Fuchsia.cpp
@@ -129,7 +129,7 @@
         ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
         if (OnlyLibstdcxxStatic)
           CmdArgs.push_back("-Bdynamic");
-        CmdArgs.push_back("-lm");
+        addCXXStdlibLinkDeps(ToolChain, Args, CmdArgs);
         CmdArgs.push_back("--pop-state");
       }
     }
Index: clang/lib/Driver/ToolChains/FreeBSD.cpp
===================================================================
--- clang/lib/Driver/ToolChains/FreeBSD.cpp
+++ clang/lib/Driver/ToolChains/FreeBSD.cpp
@@ -267,10 +267,7 @@
     if (D.CCCIsCXX()) {
       if (ToolChain.ShouldLinkCXXStdlib(Args))
         ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-      if (Args.hasArg(options::OPT_pg))
-        CmdArgs.push_back("-lm_p");
-      else
-        CmdArgs.push_back("-lm");
+      addCXXStdlibLinkDeps(ToolChain, Args, CmdArgs);
     }
     if (NeedsSanitizerDeps)
       linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
Index: clang/lib/Driver/ToolChains/DragonFly.cpp
===================================================================
--- clang/lib/Driver/ToolChains/DragonFly.cpp
+++ clang/lib/Driver/ToolChains/DragonFly.cpp
@@ -129,7 +129,7 @@
     if (D.CCCIsCXX()) {
       if (getToolChain().ShouldLinkCXXStdlib(Args))
         getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
-      CmdArgs.push_back("-lm");
+      addCXXStdlibLinkDeps(getToolChain(), Args, CmdArgs);
     }
 
     if (Args.hasArg(options::OPT_pthread))
Index: clang/lib/Driver/ToolChains/CommonArgs.h
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.h
+++ clang/lib/Driver/ToolChains/CommonArgs.h
@@ -85,6 +85,11 @@
 
 void addArchSpecificRPath(const ToolChain &TC, const llvm::opt::ArgList &Args,
                           llvm::opt::ArgStringList &CmdArgs);
+
+void addCXXStdlibLinkDeps(const ToolChain &ToolChain,
+                          const llvm::opt::ArgList &Args,
+                          llvm::opt::ArgStringList &CmdArgs);
+
 /// Returns true, if an OpenMP runtime has been added.
 bool addOpenMPRuntime(llvm::opt::ArgStringList &CmdArgs, const ToolChain &TC,
                       const llvm::opt::ArgList &Args,
Index: clang/lib/Driver/ToolChains/CommonArgs.cpp
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1226,6 +1226,48 @@
   }
 }
 
+void tools::addCXXStdlibLinkDeps(const ToolChain &ToolChain,
+                                 const ArgList &Args,
+                                 ArgStringList &CmdArgs) {
+  const llvm::Triple &Triple = ToolChain.getTriple();
+
+  bool StaticLibstdcxx = Args.hasArg(options::OPT_static_libstdcxx) &&
+                         !Args.hasArg(options::OPT_static);
+
+  // TODO: should this be only included when -static-libstdc++ is used?
+  if ((Triple.getOS() == llvm::Triple::FreeBSD ||
+       Triple.getOS() == llvm::Triple::OpenBSD ||
+       Triple.isPS4CPU()) && Args.hasArg(options::OPT_pg))
+    CmdArgs.push_back("-lm_p");
+  else
+    CmdArgs.push_back("-lm");
+
+  if (StaticLibstdcxx) {
+    if (!Triple.isAndroid())
+      CmdArgs.push_back("-lpthread");
+
+    switch (ToolChain.GetCXXStdlibType(Args)) {
+    case ToolChain::CST_Libcxx:
+      if (Triple.getOS() != llvm::Triple::FreeBSD &&
+          Triple.getOS() != llvm::Triple::NetBSD &&
+          Triple.getOS() != llvm::Triple::OpenBSD)
+        CmdArgs.push_back("-ldl");
+      break;
+
+    case ToolChain::CST_Libstdcxx:
+      switch (ToolChain.GetRuntimeLibType(Args)) {
+      case ToolChain::RLT_CompilerRT:
+        AddLibgcc(Triple, ToolChain.getDriver(), CmdArgs, Args);
+        break;
+      case ToolChain::RLT_Libgcc:
+        // libgcc will be added by AddLibgcc.
+        break;
+      }
+      break;
+    }
+  }
+}
+
 /// Add OpenMP linker script arguments at the end of the argument list so that
 /// the fat binary is built by embedding each of the device images into the
 /// host. The linker script also defines a few symbols required by the code
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to