Header only library inline not working - c++

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!

Related

c++ Library with nested includes

So I'm trying to create my own library in C++ and use it in another project.
So far it works with example code, but I have to include other libraries in my own library. So the problem is, that when I include the header files off my library,
the include paths in the header files are messed up.
A simple solution would be to add the search directories, but I don't think,
thats how its supposed to be resolved.
Sample Code - Library header file:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
int test();
The source file:
#include "sample.h"
int test() { return 20; }
Now the project in which I want to include the sample
#include <sample.h>
int main() { int a = test(); }
The problem is, that the include copies the code from sample.h directly into the main.cpp and the search directories for the other includes from sample.h are no longer defined
A simple solution would be to add the search directories, but I don't think, thats how its supposed to be resolved.
This is certainly the easiest solution since it requires no modifications to the code, and is usually an acceptable thing to do - however obviously it means the project can call the functions from glew.h and glfw3.h
The only alternative is to ensure the headers are not included by the library header, but instead by the source.
IE:
Library Header:
int test();
Library Source:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "sample.h"
int test() { return 20; }
And the project's source file left unchanged.
This requires that the types defined in glew.h and glfw3.h are not part of the public interface exposed by your library.
Eg, if your library had a function like:
GLFWwindow* window = openWindow(...);
You would need to change it to:
Library header:
struct WindowHandle;
WindowHandle* openWindow(...);
Library source:
struct WindowHandle{
GLFWwindow* window;
};
WindowHandle* openWindow(...){
WindowHandle* result;
//... do stuff...
result->window = //whatever;
return result;
}
This approach requires changing the library code, but has the advantage that the users of the library can't directly call the things the library depends on (glew and glfw in this case). This is particularly beneficial if you want to support multiple platforms, you could have a source file for opening windows via glfw, and another using direct x. The library's public interface would not need to be changed to support both backends.
If you want to know more about this approach try searching for "Opaque data types"

How to choose from functions with the same name in C++

I have this simple code in C++
#include <something.h>
#include <something2.h>
int main()
{
my_function();
return 0;
}
function with name my_function is defined in something.h and also in something2.h How to choose whichone I want to use without editting included files?
One solution is to use
namespace something_one
{
#include <something.h>
}
namespace something_two
{
#include <something2.h>
}
This works well if all the code is in the headers.
Otherwise you have to resort to #defines, stub functions implemented in carefully crafted compilation units, or a robust conversation with the global namespace polluter.
Assuming that actual definition resides in something.cpp (or .c) and something2.cpp (or .c),
Link only one of something.o or something2.o at the time of creating main application executable, depending upon from which file you want function to get executed.
With linking the correct file, you do not need to change any source code.
you might have to declare them as extern "C" at the point declaration and definition if you are compiling it as c++ files with g++ or gcc -std=c++0x or gcc -std=c++11.

C++ multiple definition error when including external library

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.

Accessing functions from external files in class definition

I'm trying to access functions from another file for use inside my class definition:
// math.cpp
int Sum(int a, int b){
return (a + b);
}
// my_class.cpp
#include <math.cpp>
#include <my_class.h>
int ComputeSomething() {
...
return ::Sum(num1, num2);
}
Despite my best efforts, I can't get the compiler to spit out anything outside the likes of ::Sum has not been declared or Sum was not declared in this scope.
I'm trying to wrap my head around code organization in C++, any help appreciated.
It might be worth noting that I'm programming for Arduino.
To be able to access functions from a user-defined library, best divide that library into a .h (or .hpp) and a .cpp file. I understand you have actually done this, but tried various options – among them the inclusion of the .cpp file – for the sake of finding a solution.
Still, to ensure things work as expected, the declarations of functions and classes should go into the .h file, best protected by something like
#ifndef MY_H_FILE
#define MY_H_FILE
/* ..Declarations.. */
#endif
Then to include the .h file (I'll assume it's named my.h), either use
#include "my.h" // path relative to build directory
or
#include <my.h> // path relative to any of the include paths
The latter only works if my.h is found on an include path previously known to the compiler (e.g. what is specified using the -I command line option in GCC). The former works if the path to the .h file given is relative to the directory your are building from.
Finally, do not use a file name that can be confused with a system library (such as "math.h"), especially if you are using the <...> syntax, as the include path will definitely include the system library header files.
Have you followed the instructions given here?
User-created libraries as of version 0017 go in a subdirectory of your
default sketch directory. For example, on OSX, the new directory would
be ~/Documents/Arduino/libraries/. On Windows, it would be My
Documents\Arduino\libraries. To add your own library, create a new
directory in the libraries directory with the name of your library.
The folder should contain a C or C++ file with your code and a header
file with your function and variable declarations. It will then appear
in the Sketch | Import Library menu in the Arduino IDE.

