CUDA MEX file generation with CMAKE this works for me

Thanks to J. Bigler I have managed to make a cmake file that works at least on 64bit windows and linux, when using VS2008.

I have a few files that need to be compiled with -maxrregcount 85, so you will see below how to have some kernels compiled with different nvcc flags.

cmake_minimum_required(VERSION 2.8)

set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS 1)

FIND_PACKAGE(Matlab)

INCLUDE_DIRECTORIES(${MATLAB_INCLUDE_DIR})

FIND_PACKAGE(CUDA)

set(NO_LIMIT cuda_mex_headers.cu helpers.cu kernel1.cu)

set(LIMIT_85 kernel2.cu kernel3.cu)

set(MEX_FILE cuda_mex_kernel.cu )

set(CUDA_NVCC_FLAGS -arch sm_13;--ptxas-options=-v)

CUDA_COMPILE( generated_files0 ${NO_LIMIT} SHARED)

CUDA_COMPILE( generated_files1 ${LIMIT_85} SHARED OPTIONS -maxrregcount 85)

CUDA_COMPILE( cuda_mex_kernel_generated ${MEX_FILE} SHARED)

ADD_LIBRARY(cuda_mex_kernel SHARED ${cuda_mex_kernel_generated} ${MEX_FILE}

  ${generated_files0}

  ${NO_LIMIT}

  ${generated_files1}

  ${LIMIT_85}

  )

TARGET_LINK_LIBRARIES(cuda_mex_kernel ${MATLAB_LIBRARIES} ${CUDA_LIBRARIES})

SET_TARGET_PROPERTIES(cuda_mex_kernel PROPERTIES PREFIX "" LINKER_LANGUAGE CXX)

if(WIN32)

  if (CMAKE_CL_64)

	  MESSAGE("Win 64")

	  SET_TARGET_PROPERTIES(rtt_kernel PROPERTIES

		  SUFFIX .mexw64

		  LINK_FLAGS /export:mexFunction

	  )

  else()

	  MESSAGE("Win 32")

	  SET_TARGET_PROPERTIES(rtt_kernel PROPERTIES

		  SUFFIX .mexw32

		  LINK_FLAGS /export:mexFunction

	  )

  endif()

else(UNIX)

  if (CMAKE_SIZEOF_VOID_P MATCHES "8")

  MESSAGE("Linux 64")

	  SET_TARGET_PROPERTIES(rtt_kernel PROPERTIES SUFFIX .mexa64)

  else()

	  MESSAGE("Linux 32")

	  SET_TARGET_PROPERTIES(rtt_kernel PROPERTIES SUFFIX .mexglx)

  endif (CMAKE_SIZEOF_VOID_P MATCHES "8")

endif()

Thanks for posting this, so that all may benefit from your experience.

The thing to note here is the use of add_library instead of cuda_add_library. cuda_add_library will compile all the files with the same set of flags, which is not what E.D. Riedijk wanted. He attempted this first (abbreviated).

CUDA_COMPILE( generated_files1 ${LIMIT_85} SHARED OPTIONS -maxrregcount 85)

CUDA_ADD_LIBRARY(cuda_mex_kernel SHARED ${generated_files1})

This didn’t work. CUDA_COMPILE expects that both {generated_files1} and {LIMIT_85} will be added to the target when CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE is ON (default), because of the way that build rules are set up for Visual Studio projects. VS applies rules to the sources, so only the sources need to be added to the solution and generated_files1 will be empty. Makefiles attach rules to the generated files and generated_files1 will not be empty.

At any rate, you can’t add {LIMIT_85} to CUDA_ADD_LIBRARY either, because there is already a build rule set up for them in the previous CUDA_COMPILE command. The only way to get both generated_files1 and LIMIT_85 into the same target is to bypass CUDA_ADD_LIBRARY and replicate the function explicitly with the code that E.D. posted (making sure to call target_link_libraries({CUDA_LIBRARIES}) and set_target_properties(PROPERTIES LINKER_LANGUAGE CXX) ).