title: Multi-config/multi-platform build for CUDA using CMake
body: <p>I've had a bit of a fight with CMake lately trying to get it to generate project files for Debug and Release targets on different platforms involving Cuda. The Cuda version I'm using is 9.1 on Windows and Linux. CMake version is 3.9 on Windows and 3.10 on Linux.</p>
  
  <p>The problem is actually simple, because I can generate the builds on Windows if <em>nvcc</em> gets passed the <code>"-DEBUG"</code> flag correctly. However, I cannot seem to pass the flag correctly by configuration automatically. I tried using <code>CMAKE_NVCC_FLAGS_CONFIG</code>, <code>CMAKE_CXX_FLAGS_CONFIG</code> with <code>CUDA_PROPAGATE_HOST_FLAGS</code> set to <code>ON/OFF</code>, switching <code>CUDA_HOST_COMPILATION_CPP</code> to <code>ON/OFF</code> did not help either. Setting the flag using expression generators to set directory properties using <code>set_directory_property</code>, or as an option to <code>cuda_add_executable</code> also did not work.</p>
  
  <p>Here's the gist of my cmake script:</p>
  
  <pre><code># CMake entry point
  cmake_minimum_required (VERSION 3.9.1)
  
  set( APP_NAME example-CUDA )
  
  find_package(XYZ)
  find_package(CUDA)  # not required according to 1st-class status in CMake3 .8+
  
  enable_language(CUDA)
  set(CUDA_VERBOSE_BUILD ON)
  
  set(SRC_EXAMPLE "main.cpp" "gj.cu"  "gj.cuh")
  SOURCE_GROUP(Example FILES ${SRC_EXAMPLE})
  
  set(SRC_BUILD_FILES ${SRC_EXAMPLE})
  
  # note: similar stuff for linux ommitted..
  if("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX /sdl- -Zm256")
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MD")
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /we4146 /we4308 /we4532 /we4533 /we4700 /we4703 /we4789 /we4995 /we4996")
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /INCREMENTAL")
      set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MP")
      set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /we4146 /we4308 /we4532 /we4533 /we4700 /we4703 /we4789 /we4995 /we4996")
      set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W4 /WX /sdl- -Zm256")
      set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Zi")
      set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG" CACHE STRING "compile flags debug" FORCE)
  endif()
  
  # cuda 9 flags for max compatibility ( note: no more sm 20!)
  set(CUDA_NVCC_FLAGS   ${CUDA_NVCC_FLAGS}    "-arch=sm_30 -gencode=arch=compute_30,code=sm_30 -gencode=arch=compute_50,code=sm_50 -gencode=arch=compute_52,code=sm_52 -gencode=arch=compute_60,code=sm_60 -gencode=arch=compute_61,code=sm_61 -gencode=arch=compute_62,code=sm_62 -gencode=arch=compute_70,code=sm_70 -gencode=arch=compute_70,code=compute_70")
  
  include_directories(SYSTEM  ${CUDA_TOOLKIT_INCLUDE} ${CMAKE_CURRENT_SOURCE_DIR})
  
  #set(CUDA_HOST_COMPILATION_CPP ON) 
  #set(CUDA_PROPAGATE_HOST_FLAGS ON)
  
  #set(CUDA_NVCC_FLAGS   ${CUDA_NVCC_FLAGS}   " -D_DEBUG ")             # works, but hadcoded config :(
  
  set(CUDA_NVCC_FLAGS_DEBUG   ${CUDA_NVCC_FLAGS_DEBUG}    " -D_DEBUG ") # fails, not picked up..
  
  #cuda_add_executable (${APP_NAME} ${SRC_EXAMPLE} OPTIONS $&lt;$&lt;CONFIG:Debug&gt;:"-DEBUG"&gt;) #fails, generator not run
  
  cuda_add_executable (${APP_NAME} ${SRC_EXAMPLE})
  target_link_libraries (${APP_NAME} PUBLIC CUDA XYZ)
  </code></pre>
  
  <p>The error I get in VS2015 (and I'm also using 2017) is the typical _ITERATOR_DEBUG_LEVEL not being correct, implying that one of the compilation units was not properly passed the -DEBUG flag and the linker sees rebug and release modules mixed. The module built by nvcc.exe is internally passed on for compilation by cl.exe for non-cuda code bits, except that all the _DEBUG configuration flags are missing. I've read through FindCUDA.cmake to find something interesting but it's almost impossible to tell what is working and what is not.</p>
  
  <p>I'm obviously missing something, but what? Any workarounds?</p>
  
  <p>UPDATE 1:  I also set the following way earlier in the CMakeLists.txt hierarchy:</p>
  
  <pre><code>project (MyLittleBigProject)
  
  # Set default build type
  set(PROJECT_CONFIGURATIONS      Debug Release               CACHE TYPE INTERNAL FORCE)
  if(DEFINED CMAKE_BUILD_TYPE)
      set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Build configs: ${PROJECT_CONFIGURATIONS}")
  else()
      set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build configs: ${PROJECT_CONFIGURATIONS}")
  endif()
  </code></pre>