C++ multiple definition error when including external library - c++

I'm trying to write a simple application allowing the user to perform a series of symbolic manipulations on a set of linear equations and am using the "Symbolicc++" library (more specifically, the latest version 3.35) for this purpose.
Since I don't have much experience with C++ and have never actually used a third-party library before, it's quite possible that I simply don't know how to properly use a library and am making some stupid mistake.
The problem is that I get a lot of multiple definition errors when I try to compile (and link) any program consisting of more than one file that includes the library's main header; the errors refer to functions and classes that are defined in the library's files (not mine).
A very simplistic example: suppose we have the files main.cpp, head.h and head.cpp. The contents is as follows:
main.cpp
------------------
#include <iostream>
#include "head.h"
int main()
{
return 0;
}
head.h
------------------
#ifndef SOMETHING
#define SOMETHING
#include "symbolicc++.h"
#endif
head.cpp
------------------
#include "head.h"
//nothing
Of course, the files in the real program contain a lot more, but even with just this, trying to build the program with, e.g.:
g++ -I /path to library's header files/ main.cpp head.cpp
yields hundreds of error message along the likes of:
/tmp/ccYNzlEF.o: In function `Cloning::Cloning()':
head.cpp:(.text+0x0): multiple definition of `Cloning::Cloning()'
/tmp/ccNWUnnC.o:main.cpp:(.text+0x0): first defined here
where, e.g., Cloning::Cloning() is declared in cloning.h, which is one of the library's header files.
A program containing only a single file including symbolicc++.h works just fine.
I also tried building this project on Visual Studio 2012 and got a similar result.
Unfortunately, I wasn't able to find any information about this problem, as virtually all the materials I found concerned errors in header files created by the user (as opposed to libraries created by someone else), so any help would be appreciated.

