Shared library creation?

Hi guys,

I have just learn how to create shared libraries in linux through the ‘Program Libraries HOWTO’.

For now, I’ve been messing around with CUDA’s template project to turn it into a shared library.

So far what I’ve done:

  1. Change main() in to cudamain().
  2. I managed to turn it into a static library (a.a) with 'nvcc -lib -I …/…/common/lib.
  3. Can’t get another program to compile with it. It errors: missing symbol ‘cudamain’ even though it recognises a.a.

However, what I really want to know is how do I make nvcc create a shared library. Thanks :mellow:

nvcc --help says that --shared will produce a shared library. I’ve never tried it as I use CMake + FindCUDA.cmake for compiling which handles all the internal compile commands needed to create the shared library.

You may need to declare cudamain as

extern "C" cudamain() { ... }

in your libs header file if the program you are linking your library to is C++.

If you are on a 64-bit Linux system, you may also need to pass the -fPIC option through to the host compiler:

       nvcc --ptxas-options=-v --compiler-options '-fPIC' -o --shared

Thanks guys. However, it still doesn’t answer my question on how do I generate the shared library. Is there anyone I can ask regarding this matter?

EDIT: Found this but have not tried it out.

Did you read my suggestion to use --shared? Did you read seibert’s post where a full command line was given?

To reiterate:

$ nvcc --shared -o --compiler-options '-fPIC' 

$ file ELF 64-bit LSB shared object, AMD x86-64, version 1 (SYSV), not stripped

$ ldd  => /opt/cuda/lib/ (0x00002ae61beda000) => /usr/lib64/ (0x00002ae61c117000) => /lib64/ (0x00002ae61c417000) => /lib64/ (0x00002ae61c69b000) => /lib64/ (0x00002ae61c8a9000) => /lib64/ (0x00002ae61cbfc000) => /lib64/ (0x00002ae61ce01000) => /lib64/ (0x00002ae61d01b000)

        /lib64/ (0x0000003a9ea00000)

If this is not what you are asking for, then please clarify what you mean by “how do I generate the shared library”

Hey guys, this is my attempt at it. Errorrreed. Thanks for the help.

hpr@hpr-xps:~/NVIDIA_CUDA_SDK/projects$ cp -rf template/ templatelib

hpr@hpr-xps:~/NVIDIA_CUDA_SDK/projects$ cd templatelib/

hpr@hpr-xps:~/NVIDIA_CUDA_SDK/projects/templatelib$ vim

----------- I changed main() to cudamain() 

hpr@hpr-xps:~/NVIDIA_CUDA_SDK/projects/templatelib$ nvcc --shared -o template_gold.cpp --compiler-options '-fPIC' -I ../../common/inc/ -I /usr/local/cuda/include/ error: identifier "CUT_BANK_CHECKER" is undefined

1 error detected in the compilation of "/tmp/tmpxft_00002803_00000000-15_template_kernel.cpp1.ii".


Since you are using CUT_BANK_CHECKER, you need to specify the include (-I) and library directories (-L) for CUT. The makefile sets these so you can open it as an example.

This is from Evan Lezar with final bits from me to make it work

Zaki: This is what I had to do to make it work.

The gcc command above would error out with

gcc -o main main.c -lname_of_shared_library

In file included from main.c:2:

…/cuda_functions.h:2: error: expected identifier or ‘(’ before string constant

make: *** [main] Error 1

What I had to do was to create another cuda_functions.h for gcc, say name it cuda_functions_wo_extern_C.h

with the contents

my_function ( int my_parameter );

I have a very similar issue, but the fix I see posted above doesn’t seem to work.

Here is the command I am using:

nvcc -Xcompiler ‘-fPIC’ --shared -v -o

However, when I use it, I get the following error:
error: relocation R_X86_64_32S against `a local symbol’ can not be used when making a shared object; recompile with -fPIC

The thread above says I need to create a .h file with a declaration of the external C function and include it in my .cu file. I have done this as follows:.

below is the code of myFile.h
extern “C” void launch_cudaCalculations(dim3 grid, dim3 block, int sbytes, float* g_data, float* g_odata, int imgw, int imgh, int tilew, int radius, float threshold, float highlight);

below is the code snippet from
#include “myFile.h”
extern “C” void launch_cudaCalculations(dim3 grid, dim3 block, int sbytes, float* in_dev_ptr, float* out_dev_ptr, int cols, int rows)
{ … do stuff … }

Now when I compile I get: error: more than one instance of overloaded function “launch_cudaCalculations” has “C” linkage

Any ideas?

Regarding the extern issue with gcc (zakim). I have since found that following definition in the .h file allows one to use a single file:

[codebox]// the following is needed to allow for the compilation with nvcc as well as gcc

#ifdef __cplusplus

#define CHECK_EXT extern "C"


#define CHECK_EXT 


CHECK_EXT void function_def ();[/codebox]

Thus, I have defined a macro, CHECK_EXT that is blank if a C compiler is used (as opposed to a C++ compiler). This macro is then prefixed to any function definitions.

As far as I can tell this is due to nvcc and gcc defaulting to either C or C++ compilation. If someone has a better explanations, it would be much appreciated.

@muffinman104: In order to compile with the -fPIC switch using nvcc , one needs to use the --compiler-options -fPIC -shared nvcc options.

For example, the following line is what I use to compile a shared library that is to be built using cublas:

nvcc --shared --compiler-options -fPIC -shared -o -L/usr/local/cuda/lib -lcublas

The shared library can then be linked to another C program as normal.

Please let me know if anything is unclear or you have more questions.


Thank You for your suggestion.
I have used your this following command to create .so file.
nvcc --shared --compiler-options -fPIC -shared -o -L/usr/local/cuda/lib -lcublas

replaced command -
/usr/local/cuda-7.0/bin/nvcc --shared -Xcompiler -fPIC -shared -o

While linking this file with c file i.e. main.c it showing error

gcc -o main main.c

/usr/bin/ld: cannot find
collect2: ld returned 1 exit status

Please let me know where i am getting wrong.

usually with the -l option you don’t pass the “lib” prefix and the “.so” suffix of libary names. It would be

-ladd or -lcuda_add


Thank You. I have resolved the issue.