Duplicate Symbols in object files: - c++

I am trying to compile two .cpp files, (foo.cpp and bar.cpp) and build a shared object (project.so). But the compilation fails and (a part of) the error I am getting is:
....
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’
My .cpp files have few common and uncommon header files, a few commonly and uncommonly named functions, and a set of commonly named variables:
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(){...}
My attempt:
I am able to get lesser number of 'duplicate symbols' error if I differ the names of global variables in each .cpp files. That is, if I change the size_t m to size_t m1 in foo.cpp and size_t m2 in bar.cpp, i do not get this part in the error
duplicate symbol _m in:
foo.o
bar.o
So, now I can see that the 5 symbols in the errors are for x,y,z,n,p ( defined globally in each .cpp file)
Same goes if I differ the name of the commonly named functions. Previously, I would also get this part in the error,
duplicate symbol __Z4inputP4init3RNGPi in:
foo.o
bar.o
which directs me to the input(){...} function.
So, I changed the name of one of the commonly named function ( input (){..} ), to inputfoo and inputbar and the respective error went away.
Now, I am sure i will be able to compile these two successfully if i make the names unique in each file. However, I cant change the x,y,z,n,p because they are numerous in these files and I have many more files to work with which have common named functions and variables.
Can anyone please explain it to me what is happening here and how to fix it? I would really like to know what is causing this. I tried reading from previous posts, 'Understanding the origin of a linker duplicate symbol error ' but I don't think it is a header related problem.
Thank you so much.

The example is incomplete, which makes it hard to comment.
But let me make a guess: you have globals in both files and they are visible across both. That is a design error. You can either
make them local to each file if their state is not shared, use static for that
make them shared by declaring one file only and using extern in the other.
But the error you quote is different and we don't know anything about your input::init()...
Also, I also see nothing related to Rcpp here, so wht add the tag for it?

Related

