NVCC linking issue

So the project I’m working on has gone from a small bunch of experiments into a major piece of code. I need to have a better way to build it than have a single file where I #include everything, so I’ve decided to split the code into .c files and figure out a compilation path I can take, the better to write a makefile.

However, I am getting odd linking issues with non-kernel code. When I compile a file using nvcc, the output of nm is as such, for two object files :

U _cudaFree

		 U _cudaMallocPitch

		 U _free

		 U _malloc

0000007e T _matrix_int_free

00000000 T _matrix_int_init

00000136 T _matrix_int_offline_free

000000af T _matrix_int_offline_init
U _cudaGetDeviceProperties

		 U _cudaMemcpy

		 U _matrix_int_offline_free

		 U _matrix_int_offline_init

00000000 T _matrix_int_print

0000019b T _matrix_int_swapoff

00000220 T _matrix_int_swapon

		 U _printf

		 U _putchar

000002a5 T _report_cuda_properties

		 U _sprintf

However, when I try to go and link the code, I get the following linker errors:

$ nvcc common.o transpose.o matrix_init.o test.o -L/usr/local/cuda/lib -lcudart

Undefined symbols:

  "matrix_int_init(__matrix_int*, int, int)", referenced from:

	  _main in test.o

  "matrix_int_print(__matrix_int, __sFILE*)", referenced from:

	  _main in test.o

	  _main in test.o

ld: symbol(s) not found

collect2: ld returned 1 exit status

Clearly, the symbols are there, and they are even named as they should be, but the linker cannot see them. When I compile the code using nvcc for the kernels and gcc for the C code, I get the same errors. What gives?

Have you tried adding

–host-compilation C

to the nvcc command?

No luck. I still get the same errors.

are you using extern “C” in your CUDA source?

Well, all code that does not contain kernels has a filename .c, which I assume leads the compiler to treat it as a regular C file. I’ve tried this before, and it did not seem to help. It complained about a string after extern.

Probably it’s similar to what I’ve faced.

To let NVCC link the object files, they should be in .o extension (in Linux) and .obj extension (in Windows).

In Windows, NVCC and GCC cannot be mixed.

At the moment I’m working on Mac OS X, and I’m compiling all files with nvcc.

I don’t think you can put extern “C” into code with a .c extension, only .cpp or .cu. Is the function it is complaining about a host function in a .c file, and you are calling it from a host function in a .cu file? If so, then I think you need to declare the .c function in the .cu with the extern “C” in there. I had a problem like that before, but there was a previous post on here with instructions that I followed (something like what I said above) and after playing with it for a while it solved it.