Browse Source

Merge topic 'ninja_multi_config_support_cuda'

c7ac13e8ed CUDA: Mult-Config Ninja generator now supports CUDA

Acked-by: Kitware Robot <[email protected]>
Merge-request: !4187
Kyle Edwards 5 years ago
parent
commit
93526fd913

+ 38 - 7
Source/cmNinjaNormalTargetGenerator.cxx

@@ -83,15 +83,15 @@ void cmNinjaNormalTargetGenerator::Generate(const std::string& config)
   if (this->GetGeneratorTarget()->GetType() == cmStateEnums::OBJECT_LIBRARY) {
     this->WriteObjectLibStatement(config);
   } else {
-    // If this target has cuda language link inputs, and we need to do
-    // device linking
-    this->WriteDeviceLinkStatement(config);
     firstForConfig = true;
     for (auto const& fileConfig : this->GetConfigNames()) {
       if (fileConfig != config &&
           !this->GetGlobalGenerator()->EnableCrossConfigBuild()) {
         continue;
       }
+      // If this target has cuda language link inputs, and we need to do
+      // device linking
+      this->WriteDeviceLinkStatement(config, fileConfig, firstForConfig);
       this->WriteLinkStatement(config, fileConfig, firstForConfig);
       firstForConfig = false;
     }
@@ -561,7 +561,8 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
 }
 
 void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement(
-  const std::string& config)
+  const std::string& config, const std::string& fileConfig,
+  bool firstForConfig)
 {
   cmGlobalNinjaGenerator* globalGen = this->GetGlobalGenerator();
   if (!globalGen->GetLanguageEnabled("CUDA")) {
@@ -584,12 +585,42 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement(
   std::string const& objExt =
     this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION");
 
-  std::string const targetOutputReal = ConvertToNinjaPath(
-    genTarget->ObjectDirectory + "cmake_device_link" + objExt);
+  std::string targetOutputDir =
+    cmStrCat(this->GetLocalGenerator()->GetTargetDirectory(genTarget),
+             globalGen->ConfigDirectory(config), "/");
+  targetOutputDir = globalGen->ExpandCFGIntDir(targetOutputDir, config);
 
-  std::string const targetOutputImplib = ConvertToNinjaPath(
+  std::string targetOutputReal =
+    ConvertToNinjaPath(targetOutputDir + "cmake_device_link" + objExt);
+
+  std::string targetOutputImplib = ConvertToNinjaPath(
     genTarget->GetFullPath(config, cmStateEnums::ImportLibraryArtifact));
 
+  if (config != fileConfig) {
+    std::string targetOutputFileConfigDir =
+      cmStrCat(this->GetLocalGenerator()->GetTargetDirectory(genTarget),
+               globalGen->ConfigDirectory(fileConfig), "/");
+    targetOutputFileConfigDir =
+      globalGen->ExpandCFGIntDir(targetOutputDir, fileConfig);
+    if (targetOutputDir == targetOutputFileConfigDir) {
+      return;
+    }
+
+    if (!genTarget->GetFullName(config, cmStateEnums::ImportLibraryArtifact)
+           .empty() &&
+        !genTarget
+           ->GetFullName(fileConfig, cmStateEnums::ImportLibraryArtifact)
+           .empty() &&
+        targetOutputImplib ==
+          ConvertToNinjaPath(genTarget->GetFullPath(
+            fileConfig, cmStateEnums::ImportLibraryArtifact))) {
+      return;
+    }
+  }
+
+  if (firstForConfig) {
+    globalGen->GetByproductsForCleanTarget(config).push_back(targetOutputReal);
+  }
   this->DeviceLinkObject = targetOutputReal;
 
   // Write comments.

+ 3 - 1
Source/cmNinjaNormalTargetGenerator.h

@@ -31,7 +31,9 @@ private:
 
   void WriteLinkStatement(const std::string& config,
                           const std::string& fileConfig, bool firstForConfig);
-  void WriteDeviceLinkStatement(const std::string& config);
+  void WriteDeviceLinkStatement(const std::string& config,
+                                const std::string& fileConfig,
+                                bool firstForConfig);
 
   void WriteObjectLibStatement(const std::string& config);
 

+ 3 - 0
Tests/RunCMake/CMakeLists.txt

@@ -140,6 +140,9 @@ if(CMAKE_GENERATOR MATCHES "Ninja")
   if(CMake_TEST_Qt5 AND Qt5Core_FOUND)
     list(APPEND NinjaMultiConfig_ARGS -DCMake_TEST_Qt5=1)
   endif()
+  if(DEFINED CMake_TEST_CUDA)
+    list(APPEND NinjaMultiConfig_ARGS -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
+  endif()
   add_RunCMake_test(NinjaMultiConfig)
 endif()
 add_RunCMake_test(CTest)

+ 21 - 0
Tests/RunCMake/NinjaMultiConfig/CudaSimple-all-clean-build-check.cmake

@@ -0,0 +1,21 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+  INCLUDE
+    ${GENERATED_FILES}
+
+  EXCLUDE
+    ${TARGET_OBJECT_FILES_simplecudaexe_Debug}
+    ${TARGET_OBJECT_FILES_simplecudashared_Debug}
+    ${TARGET_OBJECT_FILES_simplecudaobj_Debug}
+
+    ${TARGET_OBJECT_FILES_simplecudaexe_Release}
+    ${TARGET_OBJECT_FILES_simplecudashared_Release}
+    ${TARGET_OBJECT_FILES_simplecudaobj_Release}
+
+    ${TARGET_OBJECT_FILES_simplecudaexe_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simplecudashared_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simplecudaobj_MinSizeRel}
+
+    ${TARGET_OBJECT_FILES_simplecudaexe_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simplecudashared_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simplecudaobj_RelWithDebInfo}
+  )

+ 27 - 0
Tests/RunCMake/NinjaMultiConfig/CudaSimple-debug-target-build-check.cmake

@@ -0,0 +1,27 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+  INCLUDE
+    ${GENERATED_FILES}
+
+    ${TARGET_FILE_simplecudaexe_Debug}
+    ${TARGET_OBJECT_FILES_simplecudaexe_Debug}
+
+    ${TARGET_FILE_simplecudashared_Debug}
+    ${TARGET_LINKER_FILE_simplecudashared_Debug}
+    ${TARGET_OBJECT_FILES_simplecudashared_Debug}
+
+    ${TARGET_OBJECT_FILES_simplecudaobj_Debug}
+
+  EXCLUDE
+
+    ${TARGET_OBJECT_FILES_simplecudaexe_Release}
+    ${TARGET_OBJECT_FILES_simplecudashared_Release}
+    ${TARGET_OBJECT_FILES_simplecudaobj_Release}
+
+    ${TARGET_OBJECT_FILES_simplecudaexe_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simplecudashared_MinSizeRel}
+    ${TARGET_OBJECT_FILES_simplecudaobj_MinSizeRel}
+
+    ${TARGET_OBJECT_FILES_simplecudaexe_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simplecudashared_RelWithDebInfo}
+    ${TARGET_OBJECT_FILES_simplecudaobj_RelWithDebInfo}
+  )

+ 21 - 0
Tests/RunCMake/NinjaMultiConfig/CudaSimple.cmake

@@ -0,0 +1,21 @@
+enable_language(CUDA)
+file(TOUCH ${CMAKE_BINARY_DIR}/empty.cmake)
+
+add_library(simplecudaobj OBJECT simplelib.cu)
+set_target_properties(simplecudaobj
+                      PROPERTIES
+                      POSITION_INDEPENDENT_CODE ON)
+
+add_library(simplecudashared SHARED )
+target_link_libraries(simplecudashared PRIVATE simplecudaobj)
+set_target_properties(simplecudaobj simplecudashared
+                      PROPERTIES
+                      CUDA_SEPARABLE_COMPILATION ON)
+
+add_executable(simplecudaexe main.cu )
+target_link_libraries(simplecudaexe PRIVATE simplecudashared)
+
+include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
+generate_output_files(simplecudaexe simplecudashared simplecudaobj)
+
+file(APPEND "${CMAKE_BINARY_DIR}/target_files.cmake" "set(GENERATED_FILES [==[${CMAKE_BINARY_DIR}/empty.cmake]==])\n")

+ 8 - 0
Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake

@@ -184,6 +184,14 @@ run_ninja(Install debug-in-release-graph-install build-Release.ninja install:Deb
 #run_cmake_configure(AutoMocExecutable)
 #run_cmake_build(AutoMocExecutable debug-in-release-graph Release exe)
 
+if(CMake_TEST_CUDA)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CudaSimple-build)
+  run_cmake_configure(CudaSimple)
+  include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+  run_cmake_build(CudaSimple debug-target Debug simplecudaexe)
+  run_ninja(CudaSimple all-clean build-Debug.ninja clean:Debug)
+endif()
+
 if(CMake_TEST_Qt5)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Qt5-build)
   set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_CROSS_CONFIG_ENABLE=ON")

+ 15 - 0
Tests/RunCMake/NinjaMultiConfig/main.cu

@@ -0,0 +1,15 @@
+
+#include <cuda.h>
+
+#ifdef _WIN32
+#  define IMPORT __declspec(dllimport)
+#else
+#  define IMPORT
+#endif
+
+IMPORT int simplelib();
+
+int main(void)
+{
+  return simplelib();
+}

+ 9 - 0
Tests/RunCMake/NinjaMultiConfig/simplelib.cu

@@ -0,0 +1,9 @@
+#include <cuda.h>
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+  int simplelib()
+{
+  return 0;
+}