jlebar updated this revision to Diff 44156.
jlebar marked 4 inline comments as done.
jlebar added a comment.

Address tra's review comments.


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,40 @@
+// 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:   --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:   --sysroot=%S/Inputs/CUDA %s 2>&1 \
+// RUN:   | FileCheck %s -check-prefix CUDA -check-prefix CUDA-x86_64
+//
+// 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,8 +224,16 @@
   }
 }
 
-static void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
-                            const ArgList &Args, ArgStringList &CmdArgs) {
+// 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) {
   const Driver &D = TC.getDriver();
 
   // Add extra linker input arguments which are not treated as inputs
@@ -264,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
@@ -6409,7 +6421,7 @@
                   {options::OPT_T_Group, options::OPT_e, options::OPT_s,
                    options::OPT_t, options::OPT_u_Group});
 
-  AddLinkerInputs(HTC, Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, HTC, Inputs, Args, CmdArgs);
 
   //----------------------------------------------------------------------------
   // Libraries
@@ -6472,7 +6484,7 @@
   CmdArgs.push_back("old-gnu");
   CmdArgs.push_back("-target");
   CmdArgs.push_back(Args.MakeArgString(getToolChain().getTripleString()));
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, getToolChain(), Inputs, Args, CmdArgs);
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
   C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
@@ -6500,7 +6512,7 @@
   ArgStringList CmdArgs;
   CmdArgs.push_back("-flavor");
   CmdArgs.push_back("ld");
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, getToolChain(), Inputs, Args, CmdArgs);
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
   C.addCommand(llvm::make_unique<Command>(JA, *this, Linker, CmdArgs, Inputs));
@@ -6803,7 +6815,7 @@
   if (D.isUsingLTO())
     AddGoldPlugin(ToolChain, Args, CmdArgs, D.getLTOMode() == LTOK_Thin);
 
-  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, ToolChain, Inputs, Args, CmdArgs);
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     if (D.CCCIsCXX())
@@ -7173,7 +7185,7 @@
 
   Args.AddAllArgs(CmdArgs, options::OPT_L);
 
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, getToolChain(), Inputs, Args, CmdArgs);
   // Build the input file for -filelist (list of linker input files) in case we
   // need it later
   for (const auto &II : Inputs) {
@@ -7391,7 +7403,7 @@
   Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
                             options::OPT_e, options::OPT_r});
 
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, getToolChain(), Inputs, Args, CmdArgs);
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     if (getToolChain().getDriver().CCCIsCXX())
@@ -7564,7 +7576,7 @@
                             options::OPT_e, options::OPT_s, options::OPT_t,
                             options::OPT_Z_Flag, options::OPT_r});
 
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, getToolChain(), Inputs, Args, CmdArgs);
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     if (D.CCCIsCXX()) {
@@ -7683,7 +7695,7 @@
   Args.AddAllArgs(CmdArgs,
                   {options::OPT_L, options::OPT_T_Group, options::OPT_e});
 
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, getToolChain(), Inputs, Args, CmdArgs);
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     if (D.CCCIsCXX()) {
@@ -7949,7 +7961,7 @@
     AddGoldPlugin(ToolChain, Args, CmdArgs, D.getLTOMode() == LTOK_Thin);
 
   bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
-  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, ToolChain, Inputs, Args, CmdArgs);
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     addOpenMPRuntime(CmdArgs, ToolChain, Args);
@@ -8245,7 +8257,7 @@
   Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
   Args.AddAllArgs(CmdArgs, options::OPT_r);
 
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, getToolChain(), Inputs, Args, CmdArgs);
 
   unsigned Major, Minor, Micro;
   getToolChain().getTriple().getOSVersion(Major, Minor, Micro);
@@ -8832,7 +8844,7 @@
     CmdArgs.push_back("--no-demangle");
 
   bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
-  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, ToolChain, Inputs, Args, CmdArgs);
   // The profile runtime also needs access to system libraries.
   getToolChain().addProfileRTLibs(Args, CmdArgs);
 
@@ -9026,7 +9038,7 @@
   if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
     CmdArgs.push_back("--no-demangle");
 
-  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, ToolChain, Inputs, Args, CmdArgs);
 
   if (D.CCCIsCXX() &&
       !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
@@ -9138,7 +9150,7 @@
   Args.AddAllArgs(CmdArgs,
                   {options::OPT_L, options::OPT_T_Group, options::OPT_e});
 
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, getToolChain(), Inputs, Args, CmdArgs);
 
   getToolChain().addProfileRTLibs(Args, CmdArgs);
 
@@ -9259,7 +9271,7 @@
   Args.AddAllArgs(CmdArgs,
                   {options::OPT_L, options::OPT_T_Group, options::OPT_e});
 
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, getToolChain(), Inputs, Args, CmdArgs);
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     CmdArgs.push_back("-L/usr/lib/gcc50");
@@ -9762,7 +9774,7 @@
 
   Args.AddAllArgs(CmdArgs, options::OPT_L);
   TC.AddFilePathLibArgs(Args, CmdArgs);
-  AddLinkerInputs(TC, Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, TC, Inputs, Args, CmdArgs);
 
   // TODO: Add ASan stuff here
 
@@ -9886,7 +9898,7 @@
                    false))
     CmdArgs.push_back("-fexceptions");
 
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, getToolChain(), Inputs, Args, CmdArgs);
 
   const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
@@ -10040,7 +10052,7 @@
 
   Args.AddAllArgs(CmdArgs, options::OPT_L);
   TC.AddFilePathLibArgs(Args, CmdArgs);
-  AddLinkerInputs(TC, Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, TC, Inputs, Args, CmdArgs);
 
   if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib) &&
       !Args.hasArg(options::OPT_nodefaultlibs)) {
@@ -10218,7 +10230,7 @@
 
   TC.AddFilePathLibArgs(Args, CmdArgs);
 
-  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, getToolChain(), Inputs, Args, CmdArgs);
 
   if (UseDefaultLibs) {
     if (C.getDriver().CCCIsCXX())
@@ -10327,7 +10339,7 @@
   if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
     CmdArgs.push_back("--no-demangle");
 
-  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, ToolChain, Inputs, Args, CmdArgs);
 
   if (Args.hasArg(options::OPT_pthread)) {
     CmdArgs.push_back("-lpthread");
@@ -10423,7 +10435,7 @@
   if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
     CmdArgs.push_back("--no-demangle");
 
-  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
+  AddLinkerInputs(C, ToolChain, Inputs, Args, CmdArgs);
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     // For PS4, we always want to pass libm, libstdc++ and libkernel
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,18 @@
   }
 }
 
+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 (-L/path/to/cuda/lib{,64} -lcudart_static -lrt -lpthread -ldl)">;
 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