title: CUDA Link Error (Lib to Dll)
body: <p>Im trying to create a framework to be able to use CUDA code in several game engine. To be able to communicate with all the wanted engines the frame consists of two main parts. A Lib and a DLL. The Lib contains all the functionality (CUDA and regular C++) and the DLL functions as a bridge to call functions from the Lib.</p>
  
  <p>Now, everything was running oke untill I've included a .cu file. When I'm building I'm getting the following error:</p>
  
  <pre><code>Error   3   error LNK2019: unresolved external symbol _Add2And7 referenced in function "public: void __thiscall PerceptorHost::UpdatePerceptorHost(void)" (?UpdatePerceptorHost@PerceptorHost@@QAEXXZ)  D:\_Professional\DAE_Research\2_Projects\PWO_ePerceptor\Source\build\src\Native_ePerceptor_Dll\Native_ePerceptor_Lib.lib(PerceptorHost.obj) Native_ePerceptor_Dll
  </code></pre>
  
  <p>When I look at the buildlogs the Lib is building fine (Native_ePerceptor_Lib.lib). It's the DLL that fails.</p>
  
  <p>Last but not least, the project has to be created using CMake (to be able to tackle different setups). Below you can find snippets of the .cu, Lib .cpp en the Dll .cpp. I looked across the interwebs to be able to find a solution but most of the solutions are regarding issues in one project and not regarding libraries. I'm pretty desperate at the moment so I hope some of you can point out what the issue, and hopefully, what a possible solution is.
  One more thing, I'm pretty sure all the necessary libraries are being included (cudart, cuda).</p>
  
  <p><strong>Kernel.cu</strong></p>
  
  <pre><code>#include &lt;cuda\cuda_runtime.h&gt;
  
  __global__ void add(int a, int b, int *c) 
  {
      *c += a + b;
      printf("%i + %i = %i \n", a, b, *c);
  }
  
  extern "C" void Add2And7(int *c)
  {
      int *dev_c;
  
      //Allocate GPU memory
      cudaMalloc((void**)&amp;dev_c, sizeof(int));
  
      add &lt;&lt;&lt;1, 1&gt;&gt;&gt;(2, 7, dev_c);
  
      //Copy GPU to CPU
      cudaMemcpy(c, dev_c, sizeof(int),
          cudaMemcpyDeviceToHost);
  
      //printf("number is %u \n", &amp;c);
  
      //Free allocated GPU memory
      cudaFree(dev_c);
  }
  </code></pre>
  
  <p><strong>PerceptorHost.cpp</strong></p>
  
  <pre><code>//Forward declaration
  extern "C" void Add2And7(int *c);
  
  void PerceptorHost::UpdatePerceptorHost()
  {
      if (!g_bIsBooted)
          return;
  
      if (!m_bTestKernel)
      {
          int output = 0;
          Add2And7(&amp;output);
          printf("2 + 7 = %i \n", output);
          m_bTestKernel = true;
      }
  }
  </code></pre>
  
  <p><strong>DLL.cpp</strong></p>
  
  <pre><code>extern "C" NATIVEDLL_API void __cdecl UpdatePerceptorHost()
  {
      PERCEPTORHOST-&gt;UpdatePerceptorHost(); //Update the PerceptorHost and all it's managers
  }
  </code></pre>
  
  <p><strong>CMAKE</strong></p>
  
  <pre><code>########################################################################
  # Add all source files to variables
  # CPU Source Files
  FILE(GLOB SRCS *.cpp)
  FILE(GLOB HDRS *.h )
  FILE(GLOB CUDA_HDRS 
          ${CMAKE_SOURCE_DIR}/include/cuda/*.h)
  FILE(GLOB CALIBRATION_FILES 
          RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
          ${CMAKE_CURRENT_SOURCE_DIR}/Calibration/*.cpp
          ${CMAKE_CURRENT_SOURCE_DIR}/Calibration/*.h)     
  FILE(GLOB CORE_FILES 
          RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
          ${CMAKE_CURRENT_SOURCE_DIR}/Core/*.cpp
          ${CMAKE_CURRENT_SOURCE_DIR}/Core/*.h)   
  FILE(GLOB DATAPROVIDER_FILES 
          RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
          ${CMAKE_CURRENT_SOURCE_DIR}/Data/DataProvider/*.cpp
          ${CMAKE_CURRENT_SOURCE_DIR}/Data/DataProvider/*.h)
  FILE(GLOB RESOURCEMANAGER_FILES 
          RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
          ${CMAKE_CURRENT_SOURCE_DIR}/Data/ResourceManager/*.cpp
          ${CMAKE_CURRENT_SOURCE_DIR}/Data/ResourceManager/*.h)       
  FILE(GLOB DEBUG_FILES 
          RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
          ${CMAKE_CURRENT_SOURCE_DIR}/Debug/*.cpp
          ${CMAKE_CURRENT_SOURCE_DIR}/Debug/*.h)  
  FILE(GLOB EXCEPTION_FILES 
          RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
          ${CMAKE_CURRENT_SOURCE_DIR}/Exceptions/*.cpp
          ${CMAKE_CURRENT_SOURCE_DIR}/Exceptions/*.h)
  FILE(GLOB HELPERS_FILES 
          RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
          ${CMAKE_CURRENT_SOURCE_DIR}/Helpers/*.cpp
          ${CMAKE_CURRENT_SOURCE_DIR}/Helpers/*.h)        
  FILE(GLOB VIDEOWRITER_FILES 
          RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
          ${CMAKE_CURRENT_SOURCE_DIR}/VideoWriter/*.cpp
          ${CMAKE_CURRENT_SOURCE_DIR}/VideoWriter/*.h)
  # GPU Source Files      
  FILE(GLOB GPU_HELPERS_FILES
          ${CMAKE_CURRENT_SOURCE_DIR}/Helpers/*.cuh
          ${CMAKE_CURRENT_SOURCE_DIR}/Helpers/*.cu)       
  
  ########################################################################
  # Group all source files
  SOURCE_GROUP("Calibration" FILES ${CALIBRATION_FILES})
  SOURCE_GROUP("Core" FILES ${CORE_FILES})
  SOURCE_GROUP("DataProvider" FILES ${DATAPROVIDER_FILES})
  SOURCE_GROUP("ResourceManager" FILES ${RESOURCEMANAGER_FILES})
  SOURCE_GROUP("Debug" FILES ${DEBUG_FILES})
  SOURCE_GROUP("Exceptions" FILES ${EXCEPTION_FILES})
  SOURCE_GROUP("Helpers" FILES ${HELPERS_FILES})
  SOURCE_GROUP("VideoWriter" FILES ${VIDEOWRITER_FILES})
  
  ########################################################################
  # Set this part as static lib
  IF (D_ENABLE_LIBRARY_CUDA)
  CUDA_ADD_LIBRARY(Native_ePerceptor_Lib
      ${CUDA_HDRS}
      ${CALIBRATION_FILES}
      ${CORE_FILES}
      ${DATAPROVIDER_FILES}
      ${RESOURCEMANAGER_FILES}
      ${DEBUG_FILES}
      ${EXCEPTION_FILES}
      ${HELPERS_FILES}
      ${VIDEOWRITER_FILES}
      ${SRCS}
      ${HDRS}
      ${GPU_HELPERS_FILES}
      )
  ELSE()
      ADD_LIBRARY(Native_ePerceptor_Lib
      ${CUDA_HDRS}
      ${CALIBRATION_FILES}
      ${CORE_FILES}
      ${DATAPROVIDER_FILES}
      ${RESOURCEMANAGER_FILES}
      ${DEBUG_FILES}
      ${EXCEPTION_FILES}
      ${HELPERS_FILES}
      ${VIDEOWRITER_FILES}
      ${SRCS}
      ${HDRS}
      )
  ENDIF()
  
  ########################################################################
  # Add preprocessor defines
  IF (D_ENABLE_LIBRARY_CUDA)
      CMAKE_MINIMUM_REQUIRED(VERSION 2.8.11 FATAL_ERROR)
      FIND_PACKAGE(CUDA REQUIRED)
      INCLUDE_DIRECTORIES(
          ${CUDA_INCLUDE_DIRS}
      )
      set(CUDA_ENABLED ON)
      add_definitions(-DCUDA_ENABLED=1)
  ENDIF (D_ENABLE_LIBRARY_CUDA)
  IF (D_ENABLE_LIBRARY_OpenCV)
      add_definitions(-DOPENCV_ENABLED=1)
  ENDIF (D_ENABLE_LIBRARY_OpenCV)
  IF (D_ENABLE_LIBRARY_Glut)
      add_definitions(-DGLUT_ENABLED=1)
  ENDIF (D_ENABLE_LIBRARY_Glut)
  
  ########################################################################
  # Include Directories   
  TARGET_LINK_LIBRARIES(Native_ePerceptor_Lib
      ${CUDA_LIBRARIES})
  
  TARGET_LINK_LIBRARIES(Native_ePerceptor_Lib
      ${OpenCV_LIBRARIES})
  
  TARGET_LINK_LIBRARIES(Native_ePerceptor_Lib
      ${Tobii_LIBRARIES})
  
  TARGET_LINK_LIBRARIES(Native_ePerceptor_Lib
      ${Glut_LIBRARIES})
  </code></pre>