Frederico Schardong
Frederico Schardong

Reputation: 2095

gcc linking differently of g++

I converted a C++ code to C and now I'm trying to change the Makefile as well. I had this:

g++ -fPIC -o bin/linux/release/gpu_md5 cuda_md5.c cuda_md5_cpu.c obj/release/cuda_md5_gpu.cu.o 
-L/usr/local/cuda/lib64 -L../../lib64 
-L../../common/lib64/linux -L/opt/cuda/NVIDIA_CUDA_SDK/lib64 -lcudart     
-L/usr/local/cuda/lib64 -L../../lib64 
-L../../common/lib64/linux -L/opt/cuda/NVIDIA_CUDA_SDK/lib64

As far as I know I could just change g++ to gcc and it should work well, but it is not. Looks like gcc can't find the functions from cuda_md5_cpu.c that I'm calling in cuda_md5.c (PS: I'm not including cuda_md5_cpu.c in cuda_md5.c):

/tmp/ccKdDJiq.o: In function `cuda_compute_md5s':
cuda_md5.c:(.text+0x201): undefined reference to `init_constants'
cuda_md5.c:(.text+0x2e2): undefined reference to `execute_kernel'
collect2: ld returned 1 exit status

What is wrong? I just changed from g++ to gcc.

Upvotes: 1

Views: 108

Answers (1)

paxdiablo
paxdiablo

Reputation: 881253

I would say there's a very good chance that obj/release/cuda_md5_gpu.cu.o (which you don't seem to be recompiling) has been compiled with a C++ compiler and therefore has symbol names which have been modified by name mangling.

Name mangling is a technique used by C++ compilers to allow different functions to have the same name but with different parameter types (overloading), and C compilers have no need to do this since there is no overloading allowed.

In other words, you may find that init_constants(int,float); may simply be morphed by a C compiler into _init_constants but, if you use a C++ compiler, you'll get something like _init_constants_$$_IntFloat so as to distinguish it from init_constants(int,double) or init_constants(void).

So a linker that tries to link together a C-compiled cuda_md5.c with a C++-compiled obj/release/cuda_md5_gpu.cu.o will not be able to match the function names together.

That's often why you see extern "C" { ... } in C++ code, it uses the C rules to export function names (and other things) to the linker to allow linking of C and C++ code together.

Upvotes: 2

Related Questions