tags:

views:

25

answers:

2

I am trying to compile a project by compiling object files and then linking them together, nothing fancy:

hello.o : hello.h hello.cu
    nvcc hello.cu -c -o hello.o
#...
main.o : $(objs)
    nvcc *.o -o exec

When I get to the link phase, just about every method is shown to be missing and undeclared, despite the fact that nm shows that each is in fact sitting within my object files, and their names are unmangled. What is going on here?

A: 

Your final make target looks bogus: shouldn't it say:

exec : $(objs)
    nvcc $(objs) -o $@

You may also need to add the CUDA libraries to the command-line (I think nvcc figures this out when you're compiling a .cu file directly, but maybe it doesn't if you just give it .o files). So, something more like this:

exec : $(objs)
    nvcc $(objs) -o $@ -lcuda -lcudart -lcublas

(Precisely which libraries you need depends on your code)

Edric
I've included that line as an example. What you posted is pretty much what I have in actuality. I also link against the CUDA libraries. My issue is with the linking phase itself.
Alex
Which symbols are the linker complaining about? cu* ones, or ones that should be coming from your code? Does it work to invoke the linker separately? By the time you've got object files, you shouldn't need to go through the nvcc compiler driver.
Edric
A: 

Ok, so my question's formulation was incorrect. In fact, the problem was that I was compiling C code like so:

hello.o : hello.h hello.cu
    nvcc hello.c -c -o hello.o
#...
main.o : $(objs)
    nvcc *.o -o exec

which caused nvcc to pass the .c files to gcc. When I grepped 'nm *.o' for the name of my method, I found that the object files emitted by gcc had unmangled names, while the .cu files, which were compiled by g++, expected mangled names.

My solution was to rename all the .c files in my project to .cu, although I think (but haven't tested) that leaving them as .c and calling g++ on them explicitly in the makefile should be enough.

Alex