simple C++ code linker error [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 5 years ago.
Im trying to run a very simple snippet of code. I've been getting a linker error. My code looks like this:
main.cpp -->
#include <iostream>
#include "Complex.h"
using namespace std;
int main()
{
Complex c1(1.0, 5.0); // this should create Complex object 1.0 + i5.0
return 0;
}
Complex.h -->
#include <iostream>
class Complex {
private:
double real;
double imaginary;
public:
Complex(double, double);
void setReal(double);
void setImaginary(double);
};
Complex.cpp -->
#include "Complex.h"
#include <cmath>
Complex::Complex(double x, double y) {
setReal(x);
setImaginary(y);
}
void Complex::setReal(double x) {
real = x;
}
void Complex::setImaginary(double x) {
imaginary = x;
}
The error I've been getting looks like this:
I have been trying to run my main for a while but I keep getting the linker error. I have no clue what's causing it. I would appreciate any suggestions.
Just do
g++ main-3.cpp complex.cpp
mind the filename main-3, this is inconsistent in your question.
You have to feed all cpp files you are using into the g++ commandline to tell g++ where the code for the functions defined in the header lies. Read up on .o files, static linking and understand what that means.
Here is a little guide I follow to understand file inclusion and other factors:
c++ compilation is moronically simple:
read .cpp file
replace every #include statement with the text of the specified file (just dump it in)
If the resulting text still has #include directives (now from the header files), goto step 2.
Compile the hughe messy blob into a ´.o´ object file, replace calls to functions with symbols and add to that file a table of known symbols and where they are defined.
if there are more .cpp files specified, start a new empty text blob. Goto step 1.
call the linker ´ld´ to link all object files together, replace symbols with the actual addresses.
Strictly speaking, above is a little bit of a lie nowadays and a lot is left out and no optimizations mentioned. But it is still a useful guide to the compiler's behaviour.
To use it to interpret your error:
Complex.h got dumped into your blob, via the #include in main.cpp , but Complex.cpp did not. g++ generated an internal temporary .o file for you that contained something along the lines of
PUT 1.0 on Stack
PUT 5.0 on Stack
JUMP Complex::Complex
... and ran the linker ´ld´ with that .o file.
ld Could not find the address of the symbol Complex::Complex,
it needs a memory address to jump to.
If you compile Complex.cpp as well, the resulting Complex.o will have a symbol table with, for example, this entry:
Complex::Complex = 0xaaff
The linker, given Complex.o can now replace the symbol in main.o with an address.
PUT 1.0 on Stack
PUT 5.0 on Stack
JUMP 0xaaff

c++ can't compile a file

I'm a beginner at c++ and I'm trying to write a program to find greatest common factor. In main i have:
#include <iostream>
#include <cstdlib>
#include "longgcd.cpp"
int main(int argc, char* argv[]){
long gcd(long m, long n);
long m,n,g;
m=atol(argv[1]);
n=atol(argv[2]);
g=gcd(m,n);
std::cout<<"gcd("<<m<<","<<n<<")="<<g<<std::endl;
return 0;
}
and then i put the subfunction into another file called longgcd.cpp
#include <iostream>
#include <cstdlib>
long gcd( long m, long n){
long r;
while(n !=0){
r=m%n;
m=n;
n=r;
}
return m;
}
somehow longgcd.cpp can't compile. i get an error:
/usr/lib/gcc/i486-linux-gnu/4.3.2/../../../../lib/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: ld returned 1 exit status
make: *** [longgcd] Error 1
somehow I have difficulty running this program and making it work, i can't see whats wrong with it. Thanks for any help or suggestions.
Can you show the line you used to compile? It sounds like you tried to compile longgcd.cpp independently as an executable, and since that file doesn't have main, the linker correctly complained that it couldn't find main.
The simplest solution is to compile both files together
g++ $FLAGS longgcd.cpp main.cpp
You should be compiling the source file that contains the main() function.
Note that #includeing cpp's is generally discouraged. You can put the declaration for gcd in a header file and include this file from both the implementation cpp containing the code for it and the main file that calls it. In this case you will need to specify both cpp files to the compiler command line because they're both needed to assemble the final program. Even with this complication this way is much better than including cpps.
One issue is that main should be in your .cpp file, and not your header.
Another is that you normally #include a header (.h or .hpp) into a .cpp file and not the other way around.
Also please get a decent C++ book to read.
Do not include longgcd.cpp. You should almost never include a .cpp (unless you really, really, know what is going down)
You should specify all the cpps to the compiler. E.g: g++ main.cpp longgcd.cpp
Also move the long gcd(long m, long n); line above your main function.

Trying to use functions in a header/cpp file

I have two files:
hello.h and hello.cpp
hello.h
#ifndef __HELLO_H__
#define __HELLO_H__
using namespace std;
void PrintMessage();
#endif
hello.cpp
#include <iostream>
#include "hello.h"
using namespace std;
void PrintMessage()
{
cout << "I want to be displayed!";
}
Now, I want to use PrintMessage() in a new .cpp file, but I keep getting an error message. This is what I'm doing:
printingmessage.cpp
#include <iostream>
#include "hello.h"
using namespace std;
int main()
{
PrintMessage();
return 0;
}
Am I just doing something blatantly wrong? I do have all of them in the same folder; I assume it has something to do with Dev-C++ (what I'm using to write/compile/run), but I can't figure it out. Anyone have any ideas?
I created a folder on my desktop, put all three files inside, and I tried to compile my printingmessage.cpp file exactly as it is. This is the error I'm getting:
[Linker error] Undefined reference to 'PrintMessage()'
i don't know dev C++ , but i would strongly advise if you do any serious coding to learn/move to the terminal and use make files, or a newer IDE such as visual studios.
heres a short script you can run save it as bash.sh
something like this
g++ hello.cpp -O2 -g -c
g++ hello.o printmessage.cpp -Wall -O2 -o print
then run it with ./print
I assume it has something to do with Dev-C++ (what I'm using to
write/compile/run), but I can't figure it out.
I guess so, too. Behind the scenes, the following things have to happen:
Both files get compiled. This creates a *.obj file for every *.cpp file, and uses the header.
The object files are linked against one another and possibly against required libraries.
Your problem lies in the “one another” part of the second step: the code compiles all right, but linking fails. The header file is irrelevant at that point. More precisely, the linker invocation for printingmessage.obj contains a reference to a function which isn't defined in that object file or any of the default libraries. Most likely the problem is due to the *.cpp files not being part of the same project. You need to create a multi-source-file project where you can link multiple object files. How you do that with Dev-C++ is probably somewhere in their manuals.

Linker error when using static members

I'm using Qt 4.7 and Cmake 2.8.3 with g++ 4.2.1 on Mac OS X.
I'm getting a bizarre linker error when using static or global variables in one of my files.
Here's the error:
ld: duplicate symbol ColorTrail::calculateColorUniformLocation in CMakeFiles/GLBall.dir/src/DesktopMain.cpp.o and CMakeFiles/GLBall.dir/src/ColorTrail.cpp.o
collect2: ld returned 1 exit status
calculateColorUniformLocation is a static member of class ColorTrail... but its not even used in DesktopMain.cpp at all!
Here's what I've tried:
Renaming the variable doesn't fix the problem.
Moving the variable out of the class and just making it a plain global variable also doesn't fix it
The file ColorTrail.h:
#ifndef COLORTRAIL
#define COLORTRAIL 9
#include "GlobalConstants.h"
#include <vector>
using namespace std;
class ColorTrail
{
private:
//note that this is NOT a Q_OBJECT
static GLint calculateColorUniformLocation;
//omitted for brevity
};
GLint ColorTrail::calculateColorUniformLocation;
#endif
DesktopMain.cpp uses class ColorTrail, but not statically and never references the variable.
Anyone have any idea what could be wrong/had a similar problem with Qt?
You need to define the static variable in cpp file and not in header file. If you define it in header file, every cpp file which includes this header will get its own copy hence linker complains about duplicate symbols.
Static data members must be explicitly defined in exactly one compilation unit
See this link: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12

Weird 'undefined reference' error

I have run into a peculiar error in a C++ project at work.
I have found a fix, but I am now really satisfied, as I would like to understand what actually causes the error.
When building this snippet of code:
#include <iostream>
#include "snmp/snmp/SW_SNMP_Values.hpp"
#include "snmp/agent/SW_Agent.hpp"
#include "snmp/agent/SW_Agent_PP.hpp"
int main()
{
//SW_Agent_PP agent;
return 0;
}
Notice that SW_Agent_PP is COMMENTED OUT!! When building this, I get a ton of undefined reference errors, for classes that are in use by the SW_Agent_PP object.
The FIX is to ACTUALLY CREATE THE OBJECT! so if I do this:
#include <iostream>
#include "snmp/snmp/SW_SNMP_Values.hpp"
#include "snmp/agent/SW_Agent.hpp"
#include "snmp/agent/SW_Agent_PP.hpp"
int main()
{
SW_Agent_PP agent;
return 0;
}
everything works fine and dandy.
How can I get linker errors for NOT using something? I would like to hear if anyone have run into similar experiences before, and if they found what caused it.
I am sorry, but I cannot release more code as it is company property.
Many thanks in advance!
Linkers are complicated and this behaviour is by no means unusual. Here's one possible explanation:
You are linking with a static library libfoo.a.
libfoo.a contains foo.o that contains SW_Agent_PP::SW_Agent_PP() and a bunch of other functions.
Another library libbar.a, listed after libfoo.a in the link line, uses a bunch of other functions from libfoo.a.
The linker processes static libraries in order and never goes back. Therefore the references in libbar.a can be only satisfied if corresponding object was pulled from libfoo.a by main().
The solution is to reorder the libraries in the link line.
There are other possible explanations. It's hard to tell without seeing actual code.