nvcc linking problem

Hi,

this is the continuation of the same problem i posted here before but found no solution.

The problem is , when i compile .cu files with nvcc it adds strange characters into the function name, and because of this i can not link it with another code i compile with mpicc. (it gives “undefined reference” error )

For example this simple function:

void gpu_init() {

	cudaSetDevice( cutGetMaxGflopsDeviceId() );

}

is compiled into :

0000000000011808 <_Z8gpu_initv>:

   11808:	   55					  push   %rbp

   11809:	   48 89 e5				mov	%rsp,%rbp

   1180c:	   e8 00 00 00 00		  callq  11811 <_Z8gpu_initv+0x9>

   11811:	   89 c7				   mov	%eax,%edi

   11813:	   e8 00 00 00 00		  callq  11818 <_Z8gpu_initv+0x10>

   11818:	   c9					  leaveq 

   11819:	   c3					  retq

when i link with another object file that uses this function i get:

main-master.c:(.text+0xa7f): undefined reference to `gpu_init'

my question is , how do i tell nvcc to compile the what that it doesn’t add the “_Z8” and “v” characters into the function name when it creates the object file? (declaring ‘extern’ doesn’t help, because nvcc changes the function name, while other compilers do not)

Thanks in advance

The “strange” characters are the product standard C++ function name mangling, and it isn’'t nvcc that is doing it, it is your host compiler, which is treating the host cost as C++. If you declared functions like this:

extern "C" void func();

the problem should go away, There should also be a nvcc switch to force it to treat host code in .cu files as C as default, but off the top of my head I can’t recall what it is, but I am sure the nvcc manual will reveal all. Either approach should fix your problem.

thanks. just “extern” wasn’t enough, but the “C” addition did the job

From http://www.faqs.org/docs/Linux-mini/C+±dlopen.html :

Warning

There are two different forms of the extern “C” declaration: extern “C” as used above, and extern “C” { … } with the declarations between the braces. The first (inline) form is a declaration with extern linkage and with C language linkage; the second only affects language linkage. The following two declarations are thus equivalent:

extern “C” int foo;

extern “C” void bar();

and

extern “C” {

 extern int foo;

 extern void bar();

}

As there is no difference between an extern and a non-extern function declaration, this is no problem as long as you are not declaring any variables. If you declare variables, keep in mind that

extern “C” int foo;

and

extern “C” {

int foo;

}

are not the same thing.

For further clarifications, refer to [ISO14882], 7.5, with special attention to paragraph 7, or to [STR2000], paragraph 9.2.4.