瀏覽代碼

Merge topic 'vs-cuda-custom-dir'

25f29b9741 cuda: Adapted tests to work with modified cuda toolset
ee86770a3f cuda: Added docs for extended cuda toolset
0ad180d712 cuda: Extend cuda compiler detection to work with custom cuda path
55b0532128 cuda: Extend vs10 target generator to use custom cuda path
df0247a371 cuda: Extend toolset argument to accept path

Acked-by: Kitware Robot <[email protected]>
Merge-request: !3713
Brad King 6 年之前
父節點
當前提交
cee20ad537

+ 1 - 0
Help/manual/cmake-variables.7.rst

@@ -112,6 +112,7 @@ Variables that Provide Information
    /variable/CMAKE_VS_PLATFORM_NAME_DEFAULT
    /variable/CMAKE_VS_PLATFORM_TOOLSET
    /variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA
+   /variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR
    /variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE
    /variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION
    /variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION

+ 7 - 4
Help/variable/CMAKE_GENERATOR_TOOLSET.rst

@@ -40,10 +40,13 @@ The ``key=value`` pairs form a comma-separated list of options to
 specify generator-specific details of the toolset selection.
 Supported pairs are:
 
-``cuda=<version>``
-  Specify the CUDA toolkit version to use.  Supported by VS 2010
-  and above with the CUDA toolkit VS integration installed.
-  See the :variable:`CMAKE_VS_PLATFORM_TOOLSET_CUDA` variable.
+``cuda=<version>|<path>``
+  Specify the CUDA toolkit version to use or the path to a
+  standalone CUDA toolkit directory.  Supported by VS 2010
+  and above. The version can only be used with the CUDA
+  toolkit VS integration globally installed.
+  See the :variable:`CMAKE_VS_PLATFORM_TOOLSET_CUDA` and
+  :variable:`CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR` variables.
 
 ``host=<arch>``
   Specify the host tools architecture as ``x64`` or ``x86``.

+ 4 - 2
Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA.rst

@@ -6,7 +6,9 @@ NVIDIA CUDA Toolkit version whose Visual Studio toolset to use.
 The :ref:`Visual Studio Generators` for VS 2010 and above support using
 a CUDA toolset provided by a CUDA Toolkit.  The toolset version number
 may be specified by a field in :variable:`CMAKE_GENERATOR_TOOLSET` of
-the form ``cuda=8.0``.  If none is specified CMake will choose a default
-version.  CMake provides the selected CUDA toolset version in this variable.
+the form ``cuda=8.0``. Or it is automatically detected if a path to
+a standalone CUDA directory is specified in the form ``cuda=C:\path\to\cuda``.
+If none is specified CMake will choose a default version.
+CMake provides the selected CUDA toolset version in this variable.
 The value may be empty if no CUDA Toolkit with Visual Studio integration
 is installed.

+ 16 - 0
Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR.rst

@@ -0,0 +1,16 @@
+CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR
+-----------------------------------------
+
+Path to standalone NVIDIA CUDA Toolkit (eg. extracted from installer).
+
+The :ref:`Visual Studio Generators` for VS 2010 and above support using
+a standalone (non-installed) NVIDIA CUDA toolkit.  The path
+may be specified by a field in :variable:`CMAKE_GENERATOR_TOOLSET` of
+the form ``cuda=C:\path\to\cuda``.  The given directory must at least
+contain a folder ``.\nvcc`` and must provide Visual Studio integration
+files in path ``.\CUDAVisualStudioIntegration\extras\
+visual_studio_integration\MSBuildExtensions\``. One can create a standalone
+CUDA toolkit directory by either opening a installer with 7zip or
+copying the files that are extracted by the running installer.
+The value may be empty if no path to a standalone CUDA Toolkit was
+specified.

+ 8 - 2
Modules/CMakeDetermineCompilerId.cmake

@@ -347,8 +347,14 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
       set(cuda_tools "CUDA ${CMAKE_VS_PLATFORM_TOOLSET_CUDA}")
       set(id_compile "CudaCompile")
       set(id_PostBuildEvent_Command [[echo CMAKE_CUDA_COMPILER=$(CudaToolkitBinDir)\nvcc.exe]])
