C标头出现重复符号问题 [英] Duplicate symbol issue with C headers
问题描述
这是我第一次处理CUDA项目,该项目比简单的写入单个源文件和编译例程稍微复杂一些.不出所料,我在使用C标头时遇到了一些问题,即重复的符号.
This is my first time tackling a CUDA project that's slightly more complex than the simple write-single-source-file-and-compile routine. As expected, I'm facing some issues with C headers, namely duplicated symbols.
根据链接器,在多个.cu
文件中包含以下头文件会引起冲突:
According to the linker, conflicts arise over the inclusion of the following header file in multiple .cu
files:
env_vars.h
#ifndef ENV_VARS_H_
#define ENV_VARS_H_
/*** GLOBAL VARIABLES ***/
unsigned int h_n_osc;
__device__ unsigned int d_n_osc;
/*** CONSTANTS ***/
const double OMEGA_0 = 6.447421494058077e+09;
/* other constants defined in the middle */
#endif
multigpu.cu
#include "env_vars.h"
/* assigns h_n_osc */
adm_matrix.cu
#include "env_vars.h"
/* uses h_n_osc */
在Nsight Eclipse Edition中构建项目会导致链接器抱怨h_n_osc
变量被定义了两次:
Building the project in Nsight Eclipse Edition results in the linker complaining about the h_n_osc
variable being defined twice:
duplicate symbol _h_n_osc in:
./adm_matrix.o
./multigpu.o
ld: 1 duplicate symbol for architecture x86_64
通过Internet搜索,我已经意识到将h_n_osc
变量的声明移动到multigpu.cu
并将其重新声明为adm_matrix.cu
中的extern
变量(以及以后可能需要的任何地方)解决了问题,实际上做到了.
Searching through the Internet, I've realized that moving the declaration of the h_n_osc
variable to multigpu.cu
and re-declaring it as an extern
variable in adm_matrix.cu
(and wherever I might need it later) solves the problem, which in fact it does.
问题已解决,但我想对此进行更深入的研究:
Problem solved, but I'd like to take a deeper look into this:
- 为什么链接程序也不会抱怨
d_n_osc
变量?为什么常量(例如OMEGA_0
)同样不是问题? - 这是否意味着无法将全局变量放在头文件中?
- 让我最困惑的是,互联网上的许多消息来源都指出,仅当头文件包含变量的定义而其简单的 declaration 应该不构成问题.我很难相信这一点的原因是,即使我的标头只包含一个声明,我也要面对这个问题!我想念什么吗?
- Why doesn't the linker complain about the
d_n_osc
variable as well? And why are the constants (such asOMEGA_0
) equally not a problem? - Does this mean that it is not possible to place global variables in header files?
- What puzzles me most is that a number of sources over the Internet state that duplicated symbol errors should happen only when the header file contains a definition of the variable, while its simple declaration shouldn't constitute a problem. The reason I have a hard time believing this is that I'm facing the issue even though my header only contains a declaration! Am I missing something?
伙计们,感谢您的耐心等待!
Thanks in advance for your patience, folks!
推荐答案
头文件通常应仅包含 声明性代码. h_n_osc
应该在此处声明,而不是定义.
Header files should normally contain only declarative code. h_n_osc
should be declared here, not defined.
extern unsigned int h_n_osc;
在至少一个模块中,或者在一个新模块中,您将需要一个定义;例如:
In at least one of your modules, or a new one of its own you will need a definition; for example:
env_vars.cu
#include "env_vars.h"
unsigned int h_n_osc;
然后链接该链接.或者,您当然可以将 definition 放置在现有模块multigpu.cu或adm_matrix.cu中.
Then link that. Alternatively you could of course place the definition in one of the existing modules multigpu.cu or adm_matrix.cu.
我不确定此问题似乎可以解决该问题.
I am not sure of the semantics of the The CUDA __device__
extension, while it may link, it is not necessarily correct; you may end up with each module referencing a separate copy of the device variable; it may be necessary to qualify that with extern
as well. This question appears to deal with that issue.
这篇关于C标头出现重复符号问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!