C++ header-implementation-header-implementation dependency chain

I'm trying to create simple C++ incremental-build tool with dependency resolver.
I've been confused about one problem with cpp build process.
Imagine we have a library consists several files:
// h1.h
void H1();
// s1.cpp
#include "h1.h"
#include "h2.h"
void H1(){ H2(); }
// h2.h
void H2();
// s2.cpp
#include "h2.h"
#include "h3.h"
void H2(){ /*some implementation*/ }
void H3(){ /*some implementation*/ }
// h3.h
void H3();
When in client code including h1.h
// app1.cpp
#include "h1.h"
int main()
{
H1();
return 0;
}
there is implicit dependency of s2.cpp implementation:
our_src -> h3 -> s1 -> h2 -> s2. So we need to link with two obj files:
g++ -o app1 app1.o s1.o s2.o
In contrast when h3.h included
// app2.cpp
#include "h3.h"
int main()
{
H3();
return 0;
}
there is only one source dependency:
our_src -> h3 -> s2
So when we include h3.h we need only s2.cpp compiled (in spite of s1.cpp -> h2.h inclusion):
g++ -o app2 app2.o s2.o
This is very simple example of the problem, in real projects surely we may have several hundreds files and chains of inefficient includes may contain much more files.
So my question is: Is there a way or instruments to find out which header inclusion could be omitted when we check dependencies (without CPP parsing)?
I would appreciate for any responce.
In the case you stated to see the implicit dependence on s2.cpp you need to parse the implementation module s1.cpp because only there you will find that the s1 module is using s2. So to the question "can I solve this problem without parsing .cpp files" the answer is clearly a no.
By the way as far as the language is concerned there is no difference between what you can put in an header file or in an implementation file. The #include directive doesn't work at the C++ level, it's just a textual macro function without any understanding of the language.
Moreover even parsing "just" C++ declarations is a true nightmare (the difficult part of C++ syntax are the declarations, not the statements/expressions).
May be you can use the result of gccxml that parses C++ files and returns an XML data structure that can be inspected.
This is not an easy problem. Just a couple of many things that make this difficult:
What if one header file is implemented in N>1 source files? For example, suppose class Foo is defined in foo.h but implemented in foo_cotr_dotr.cpp, foo_this_function.cpp, and foo_that_function.cpp.
What if the same capability is implemented in multiple source files? For example, suppose Foo::bar() has implementations in foo_bar_linux.cpp, foo_bar_osx.cpp, foo_bar_sunos.cpp. The implemention to be used depends on the target platform.
One easy solution is to build a shared or dynamic library and link against that library. Let the toolchain resolve those dependencies. Problem #1 disappears entirely, and problem #2 does too if you have a smart enough makefile.
If you insist on bucking this easy solution you are going to need to do something to resolve those dependencies yourself. You can eliminate the above problems (not an exhaustive list) by a project rule one header file == one source file. I have seen such a rule, but not nearly as often as I've seen a project rule that says one function == one source file.
You may have a look at how I implemented Wand. It uses a directive to add dependencies for individual source files. The documentation is not fully completed yet, but there are examples of Wand directives in the source code of Gabi.
Examples
Thread class include file
Thread.h needs thread.o at link time
#ifdef __WAND__
dependency[thread.o]
target[name[thread.h] type[include]]
#endif
Thread class implementation on windows (thread-win32.cpp)
This file should only be compiled when Windows is the target platform
#ifdef __WAND__
target[name[thread.o] type[object] platform[;Windows]]
#endif
Thread class implementation on GNU/Linux (thread-linux.cpp)
This file should only be compiled when GNU/Linux is the target platform. On GNU/Linux, the external library pthread is needed when linking.
#ifdef __WAND__
target
[
name[thread.o] type[object] platform[;GNU/Linux]
dependency[pthread;external]
]
#endif
Pros and cons
Pros
Wand can be extended to work for other programming languages
Wand will save all necessary data needed to successfully link a new program by just giving the command wand
The project file does not need to mention any dependencies since these are stored in the source files
Cons
Wand requires extra directives in each source file
The tool is not yet widely used by library writers