2012-10-14 62 views
1

我將C++代碼轉換爲C,現在我試圖更改Makefile。我有這樣的:gcc鏈接不同的g ++

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。

回答

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++代碼鏈接在一起。

+0

我很確定我不再使用g ++,這裏是makefile http://pastebin.com/Abnh7Vm2 –

+0

@FredericoSchardong,我相信你不是。但問題是CUFILES沒有用makefile編譯,它們被添加到'OBJS'列表中,這意味着它們已經被編譯。如果它們是用C++編譯器編譯的(沒有'extern C'),你會遇到這個問題。 – paxdiablo

+0

他們正在344線上編譯。我錯了嗎? –