This library seems seriously broken. The way it is designed, you cannot include "symbolicc++.h" multiple times without violating the one-definition rule.
For example, let's have a look at cloning.h. It defines a Cloning class with a default constructor declaration:
class Cloning
{
private: int refcount;
void (*free_p)(Cloning*);
// ...
public: Cloning();
// ...
};
Later on, within the header file, it also defines that constructor:
Cloning::Cloning() : refcount(0), free_p(0) {}
That's it. Every one of your *.cpp files which directly or indirectly includes cloning.h will be exposed to the definition of the same function. The linker notices the multiple definitions and gives up.
Try to modify cloning.h. Remove the constructor definition line above and place the constructor definition into the class definition, making it an inline function:
// just to see what's going on...
class Cloning
{
private: int refcount;
void (*free_p)(Cloning*);
// ...
public: Cloning() : refcount(0), free_p(0) {};
// ...
};
This will fix the error for Cloning::Cloning. But that's just to shed more light on the issue; I don't advise you to do this. It would be the library authors' job to fix their code.
Further recommended reading: Why include guards do not prevent multiple function definitions?
Here is a way for you to reproduce the same problem with a few lines of your own code:
head.h:
#ifndef SOMETHING
#define SOMETHING
struct Example
{
Example(); // constructor declaration
};
Example::Example() // constructor definition
{
}
#endif
head.cpp:
#include "head.h"
//nothing
main.cpp:
#include "head.h"
int main()
{
}
Example linker error (taken from Visual C++ 2013):
1>main.obj : error LNK2005: "public: __thiscall Example::Example(void)" (??0Example##QAE#XZ) already defined in head.obj
1>[...] fatal error LNK1169: one or more multiply defined symbols found
If you absolutely must use this library, you'll have to build your own safe wrapper around it. But frankly, just don't. I'm sure there are numerous other libraries that solve the same problems and that can actually be used according to C++ language rules and conventions.

Related

DLL library errors when using functions in multiple files

I am making libraries, to use in multiple games so I don't have to duplicate code. In this example, my main program is main.cpp and the other two files are my libraries. Everything is linked correctly.
When all my functions in Common Functions Library.h have static in front, I get the error: static function 'std::string common::joinAll(std::vector<std::string,std::allocator<_Ty>>)' declared but not defined (Error C2129) from main.cpp (even though the functions are in the Common Functions Library.h/.cpp), and it says the line number is one more than there is in the whole program which is very strange.
So, to fix this, I found people online saying I need to replace static with inline, so I tried again and got this error: cannot open file 'Common Functions Library.lib' (Error LNK1104)
Then I tried setting all the functions back to static, and then commented out #include "Cubes Library.h" in main.cpp, which didn't give me the other errors anymore, but instead things related to the cubes library (obviously). However, this stopped on line 65, after where the functions which caused the errors saying they weren't defined. I have no clue what is going wrong, but thanks for any help :)
Code:
main.cpp
#include "Common Functions Library.h"
#include "Cubes Library.h"
// Using functions from `Common Functions Library`
Common Functions Library.cpp (Part of a DLL)
#include "Common Functions Library.h"
namespace common
{
// Functions
}
Cubes Library.cpp (Part of a DLL)
#include "Cubes Library.h"
#include "Common Functions Library.h"
If you put inline in front of all functions and define in header, there is no need for .cpp file and hence no need for .lib.
I also see namespace common in your Common Functions Library.h. So don't forget to put using namespace common; in your main.cpp or prefix common:: before all usage of class in main.cpp.

Header only library inline not working

I am struggling with my library design. I want to create a library to be used in my future projects (header only for now...)
I have this file structure:
C:\Libs\MYLIB
- Tools.hpp
- Tools.cpp
The code looks like this:
Tools.hpp
#pragma once
class Tools
{
public:
Tools();
~Tools();
};
Tools.cpp
#include "Tools.hpp"
inline Tools::Tools()
{
}
inline Tools::~Tools()
{
}
And then there is is another project, in a totally different folder including this file:
#include <MYLIB/Tools.hpp>
int main()
{
Tools t;
return 0;
}
But I always get this error:
undefined reference to Tools::Tools()'
undefined reference toTools::~Tools()'
When I create a .hpp file only with inline implementation inside my class, like this:
#pragma once
class Tools
{
public:
Tools(){};
~Tools(){};
void DoSomething(){};
};
it works (so my include paths are correct), but I don't want to bloat my .hpp file (I want to use doxygen later on, and keep my declaration from implementation).
I know using inline can be ignored by the compiler, I guess this is what happens here?! So what is the best way to create a private header only library
My specs:
Win 10 with CodeLite
MinGW (g++)
Another question:
Should this line in Tools.cpp
#include "Tools.hpp"
better be like this:
#include <MYLIB/Tools.hpp>
You can use an ad-hoc static lib, which is convenient for libraries that are small and/or change often and thus don't provide much benefit compared to the overhead of versioning/compiling/distributing separately. The idea is that you separate headers/sources as normal, but you just #include the .cpp file in one translation unit. Be aware that this technique has its benefits, but also limits!

one or more multiply defined symbols found error - simple

I'm trying to deal with this problem for some time and I can't seem to find the solution. I'm getting error:
one or more multiply defined symbols found
I faced this error while dealing with something more complicated, but even simple examples like this one don't work for me. Here is my main.cpp:
#include "defs.cpp"
int main()
{
string a = "A";
printIt(a);
}
, and here is my defs.cpp:
#include "header.h"
void printIt(string a)
{
cout << a;
}
, and this is my header.h:
#include <string>
#include <iostream>
using namespace std;
void printIt(string a);
I guess this is something trivial, but please don't rage if you think this is duplicate, because I'm a beginner and I didn't understand more complicated examples. Some help would be appreciated.
When you see #include "defs.cpp" you need to get very suspicious: cpp files are not meant to be included; only header files are designed for that.
Instead of including a cpp file, write a header for it. It appears that you have a suitable header already - your header.h, which contains the forward declaration of printIt:
void printIt(string a);
Now replace #include defs.cpp with #include "header.h", and compile your code. This should fix the problem.
Compiling this depends on the system where you are trying it out. On UNIX-like systems, you would write
g++ defs.cpp main.cpp
./a.out
You should not #include a CPP file. Only include header files containing the function prototype definitions. If no such header file exists, put the function prototype in your program (for eg. in file where main is written).
In your case, you are including (directly/indirectly) the CPP file which is having the definition of the function. Since same definition is compiled through CPP files, compiler is putting them into .OBJ file (known as intermediate or object files). The linker finally attempts to combine these Object files, and says some function (symbol) is multiply defined.
In main.cpp you are including defs.cpp which includes a definition of printIt. So the translation unit corresponding to main.cpp defines printIt.
However, you are also compiling defs.cpp which defines printIt. defs.cpps corresponding translation unit thus defines printIt too.
Combining both into one program would lead to multiple (yet equivalent) definitions of this function which is forbidden by the ODR. Remove the #include directive and your program should link correctly.
This is because you are including:-
#include "defs.cpp"
and due to this there are multiple definitions of method printIt.
These are some basic rules:-
1) You must always include only header files in your source files. Even then you have to make sure header files are included only once because if it is included more than once then there could again be problem of multiple definition.To protect against that your header files should contain header gaurds.
2) C++ always adheres with single definition rule. However , you can have as many declaratons as possible as long as all declarations are consistent.

