linking problem undefined reference to

Hi,

when i link my cuda program i get this error:

master waver # nvcc -I"/usr/local/cuda/common/inc" -L"/usr/local/cuda/common/lib" "-lrt -lcutil" -o neat-main neat-main.o nets.o

neat-main.o: In function `main':

tmpxft_000014b5_00000000-11_neat-main.ii:(.text+0xeba3): undefined reference to `generate_nets(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int)'

collect2: ld returned 1 exit status

i have a separate .c file where i defined a function, generate_nets , and a .cu file where i defined my main() which calls generate_nets() function before launching a kernel on the GPU

they compile ok independently:

master waver # nvcc -I"/usr/local/cuda/common/inc" -L"/usr/local/cuda/common/lib" "-lrt -lcutil" -c nets.c

master waver # nvcc -I"/usr/local/cuda/common/inc" -L"/usr/local/cuda/common/lib" "-lrt -lcutil" -c neat-main.cu

master waver #

the symbol table shows this:

master waver # objdump -t nets.o |grep generate_nets

0000000000000446 g	 F .text  000000000000037e generate_nets

master waver # objdump -t neat-main.o |grep generate_nets

0000000000000000		 *UND*  0000000000000000 _Z13generate_netsjjjjj

master waver #

it is just the neat-main.o prefixed '_Z13" to the function name, that’s why i guess it is not linking, right? How can I tell nvcc to do not generate prefixes and suffixes to the function names so they could link together fine?

Thanks in advance

define your function as extern “C”.

tried it, but nope,

master waver # rm nets.o

master waver # rm neat-main.o

master waver # grep -A1 generate_nets nets* nets.c:extern net_group *generate_nets(uint max_nets,uint max_nodes,uint max_links,

