gcc链接不同的g ++

时间:2012-10-14 05:29:00

标签: gcc g++ dynamic-linking

我将C ++代码转换为C,现在我也在尝试更改Makefile。我有这个:

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

据我所知,我可以将g ++更改为gcc,它应该可以正常工作,但事实并非如此。看起来gcc找不到我在cuda_md5.c中调用的cuda_md5_cpu.c中的函数(PS:我不在cuda_md5.c中包含cuda_md5_cpu.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

有什么问题?我刚刚从g ++改为gcc。

1 个答案:

答案 0 :(得分:2)

我想说obj/release/cuda_md5_gpu.cu.o(你似乎没有重新编译)很可能是用C ++编译器编译的,因此它的符号名称已被名称修改修改过。

名称修改是C ++编译器使用的一种技术,允许不同的函数具有相同的名称但具有不同的参数类型(重载),并且C编译器不需要这样做,因为不允许重载。

换句话说,你可能会发现init_constants(int,float);可能只是被C编译器变成_init_constants,但是,如果你使用C ++编译器,你会得到像_init_constants_$$_IntFloat这样的东西。以便将其与init_constants(int,double)init_constants(void)区分开来。

因此,尝试将C编译的cuda_md5.c与C ++编译的obj/release/cuda_md5_gpu.cu.o链接在一起的链接器将无法将函数名称匹配在一起。

这通常是您在C ++代码中看到extern "C" { ... }的原因,它使用C规则将函数名称(和其他内容)导出到链接器,以允许将C和C ++代码链接在一起。