【问题标题】:NVCC linking error in C and CUDA-C codeC 和 CUDA-C 代码中的 NVCC 链接错误
【发布时间】:2013-06-12 23:18:07
【问题描述】:

我正在研究 DNA 片段组装程序。纯 CPU 版本是使用 GCC 用 C 语言构建的,我正在尝试使用 NVCC 构建 GPU 版本。

这是生成文件

all : clean FragmentAssembly.exe

FragmentAssembly.exe : Common.o Fragment.o ILS.o Consensus.o main.o
    nvcc -pg -o FragmentAssembly.exe Common.o Fragment.o ILS.o Consensus.o main.o 

Common.o : Common.cu
    nvcc -pg -o Common.o -c Common.cu

Fragment.o : Fragment.cu
    nvcc -pg -o Fragment.o -c Fragment.cu

ILS.o : ILS.cu
    nvcc -pg -o ILS.o -c ILS.cu

Consensus.o : Consensus.cu
    nvcc -pg -o Consensus.o -c Consensus.cu

main.o : main.cu
    nvcc -pg -o main.o -c main.cu

clean : 
    rm -f *.exe *.o

正如所见,原来的 .c 文件变成了 .cu 文件,供 nvcc 正确编译。 除了main.cu之外,所有的cu文件都包含它们对应的文件(Common.h for Common.cu等)。

ILS.h 包含全局变量p_instanceFragmentsp_instanceLength 的定义

问题是在编译 NVCC 时,由于未知原因,我收到以下错误:

Consensus.o:(.bss+0x0): multiple definition of `p_instanceFragments'
ILS.o:(.bss+0x0): first defined here
Consensus.o:(.bss+0x8): multiple definition of `p_instanceLength'
ILS.o:(.bss+0x8): first defined here

没有真正的多重定义,因为使用 GCC 正确构建了相同的代码。看起来ILS.h 被两次包含在 nvcc 中,分别是 ILS.cuConsensus.cu。这也是不可能的,因为我已经用 #ifndef .. #define .. #endif 语句包装了我的所有头文件,以避免多次包含和无限包含循环。

也许与 makefile 命令有关?还是我应该使用 gcc 进行链接?能告诉我怎么处理吗?

问候,

【问题讨论】:

  • 没有任何代码(尤其是头文件中 p_instanceFragments 的定义),或多或少都无法判断出什么问题……只是提示:有没有可能在ILS.h你用过int p_instanceFragments;之类的东西吗? (当然你可能有一个更复杂的类型,而不是int)。这实际上是一个链接器问题。我猜您需要在ILS.h 中使用extern int p_instanceFragments;,然后在Consensus.cu 中使用ILS.cu,您需要声明int p_InstanceFragments;。当然,所有这些都是完全没有代码的猜测工作......
  • 解决了这个问题,谢谢:)

标签: c hyperlink makefile nvcc multiple-definition-error


【解决方案1】:

经过讨论:这里描述发生了什么:

如果您使用 gcc 并且您有两个文件(比如说 f1.cf2.c),并且在这两个文件中声明:

int myGlobalVariable;

然后会发生以下情况:

  • f1.c编译成f1.o时,目标文件将为myGlobalVariable预留空间。
  • f2.c编译成f2.o时,目标文件也会为myGlobalVariable预留空间。
  • 当您将两个目标文件链接在一起时,链接器将检测到有两个名为 myGlobalVariable 的变量并将这些变量合并在一起。

现在看来nvcc 编译器/链接器能够合并这些变量。

问题是,文件ILS.h 声明了<some type> p_instanceFragments;。因为ILS.h 包含在ILS.cuConsensus.cu 中,所以你会得到这个变量两次,nvcc 在它必须链接应用程序时会抱怨。

解决方案是在ILS.h 中声明extern <some type> p_instanceFragments;,然后在ILS.cu Consensus.cu 中定义<some type> p_instanceFragments;(不能同时在两者中)。

What are extern variables in C 的问题有一个相当广泛的答案,详细解释了所有这些。

【讨论】:

  • 谢谢。最适合初学者详细介绍
猜你喜欢
  • 2012-08-30
  • 1970-01-01
  • 2018-12-18
  • 1970-01-01
  • 2014-07-18
  • 1970-01-01
  • 2012-08-13
  • 1970-01-01
  • 2016-03-20
相关资源
最近更新 更多