nets.c-			uint max_nodes_per_net, uint max_links_per_node) {

--

nets.h:extern net_group *generate_nets(uint max_nets,uint max_nodes,uint max_links,

nets.h-				   uint max_nodes_per_net, uint max_links_per_node);

master waver # grep -A1 generate_nets neat-main.*

neat-main.cu:	ng=generate_nets(5,40,80,15,15);

neat-main.cu-

master waver # nvcc -I"/usr/local/cuda/common/inc" -L"/usr/local/cuda/common/lib" "-lrt -lcutil" -c nets.c master waver # nvcc -I"/usr/local/cuda/common/inc" -L"/usr/local/cuda/common/lib" "-lrt -lcutil" -c neat-main.cu master waver # nvcc -I"/usr/local/cuda/common/inc" -L"/usr/local/cuda/common/lib" "-lrt -lcutil" -o neat-main neat-main.o nets.o

neat-main.o: In function `main':

tmpxft_00001630_00000000-11_neat-main.ii:(.text+0xeba3): undefined reference to `generate_nets(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int)'

collect2: ld returned 1 exit status

master waver # objdump -t neat-main.o |grep generate_nets 0000000000000000		 *UND*  0000000000000000 _Z13generate_netsjjjjj

master waver # objdump -t nets.o |grep generate_nets

0000000000000446 g	 F .text  000000000000037e generate_nets

master waver #

i think, the problem is with NVCC , because when i compile the file with .c extension, it links, but when i compile it as .cu extension, it doesn’t, check this:

master waver # rm test.o nets.o neat-main.o

rm: cannot remove `test.o': No such file or directory

rm: cannot remove `nets.o': No such file or directory

rm: cannot remove `neat-main.o': No such file or directory

master waver # cat test.c

#include <stdlib.h>

#include <sys/types.h>

#include <stdio.h>

#include "neat_types.h"

#include "nets.h"

int main() {

	generate_nets(1,1,1,1,1);

}

master waver # gcc -c test.c

master waver # gcc -c nets.c

master waver # gcc -o test-gcc test.o nets.o

master waver # rm test.o nets.o neat-main.o

rm: cannot remove `neat-main.o': No such file or directory

master waver # mv test.c test.cu

master waver # nvcc -c test.cu

master waver # nvcc -c nets.c

master waver # nvcc -o test-nvcc test.o nets.o

test.o: In function `main':

tmpxft_000017a8_00000000-11_test.ii:(.text+0xe330): undefined reference to `generate_nets(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int)'

collect2: ld returned 1 exit status

master waver #

master waver # objdump -t nets.o |grep generate

0000000000000446 g	 F .text  000000000000037e generate_nets

master waver # objdump -t test.o |grep generate

0000000000000000		 *UND*  0000000000000000 _Z13generate_netsjjjjj

master waver #

Hi, I know this is an old thread, but I have about the same problem this guy had. I’m trying to call functions in appcu.cu from app.c, not the other way around, but I’m getting the same kind of errors.

When compiling with the following, all in one step:

nvcc -O3 -DNDEBUG -D_REENTRANT -m64 -I. -I.. -o app ../main.c ../sieve.c ../clock.c ../util.c appcu.cu app.c -lm -lpthread

I get:

/tmp/tmpxft_00007384_00000000-16_app.o: In function `app_fini':

app.c:(.text+0x176): undefined reference to `cuda_finalize'

/tmp/tmpxft_00007384_00000000-16_app.o: In function `app_init':

app.c:(.text+0x108a): undefined reference to `cuda_app_init'

/tmp/tmpxft_00007384_00000000-16_app.o: In function `app_thread_fun':

app.c:(.text+0x1af6): undefined reference to `check_ns'

collect2: ld returned 1 exit status

both files #include “appcu.h”, which contains the following function definitions:

void cuda_app_init(void);

void check_ns(const uint64_t *P, const uint64_t *K, unsigned char *factor_found);

void cuda_finalize(void);

Any suggestions?

try adding

--host-compilation C

to your argument list for nvcc. The underlying problem is that nvcc invokes the host C++ compiler by default for compiling host code in .cu files, and that brings C++ style function name mangling into play. You either need to tell nvcc to use C rather than C++ on host code, or tell the C++ to use C function name semantics and argument behaviour.

Nope; that only adds the following before the other errors:

In file included from /tmp/tmpxft_00005aae_00000000-1_appcu.cudafe1.stub.c:6,

				 from appcu.cu:212:

/usr/local/cuda/bin/../include/crt/host_runtime.h:178: warning: ‘struct surfaceReference’ declared inside parameter list

/usr/local/cuda/bin/../include/crt/host_runtime.h:178: warning: its scope is only this definition or declaration, which is probably not what you want

The original errors appeared after those.

Any other ideas?

Those are only warnings, they can be safely ignored.

Run

objdump -t

on whichever of the compiled object files contains the code for the “missing” functions and see what they are named.

Even with --host-compilation C, which I agree may be correct, I get the following from appcu.o when I grep for the function names:

0000000000000400 g	 F .text  000000000000002c _Z13cuda_finalizev

0000000000000450 g	 F .text  00000000000002ed _Z13cuda_app_initv

0000000000000740 g	 F .text  0000000000000188 _Z8check_nsPKmS0_Ph

But app.o has their normal names:

0000000000000000		 *UND*  0000000000000000 cuda_finalize

0000000000000000		 *UND*  0000000000000000 cuda_app_init

0000000000000000		 *UND*  0000000000000000 check_ns

Again, very similar to the first poster.

Aha! I solved it!

Turns out extern “C” is the solution; but I hadn’t been doing it right. What I hadn’t considered was that while the C++ compiler needs extern “C”, the C compiler doesn’t recognize it and doesn’t appreciate it when it appears.

So I finally did what the websites said to do with extern “C” :"> , as I found on Wikipedia:

#ifdef __cplusplus 

extern "C" {

#endif

	/* ... */

#ifdef __cplusplus

}

#endif

And that worked. :)

avidday, thanks for the suggestions. I wonder why nvcc refused to compile the CUDA code as C?