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
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?
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:
/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:
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
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
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: