jlebar updated this revision to Diff 44178.
jlebar added a comment.

Split out the bits adding an arg to AddLinkerInputs into a separate patch, 
http://reviews.llvm.org/D15939.


http://reviews.llvm.org/D15596

Files:
  include/clang/Driver/Options.td
  include/clang/Driver/ToolChain.h
  lib/Driver/ToolChain.cpp
  lib/Driver/ToolChains.cpp
  lib/Driver/ToolChains.h
  lib/Driver/Tools.cpp
  test/Driver/cuda-default-libs.cu

Index: test/Driver/cuda-default-libs.cu
===================================================================
--- /dev/null
+++ test/Driver/cuda-default-libs.cu
@@ -0,0 +1,42 @@
+// Checks that we add -L /path/to/cuda/lib{,64} and -lcudart_static -ldl -lrt
+// -lpthread as appropriate when compiling CUDA code.
+
+// REQUIRES: clang-driver
+// REQUIRES: x86-registered-target
+// REQUIRES: nvptx-registered-target
+
+// RUN: %clang -### -v --target=i386-unknown-linux \
+// RUN:   -lfoo --sysroot=%S/Inputs/CUDA %s 2>&1 \
+// RUN:   | FileCheck %s -check-prefix CUDA -check-prefix CUDA-x86_32
+//
+// RUN: %clang -### -v --target=x86_64-unknown-linux \
+// RUN:   -lfoo --sysroot=%S/Inputs/CUDA %s 2>&1 \
+// RUN:   | FileCheck %s -check-prefix CUDA -check-prefix CUDA-x86_64
+//
+// # Our new flags should come after user-specified flags.
+// CUDA: -lfoo
+// CUDA-x86_32: "-L" "{{.*}}/Inputs/CUDA/usr/local/cuda/lib"
+// CUDA-x86_64: "-L" "{{.*}}/Inputs/CUDA/usr/local/cuda/lib64"
+// CUDA-x86_32-NOT: "-L" "{{.*}}/Inputs/CUDA/usr/local/cuda/lib64"
+// CUDA-x86_64-NOT: "-L" "{{.*}}/Inputs/CUDA/usr/local/cuda/lib"
+// CUDA-DAG: "-lcudart_static"
+// CUDA-DAG: "-ldl"
+// CUDA-DAG: "-lrt"
+// CUDA-DAG: "-lpthread"
+
+// If we can't find CUDA, don't include it in our library search path, and
+// don't include any additional libraries via -l.
+// RUN: %clang -### -v --target=i386-unknown-linux \
+// RUN:   --sysroot=%S/Inputs/no-cuda-there %s 2>&1 | FileCheck %s -check-prefix NOCUDA
+//
+// Also don't add anything if we pass -nocudalib.
+// RUN: %clang -### -v --target=x86_64-unknown-linux -nocudalib \
+// RUN:   --sysroot=%S/Inputs/CUDA %s 2>&1 | FileCheck %s -check-prefix NOCUDA
+//
+// NOCUDA-NOT: "-L" "{{.*}}/no-cuda-there/{{.*}}"
+// NOCUDA-NOT: "-lcudart_static"
+// NOCUDA-NOT: "-ldl"
+// NOCUDA-NOT: "-lrt"
+// NOCUDA-NOT: "-lpthread"
+// NOCUDA-NOT: "-L" "{{.*}}/Inputs/CUDA/usr/local/cuda/lib"
+// NOCUDA-NOT: "-L" "{{.*}}/Inputs/CUDA/usr/local/cuda/lib64"
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -224,6 +224,13 @@
   }
 }
 