A C++ library used in multiple compilational units causes linker errors

I've been working on a larger project and stumbled onto a problem when refactoring it into multiple compilational units from its previous state of having only one.
Each one of the compilational units includes a custom library that it needs and they all compile normally, but when Xcode is trying to link then, the linker throws out a lot of duplicate symbol errors.
The library is composed of multiple files too, some of which require each other. Here's the example of how the library file is written.
File 1:
// lib.hpp
#ifndef LIB1_HPP_
#define LIB1_HPP_
namespace lib1
{
class Class1
{
void foo (int a);
}
}
#endif
File 2:
// lib.cpp
#include "lib.hpp"
lib1::Class1:foo (int a)
{
return ...;
}
The only files included are the .hpp files, .cpp files are compiled with -c and added to the project in Xcode.
The error mentioned is (changed function names to match the ones in this post):
duplicate symbol __ZN5lib13Class5_fooE in:
/Users/---/Library/Developer/Xcode/DerivedData/Project-haivawxacqnzswdyqtfrxlrqlakt/Build/Intermediates/Project.build/Debug/Project.build/Objects-normal/x86_64/file.o
The error appears multiple times as there are multiple functions in the library, but it's always the same thing.
You should add
#pragma once
or
#ifndef Class1_h
#define Class1_h
... your declarations ...
#endif
The issue was a problem with me incorrectly using extern. I've fixed it a while ago.

Strange Linking error

I'm working on a big c++ project and change code from other people. During this I got a linker error stating that reference VarA is multiple defined. I found the corresponding variable and it had been defined in a cpp file which had directly been included into the project. I tried to convert the source file in a header file and a source file, which doesn't work.
I then tried to move the variable declaration into new separate h/cpp only containing this variable, which looks then like:
h-file (aaa.h)
#ifndef AAA_H
#define AAA_H
#include "classAdefinition.h"
extern ClassA VarA;
#endif
cpp-file (aaa.cpp)
#include "aaa.h"
ClassA VarA;
If I now include aaa.h in the main file, the linker error adds the new created aaa.obj to the error message (e.g. VarA is also defined there) which is exactly what I expected. But when I remove the definition of VarA in the main file I get a linker error staying that VarA is not defined, which is really confusing.
Does anyone have a clue what might be the cause of this behavior?
I'm using VS2008, and the project is created with cmake. Might this cause the problem? E.g. could there be a configuration issue? We also use templates quite often, can this lead to the problem?
In order to remove the multiple defined error which occurs because of multiple cyclic calls I suggest the first and foremost thing that you should do is to edit your header files to include the following macro (whatever it might be in your case) give each file a unique name
#ifndef CAR_HPP
#define CAR_HPP
class Car
{
public:
....
protected:
....
};
#endif
I haven't found the error, but the problem is now avoided because most of the third-party code has been changed and the error does no longer occure.