title: unresolved external symbol cuda_library::foo(int) in Visual Studio/CMake
body: <h2>Original question (title: .cu file is processed as a .cpp file in Visual Studio/CMake)</h2>
  <p>I am trying to add a static library with CUDA code to my C++ project. I have a top level <code>CMakeLists.txt</code> file, a static library that's added from there, and my CUDA-using library that's added from that library (both libraries have their own <code>CMakeLists.txt</code> file. In the root file I have used <code>enable_language(CUDA)</code>, in the 1st level library's <code>CMakeLists.txt</code> I have done this:</p>
  <pre><code>  add_subdirectory(cuda_library)
    set_target_properties(level_1_lib PROPERTIES POSITION_INDEPENDENT_CODE ON)
    set_target_properties(level_1_lib PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
    target_link_libraries(level_1_lib cuda_library)
  </code></pre>
  <p>and in the CUDA library's <code>CMakeLists.txt</code>:</p>
  <pre><code>add_library(cuda_library 
    cuda_library.cu cuda_library.h)
  
  target_include_directories(cuda_library
    INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
    )
  </code></pre>
  <p>A <code>.cpp</code> file in the level 1 library calls an &quot;interface function&quot; I declare in <code>cuda_library.h</code> that is implemented in <code>cuda_library.cu</code> and internally launches a CUDA <code>__global__</code> kernel this way:</p>
  <pre><code>namespace cuda_library {
      __global__
      void real_foo(int number, int *out) { 
          *out = number * 2; 
      }
  
      inline int foo(int number) { 
          int* x;
          
          cudaMallocManaged(&amp;x, sizeof(int));
          real_foo&lt;&lt;&lt;1,1&gt;&gt;&gt;(number, x); 
          cudaDeviceSynchronize();
          int y = *x;
          cudaFree(x);
          return y;
      } 
  }
  </code></pre>
  <p>When I build from Visual Studio (with the CMake extension enabled, and it uses <code>ninja</code> as a generator), though, the build does not like the <code>__global__</code> keyword, making me think that the <code>.cu</code> file is treated like a normal <code>.cpp</code> file and not compiled as CUDA code.</p>
  <p>What am I doing wrong?</p>
  <h2>Edit to better clarify the errors I get</h2>
  <p>If I hit Visual Studio's &quot;Build All&quot; (or run CMake with ninja from the Visual Studio command prompt, which normally can compile simple CUDA examples with <code>nvcc</code>, the errors are the same) and I'm not on the <code>cuda_library.cu</code> file, I only get errors that boil down to <code>unresolved external symbol cuda_library::foo(int)</code>, which from some research means that the function might be declared but not defined. This makes sense if the header is included but the <code>.cu</code> file is not correctly compiled.</p>
  <p>However, only if I make the <code>.cu</code> file active VS shows me the errors that are related to the CUDA code treated like C++ code, and they don't have the normal error logo (like the first error in this image), but the one you can see in the second and third one:</p>
  <p><a href="https://i.stack.imgur.com/Sa0kY.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Sa0kY.png" alt="Possible intellisense errors" /></a></p>
  <p>so could they simply be Intellisense errors that do not appear while building?</p>
  <p>In that case there might be another cause why the static library's implementation is not properly linked. To be more thorough about it, this is the header (<code>cuda_library.h</code>):</p>
  <pre><code>#ifndef _CUDA_LIBRARY_H_
  #define _CUDA_LIBRARY_H_
  
  namespace cuda_library {
      inline int foo(int number);
  }
  
  #endif
  </code></pre>
  <p>and I try to import and use it this way in the <code>.cpp</code> file where the <code>unresolved external symbol cuda_library::foo(int)</code> error occurs:</p>
  <pre><code>#include &quot;cuda_library/cuda_library.h&quot;
  
  printf(&quot;Result from the GPU: %d\n&quot;, cuda_library::foo(5));
  </code></pre>
  <p>Funnily enough I've also tried</p>
  <pre><code>#include &lt;cuda_library.h&gt;
  
  </code></pre>
  <p>and the result is the same, maybe because CMake includes it in what would be the include search path?</p>
  <p>The project has this structure:</p>
  <pre><code>root_dir\
    CMakeLists.txt
    libs\
      CMakeLists.txt
      level_1_lib\
        CMakeLists.txt
        file_using_cuda_lib.cpp
        cuda_library\
          CMakeLists.txt
          cuda_library.cu
          cuda_library.h
  
  </code></pre>
  <p>I really can't understand what's exactly going wrong, so any help is well accepted.</p>