+// Is the given action, or any of its inputs, a CUDA action?
+static bool isCudaAction(const Action* A) {
+  return isa<CudaDeviceAction>(A) || isa<CudaHostAction>(A) ||
+         std::any_of(A->getInputs().begin(), A->getInputs().end(),
+                     isCudaAction);
+}
+
 static void AddLinkerInputs(const Compilation &C, const ToolChain &TC,
                             const InputInfoList &Inputs, const ArgList &Args,
                             ArgStringList &CmdArgs) {
@@ -265,6 +272,10 @@
   //                and only supported on native toolchains.
   if (!TC.isCrossCompiling())
     addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
+
+  // Add -L/path/to/cuda/lib if any of our inputs are .cu files.
+  if (std::any_of(C.getActions().begin(), C.getActions().end(), isCudaAction))
+    TC.AddCudaLinkerArgs(Args, CmdArgs);
 }
 
 /// \brief Determine whether Objective-C automated reference counting is
Index: lib/Driver/ToolChains.h
===================================================================
--- lib/Driver/ToolChains.h
+++ lib/Driver/ToolChains.h
@@ -796,6 +796,8 @@
       llvm::opt::ArgStringList &CC1Args) const override;
   void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
                           llvm::opt::ArgStringList &CC1Args) const override;
+  void AddCudaLinkerArgs(const llvm::opt::ArgList &DriverArgs,
+                         llvm::opt::ArgStringList &CC1Args) const override;
   bool isPIEDefault() const override;
   SanitizerMask getSupportedSanitizers() const override;
   void addProfileRTLibs(const llvm::opt::ArgList &Args,
Index: lib/Driver/ToolChains.cpp
===================================================================
--- lib/Driver/ToolChains.cpp
+++ lib/Driver/ToolChains.cpp
@@ -4120,6 +4120,17 @@
   }
 }
 
+void Linux::AddCudaLinkerArgs(const ArgList &DriverArgs,
+                              ArgStringList &LDArgs) const {
+  if (DriverArgs.hasArg(options::OPT_nocudalib) || !CudaInstallation.isValid())
+    return;
+
+  LDArgs.push_back("-L");
+  LDArgs.push_back(DriverArgs.MakeArgString(CudaInstallation.getLibPath()));
+  for (const char *Flag : {"-lcudart_static", "-ldl", "-lrt", "-lpthread"})
+    LDArgs.push_back(DriverArgs.MakeArgString(Flag));
+}
+
 bool Linux::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); }
 
 SanitizerMask Linux::getSupportedSanitizers() const {
Index: lib/Driver/ToolChain.cpp
===================================================================
--- lib/Driver/ToolChain.cpp
+++ lib/Driver/ToolChain.cpp
@@ -665,4 +665,11 @@
 }
 
 void ToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
-                                   ArgStringList &CC1Args) const {}
+                                   ArgStringList &CC1Args) const {
+  // Only supported on Linux at the moment.
+}
+
+void ToolChain::AddCudaLinkerArgs(const ArgList &DriverArgs,
+                                  ArgStringList &LDArgs) const {
+  // Only supported on Linux at the moment.
+}
Index: include/clang/Driver/ToolChain.h
===================================================================
--- include/clang/Driver/ToolChain.h
+++ include/clang/Driver/ToolChain.h
@@ -408,6 +408,10 @@
   virtual void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
                                   llvm::opt::ArgStringList &CC1Args) const;
 
+  /// \brief Add LD arguments pointing to CUDA libraries.
+  virtual void AddCudaLinkerArgs(const llvm::opt::ArgList &DriverArgs,
+                                 llvm::opt::ArgStringList &LDArgs) const;
+
   /// \brief Return sanitizers which are available in this toolchain.
   virtual SanitizerMask getSupportedSanitizers() const;
 };
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -1632,6 +1632,8 @@
 def nobuiltininc : Flag<["-"], "nobuiltininc">, Flags<[CC1Option]>,
   HelpText<"Disable builtin #include directories">;
 def nocudainc : Flag<["-"], "nocudainc">;
+def nocudalib : Flag<["-"], "nocudalib">,
+  HelpText<"Don't link with libraries necessary for running CUDA">;
 def nocudalibdevice : Flag<["-"], "nocudalibdevice">,
   HelpText<"Don't link in the CUDA libdevice bitcode (libdevice.compute_xx.yy.bc)">;
 def nodefaultlibs : Flag<["-"], "nodefaultlibs">;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to