title: CUDA build shared library
body: <p>I need to create a shared library for cuda. The compilation of the library works fine but when I try to use it in my program nvcc returns a linker or ptxas error.</p>
  
  <p>I reduced the problem to the following code. The library must replace different C functions (here: memset). 
  The library consists of three C++ files:</p>
  
  <h3>FileA.h</h3>
  
  <pre><code>#ifndef FILEA_H_
  #define FILEA_H_
  
  namespace A {
      __device__ 
      void* memset(void* _in, int _val, int _size);
  };
  #endif
  </code></pre>
  
  <h3>FileA.cpp</h3>
  
  <pre><code>#include "FileA.h"
  
  __device__ 
  void* A::memset(void* _in, int _val, int _size) {
      char* tmp = (char*)_in;
      for(int i = 0; i &lt; _size; i++) tmp[i] = _val;
      return _in;
  }
  </code></pre>
  
  <h3>TempClass.h</h3>
  
  <pre><code>#ifndef TEMPCLASS_H_
  #define TEMPCLASS_H_
  
  #include "FileA.h"
  
  namespace A {
      template &lt;typename T&gt;
      class TC {
      public:
          __device__ 
          TC() {
              data = new T[10];
          }
  
          __device__ 
          ~TC(){
              delete [] data;
          }
  
          __device__ 
          void clear(){
              A::memset(data, 0, 10*sizeof(T));
          }
  
          T* data;
      };
  };
  #endif
  </code></pre>
  
  <p>Using the following commands I create a shared library:</p>
  
  <pre><code>nvcc -Xcompiler -fPIC -x cu -rdc=true -c FileA.cpp -o FileA.o
  nvcc -Xcompiler -fPIC --shared -o libTestA.so FileA.o -lcudart
  </code></pre>
  
  <p>This library should be used in a main program:</p>
  
  <h3>main.cpp</h3>
  
  <pre><code>#include &lt;cuda.h&gt;
  #include &lt;TempClass.h&gt;
  #include &lt;iostream&gt;
  
  __device__
  int doSomthing() {
      A::TC&lt;int&gt;* tc = new A::TC&lt;int&gt;();
      tc-&gt;clear();
      for (int i = 0; i &lt; 5; i++) tc-&gt;data[i] = i;
  
      int sum = 0;
      for (int i = 0; i &lt; 5; i++)  sum += tc-&gt;data[i];
      delete tc;
      return sum;
  }
  
  __global__
  void kernel(int* _res) {
      _res[0] = doSomthing();
  }
  
  int main(int argc, char** argv) {
      int* devVar;
      int* hostVar;
      hostVar = new int[1];
      hostVar[0] = -1;
      cudaMalloc(&amp;devVar, sizeof(int));
      cudaMemcpy(devVar, hostVar, sizeof(int), cudaMemcpyHostToDevice);
  
      kernel&lt;&lt;&lt; 1, 1&gt;&gt;&gt; (devVar);
  
      cudaMemcpy(hostVar, devVar, sizeof(int), cudaMemcpyDeviceToHost);
  
      std::cout &lt;&lt; "kernel done. sum " &lt;&lt; *hostVar &lt;&lt; std::endl;
  
      return 0;
  }
  </code></pre>
  
  <p>If I try to compile the program with the commands:</p>
  
  <pre><code>nvcc -Xcompiler -fPIC -I. -L. -rdc=true -x cu -c main.cpp -o main.o 
  nvcc -Xcompiler -fPIC -I. -L. main.o -o main -lTestA
  </code></pre>
  
  <p>I receive the error message:</p>
  
  <pre><code>nvlink error   : Undefined reference to '_ZN1A6memsetEPvii' in 'main.o'
  </code></pre>
  
  <p>I receive the same error if I try to compile the file directly:</p>
  
  <pre><code>nvcc -Xcompiler -fPIC -I. -L. -rdc=true -x cu main.cpp -o main -lTestA
  </code></pre>
  
  <p>The command <code>nm libTestA.so</code> shows that the library contains the function symbol _ZN1A6memsetEPvii.</p>
  
  <p>When I remove the <code>-rdc=true</code> option while linking I receive a ptxas error:</p>
  
  <pre><code>ptxas fatal   : Unresolved extern function '_ZN1A6memsetEPvii'
  </code></pre>
  
  <p>In my case static linking is no option, I need a shared library. I've also tried to make memset an <em>extern "C"</em> function but this collides with the original C function. The code compiles correctly with g++. Do you have suggestions how to solve this problem.</p>