-      string(CONCAT id_Import_props [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.props" />]])
-      string(CONCAT id_Import_targets [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.targets" />]])
+      if(CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR)
+        set(id_CudaToolkitCustomDir "<CudaToolkitCustomDir>${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}nvcc</CudaToolkitCustomDir>")
+        string(CONCAT id_Import_props "<Import Project=\"${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}\\CUDAVisualStudioIntegration\\extras\\visual_studio_integration\\MSBuildExtensions\\${cuda_tools}.props\" />")
+        string(CONCAT id_Import_targets "<Import Project=\"${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}\\CUDAVisualStudioIntegration\\extras\\visual_studio_integration\\MSBuildExtensions\\${cuda_tools}.targets\" />")
+      else()
+        string(CONCAT id_Import_props [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.props" />]])
+        string(CONCAT id_Import_targets [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.targets" />]])
+      endif()
       if(CMAKE_VS_PLATFORM_NAME STREQUAL x64)
         set(id_ItemDefinitionGroup_entry "<CudaCompile><TargetMachinePlatform>64</TargetMachinePlatform></CudaCompile>")
       endif()

+ 1 - 0
Modules/CompilerId/VS-10.vcxproj.in

@@ -14,6 +14,7 @@
     @id_system_version@
     @id_WindowsTargetPlatformVersion@
     @id_WindowsSDKDesktopARMSupport@
+    @id_CudaToolkitCustomDir@
   </PropertyGroup>
   @id_toolset_version_props@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

+ 56 - 2
Source/cmGlobalVisualStudio10Generator.cxx

@@ -232,7 +232,15 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
   if (this->GeneratorToolsetCuda.empty()) {
     // Find the highest available version of the CUDA tools.
     std::vector<std::string> cudaTools;
-    std::string const bcDir = this->VCTargetsPath + "/BuildCustomizations";
+    std::string bcDir;
+    if (this->GeneratorToolsetCudaCustomDir.empty()) {
+      bcDir = this->VCTargetsPath + "/BuildCustomizations";
+    } else {
+      bcDir = this->GetPlatformToolsetCudaCustomDirString() +
+        "CUDAVisualStudioIntegration\\extras\\"
+        "visual_studio_integration\\MSBuildExtensions";
+      cmSystemTools::ConvertToUnixSlashes(bcDir);
+    }
     cmsys::Glob gl;
     gl.SetRelative(bcDir.c_str());
     if (gl.FindFiles(bcDir + "/CUDA *.props")) {
@@ -243,6 +251,24 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
       std::sort(cudaTools.begin(), cudaTools.end(),
                 cmSystemTools::VersionCompareGreater);
       this->GeneratorToolsetCuda = cudaTools.at(0);
+    } else if (!this->GeneratorToolsetCudaCustomDir.empty()) {
+      // Generate an error if Visual Studio integration files are not found
+      // inside of custom cuda toolset.
+      std::ostringstream e;
+      /* clang-format off */
+      e <<
+        "Generator\n"
+        "  " << this->GetName() << "\n"
+        "given toolset\n"
+        "  cuda=" << this->GeneratorToolsetCudaCustomDir << "\n"
+        "cannot detect Visual Studio integration files in path\n"
+        "  " << bcDir;
+
+      /* clang-format on */
+      mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+
+      // Clear the configured tool-set
+      this->GeneratorToolsetCuda.clear();
     }
   }
 
@@ -319,6 +345,9 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
   if (const char* cuda = this->GetPlatformToolsetCuda()) {
     mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_CUDA", cuda);
   }
+  if (const char* cudaDir = this->GetPlatformToolsetCudaCustomDir()) {
+    mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR", cudaDir);
+  }
   return true;
 }
 
@@ -395,7 +424,17 @@ bool cmGlobalVisualStudio10Generator::ProcessGeneratorToolsetField(
   std::string const& key, std::string const& value)
 {
   if (key == "cuda") {
-    this->GeneratorToolsetCuda = value;
+    /* test if cuda toolset is path to custom dir or cuda version */
+    auto pos = value.find_first_not_of("0123456789.");
+    if (pos != std::string::npos) {
+      this->GeneratorToolsetCudaCustomDir = value;
+      /* ensure trailing backslash for easy path joining */
+      if (this->GeneratorToolsetCudaCustomDir.back() != '\\') {
+        this->GeneratorToolsetCudaCustomDir.push_back('\\');
+      }
+    } else {
+      this->GeneratorToolsetCuda = value;
+    }
     return true;
   }
   if (key == "version") {
@@ -643,6 +682,21 @@ cmGlobalVisualStudio10Generator::GetPlatformToolsetCudaString() const
   return this->GeneratorToolsetCuda;
 }
 
+const char* cmGlobalVisualStudio10Generator::GetPlatformToolsetCudaCustomDir()
+  const
+{
+  if (!this->GeneratorToolsetCudaCustomDir.empty()) {
+    return this->GeneratorToolsetCudaCustomDir.c_str();
+  }
+  return nullptr;
+}
+
+std::string const&
+cmGlobalVisualStudio10Generator::GetPlatformToolsetCudaCustomDirString() const
+{
+  return this->GeneratorToolsetCudaCustomDir;
+}
+
 bool cmGlobalVisualStudio10Generator::IsDefaultToolset(
   const std::string&) const
 {

+ 5 - 0
Source/cmGlobalVisualStudio10Generator.h

@@ -61,6 +61,10 @@ public:
   const char* GetPlatformToolsetCuda() const;
   std::string const& GetPlatformToolsetCudaString() const;
 
+  /** The custom cuda install directory */
+  const char* GetPlatformToolsetCudaCustomDir() const;
+  std::string const& GetPlatformToolsetCudaCustomDirString() const;
+
   /** Return whether we need to use No/Debug instead of false/true
       for GenerateDebugInformation.  */
   bool GetPlatformToolsetNeedsDebugEnum() const
@@ -152,6 +156,7 @@ protected:
   std::string GeneratorToolsetVersion;
   std::string GeneratorToolsetHostArchitecture;
   std::string GeneratorToolsetCuda;
+  std::string GeneratorToolsetCudaCustomDir;
   std::string DefaultPlatformToolset;
   std::string DefaultPlatformToolsetHostArchitecture;
   std::string WindowsTargetPlatformVersion;

+ 25 - 4
Source/cmVisualStudio10TargetGenerator.cxx

@@ -527,6 +527,13 @@ void cmVisualStudio10TargetGenerator::Generate()
           }
           e1.Element("TargetFrameworkTargetsVersion", targetFrameworkVer);
         }
+        if (!this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString()
+               .empty()) {
+          e1.Element(
+            "CudaToolkitCustomDir",
+            this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString() +
+              "nvcc");
+        }
       }
 
       // Disable the project upgrade prompt that is displayed the first time a
@@ -613,10 +620,17 @@ void cmVisualStudio10TargetGenerator::Generate()
       e1.SetHasElements();
 
       if (this->GlobalGenerator->IsCudaEnabled()) {
+        auto customDir =
+          this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString();
+        std::string cudaPath = customDir.empty()
+          ? "$(VCTargetsPath)\\BuildCustomizations\\"
+          : customDir +
+            "CUDAVisualStudioIntegration\\extras\\"
+            "visual_studio_integration\\MSBuildExtensions\\";
         Elem(e1, "Import")
           .Attribute("Project",
-                     "$(VCTargetsPath)\\BuildCustomizations\\CUDA " +
-                       this->GlobalGenerator->GetPlatformToolsetCudaString() +
+                     std::move(cudaPath) + "CUDA " +
+                       this->GlobalGenerator->GetPlatformToolsetCuda() +
                        ".props");
       }
       if (this->GlobalGenerator->IsMasmEnabled()) {
@@ -698,10 +712,17 @@ void cmVisualStudio10TargetGenerator::Generate()
       e1.SetHasElements();
       this->WriteTargetsFileReferences(e1);
       if (this->GlobalGenerator->IsCudaEnabled()) {
+        auto customDir =
+          this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString();
+        std::string cudaPath = customDir.empty()
+          ? "$(VCTargetsPath)\\BuildCustomizations\\"
+          : customDir +
+            "CUDAVisualStudioIntegration\\extras\\"
+            "visual_studio_integration\\MSBuildExtensions\\";
         Elem(e1, "Import")
           .Attribute("Project",
-                     "$(VCTargetsPath)\\BuildCustomizations\\CUDA " +
-                       this->GlobalGenerator->GetPlatformToolsetCudaString() +
+                     std::move(cudaPath) + "CUDA " +
+                       this->GlobalGenerator->GetPlatformToolsetCuda() +
                        ".targets");
       }
       if (this->GlobalGenerator->IsMasmEnabled()) {

+ 7 - 5
Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake

@@ -6,12 +6,14 @@ run_cmake(NoToolset)
 if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012456]")
   set(RunCMake_GENERATOR_TOOLSET "Test Toolset")
   run_cmake(TestToolset)
-  set(RunCMake_GENERATOR_TOOLSET "Test Toolset,cuda=Test Cuda")
+  set(RunCMake_GENERATOR_TOOLSET "Test Toolset,cuda=0.0")
   run_cmake(TestToolsetCudaBoth)
-  set(RunCMake_GENERATOR_TOOLSET ",cuda=Test Cuda")
-  run_cmake(TestToolsetCudaOnly)
-  set(RunCMake_GENERATOR_TOOLSET "cuda=Test Cuda")
-  run_cmake(TestToolsetCudaOnly)
+  set(RunCMake_GENERATOR_TOOLSET ",cuda=0.0")
+  run_cmake(TestToolsetCudaVersionOnly)
+  set(RunCMake_GENERATOR_TOOLSET "cuda=0.0")
+  run_cmake(TestToolsetCudaVersionOnly)
+  set(RunCMake_GENERATOR_TOOLSET "cuda=C:\\dummy\\cuda")
+  run_cmake(TestToolsetCudaPathOnly)
   if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[2456]")
     set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64")
     run_cmake(TestToolsetHostArchBoth)

+ 1 - 1
Tests/RunCMake/GeneratorToolset/TestToolsetCudaBoth-stdout.txt

@@ -1,2 +1,2 @@
 -- CMAKE_VS_PLATFORM_TOOLSET='Test Toolset'
--- CMAKE_VS_PLATFORM_TOOLSET_CUDA='Test Cuda'
+-- CMAKE_VS_PLATFORM_TOOLSET_CUDA='0.0'

+ 1 - 0
Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnly-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnly-stderr.txt

@@ -0,0 +1,12 @@
+CMake Error at CMakeLists.txt:[0-9]+ \(project\):
+  Generator
+
+    Visual Studio .*
+
+  given toolset
+
+    cuda=C:\\dummy\\cuda\\
+
+  cannot detect Visual Studio integration files in path
+
+    C:/dummy/cuda/CUDAVisualStudioIntegration/extras/visual_studio_integration/MSBuildExtensions

+ 1 - 0
Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnly.cmake

@@ -0,0 +1 @@
+message(FATAL_ERROR "This should not be reached!")

+ 1 - 1
Tests/RunCMake/GeneratorToolset/TestToolsetCudaOnly-stdout.txt → Tests/RunCMake/GeneratorToolset/TestToolsetCudaVersionOnly-stdout.txt

@@ -1,2 +1,2 @@
 -- CMAKE_VS_PLATFORM_TOOLSET='(v[0-9]+|Windows7.1SDK)'
--- CMAKE_VS_PLATFORM_TOOLSET_CUDA='Test Cuda'
+-- CMAKE_VS_PLATFORM_TOOLSET_CUDA='0.0'

+ 0 - 0
Tests/RunCMake/GeneratorToolset/TestToolsetCudaOnly.cmake → Tests/RunCMake/GeneratorToolset/TestToolsetCudaVersionOnly.cmake