【发布时间】:2016-12-09 20:09:37
【问题描述】:
我正在尝试编译两个 .cpp 文件(foo.cpp 和 bar.cpp)并构建一个共享对象(project.so)。但是编译失败并且(部分)我得到的错误是:
....
duplicate symbol _n in:
foo.o
bar.o
ld: 5 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1(use -v to see
invocation)
make: *** [project.so] Error 1
ERROR: compilation failed for package ‘project’
我的 .cpp 文件有几个常用和不常用的头文件,几个常用和不常用的命名函数,以及一组常用命名的变量:
foo.cpp
#include <iostream>
#include <fstream>
#include <vector>
#include <ctime>
#include <cmath>
size_t m1;
double k1=2.0;
std::vector<double> x,y;
std::vector<double> z;
size_t n,p;
void inputfoo(){...}
void output(){...}
bar.cpp
#include <iostream>
#include <fstream>
#include <vector>
#include <ctime>
#include <cmath>
#include "Eigen/Dense"
#include "Eigen/Cholesky"
size_t m2;
double k2=2.0;
std::vector<double> x,y;
std::vector<double> z;
size_t n,p;
void inputbar(){...}
void output(){...}
我的尝试:
如果我在每个 .cpp 文件中使用不同的全局变量名称,我能够得到较少数量的“重复符号”错误。也就是说,如果我将 foo.cpp 中的 size_t m 更改为 size_t m1 并将 bar.cpp 中的 size_t m2 更改为,我不会在错误中得到这部分
duplicate symbol _m in:
foo.o
bar.o
所以,现在我可以看到错误中的 5 个符号代表 x、y、z、n、p(在每个 .cpp 文件中全局定义)
如果我对常用函数的名称有所不同,也是如此。以前,我也会在错误中得到这部分,
duplicate symbol __Z4inputP4init3RNGPi in:
foo.o
bar.o
这将我引导到 input(){...} 函数。
因此,我将其中一个常用函数 ( input (){..} ) 的名称更改为 inputfoo 和 inputbar,相应的错误就消失了。
现在,如果我让每个文件中的名称唯一,我相信我将能够成功编译这两个文件。但是,我无法更改 x、y、z、n、p,因为它们在这些文件中很多,而且我还有更多文件可以使用,这些文件具有通用的命名函数和变量。
谁能向我解释一下这里发生了什么以及如何解决它?我真的很想知道是什么原因造成的。我尝试阅读以前的帖子,“Understanding the origin of a linker duplicate symbol error”,但我不认为这是与标题相关的问题。
非常感谢。
【问题讨论】:
-
尝试添加命名空间?
-
@flu 您的意思是在 NS 文件中添加命名空间(或 NS )?我的理解是,在编译成功后添加了各个函数的 NS,这在此处不会发生。想知道是否可以通过其他方式添加 NS,或者我在这里遗漏了什么?
-
我的意思是在 foo.cpp 中添加这样的命名空间: namespace foo { size_t m; ... } 并在 bar.cpp 中:命名空间 bar { size_t m; ... }。抱歉,cmets 中的格式不太清晰。
-
这是一个完美的例子,说明了为什么全局变量是邪恶的。您在两个文件中将
n和p声明为全局变量。您只能定义一个全局变量。 -
@flu.. 谢谢。使函数和变量静态对我有用。尚未尝试命名空间,但会牢记这一点,并将了解它在我的项目中是如何工作的。我不知道这些概念。现在我更好地理解了这一点。所以谢谢你的帮助。
标签: c++ r compilation linker-errors