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"
Related
I have created C++ static library using object files (which has many sub directories). After creating static library created a C file and a wrapper file (header file which I have under C++ directories). Now I'm trying to compile the C file by linking the C++ static library it gives error for the header file
error : no such a file or directory.
When I use -I option (-I C++ header files location) compiled successfully and able to run. But I would like to use the static library without including header files location i.e only adding static library itself C program should compile successfully.
Below is the source:
Edit:
I have the below files under libbasic folder:
testdemo.h
#ifndef TESTDEMO_H
#define TESTDEMO_H
#include<iostream>
#include<string>
using namespace std;
class testdemo
{
public:
testdemo();
void CallingTestDemo();
};
#endif // TESTDEMO_H
testdemo.cpp
#include "testdemo.h"
testdemo::testdemo()
{
}
void testdemo::CallingTestDemo()
{
`cout <<" CallingTestDemo!!!!!!\n";
}
testbasic.h
#ifndef LIBBASIC_H
#define LIBBASIC_H
#ifdef __cplusplus
#include<iostream>
#include<testdemo.h>
using namespace std;
class Libbasic
{
public:
Libbasic();
void Display();
void DisplayName(char* name);
};
#endif
#ifdef __cplusplus
extern "C" {
void displayfromC();
void displayfromCName(char* name);
}
libbasic.cpp
#include "libbasic.h"
void displayfromC()
{
Libbasic llb;
llb.Display();
}
void displayfromCName(char* name)
{
Libbasic lb;
lb.DisplayName(name);
}
Libbasic::Libbasic()
{
}
void Libbasic::Display()
{
cout <<" C called C++ API \n";
testdemo td;
td.CallingTestDemo();
}
#endif
#endif // LIBBASIC_H
I compiled the above program and created library libbasic.a
Now Im creating C API file outside the libbasic folder to call the above functions used in C++
testApi.c
#include<stdio.h>
#include <libbasic.h>
int main()
{
displayfromC();
}
Now im trying to create output using the below
gcc -o testdemo testApi.c -L ./libbasic -lbasic
Which giving libbasic.h: no such a file or directory error.
The basic Idea is create a library and API functions which can be used in any machine. If I have multiple folders and header files in C++ code then need to include all the folders while creating C application which requires to export header files too. I dont want to expose all the source to other users.
Kindly let me what mistake im doing and also how to achieve this.
A header file is not a wrapper.
If you have functions in a library, whether static or dynamic, you must have their declarations (often called "prototypes") in your code.
That is how C and C++ work so header files are integral part of any library.
As for the location of header files, these languages give you three options:
Use <filename.h> for standard include header path.
This path depends on your OS and compiler, but as long as your header file is there, you will not need to specify the path explicitly in compilation command.
Use "filename.h" for files in your local source directory, i.e. same directory where your *.c or *.cpp files reside.
The compiler can look there automatically as well, but if the header is in a sub directory, you will need to specify the relative path in your include statement.
#include "mylib/myheader.h"
Add additional search path for header files using a parameter (such as -I for gcc).
Finally, similar rule applies to the library object file it self (*.a, *.lib).
You will need the -L parameter in addition to the -l parameter if your library is not in a standard library path known to the linker.
Note that you never specified which compiler you are using, so I am guessing based on parameter names it is from gcc family or similar.
A way to alter the search path and tell the compiler where to find your library files will differ based on compiler type, but the principle is the same.
I am writting a game, and at the same time building an engine for it and for other games I may make in the future. During testing on both the game logic and the engine (separately) run well. However when I try to link them together, I encountered some problem with the inclusion of header files.
To be specific, here is what I did:
The engine is built as Static Library (.lib), and depends on GLFW static library (glfw3.lib). It contains a Window.h file:
// Window.h
#pragma once
#include <glfw3.h> // include other library's header
#include <iostream>
//test if the linking success
void test() {
std::cout << "this is Window.h";
}
class Window
{
// Window class code (declaration, function prototype, etc...)
}
*Note that the location of GLFW library is separated from engine/game project location.
The game project is hosted under the same Solution with the engine project. In the game's Properties, I have add the engine as dependencies as well as engine's .lib and include location. Then I try the following:
// game's main file
#include <Window.h>
void main()
{
test(); // call the test function from Window.h
}
When building the game, I got an error says that it can not find such file called "glfw3.h". However, if I comment out the inclusion of glfw3.h in Window.h file:
# Window.h
#pragma once
//#include <glfw3.h>
then the game build and run normally, and prints out the test line in test function.
I want to build the engine as a single .lib with header files that prototypes functions for its classes; so that in the game project I only need to include/depend the engine library and no need to care about GLFW or such. How can I achive that?
I found a similar question, but it seems the answers don't solve my question.
You could try the suggestion from the related post below. Basically build your library as you are doing then statically merge it with the glfw static lib.
How to merge two windows vc static library into one
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!
I am currently trying to get my head around library linking with Qt in order to split up some existing code into logically structured modular parts that can be called by different applications.
I keep getting a problem where no obj files are being created... so I have created a smaller sample project and replicated my problem below.
It seems, to me, the problem lies in the library ...so I will start there.
If I have code like this, the obj file is created (and can therefore be linked to by my test application):
mylib.h
#ifndef MYLIB_H
#define MYLIB_H
#include "mylib_global.h"
class MYLIB_EXPORT MyLib
{
public:
MyLib();
~MyLib();
private:
};
#endif // MYLIB_H
mylib.cpp
#include "mylib.h"
MyLib::MyLib()
{
}
MyLib::~MyLib()
{
}
But if I remove the cpp file and just have the header file with function bodys included (as is the structure of my actual codes library as the code consists ONLY of templates), nothing is created:
mylib.h
// .......
public:
MyLib(){}
~MyLib(){}
// .......
How can I get Qt to build my code please?
If your library is just a header file, you don't need to compile it, include your headers in your other projects, and they will be compiled into it.
I'm making a library that consists of multiple classes.
Here are the files used:
mylib.cpp
mylib_global.h //Qt requirement for shared lib
mylib.h //This is what i'd like to import
oneclass.cpp //The classes below provide the functionality
oneclass.h
twoclass.cpp
twoclass.h
I would like to achieve the following:
#include "mylib.h"
int main(int argc, char *argv[])
{
OneClass oneClass;
TwoClass twoClass;
}
So, i'm just importing the mylib.h in some other application header and because of it the OneClass and TwoClass are available there.
Can this be achieved?
Also, please comment if this is a conceptually wrong way to implement libraries, and if so, why?
Yes, that can be achieved.
Simply include all public definitions that your libraries provide into the libraries main header file.
In your example make mylib.h should look like as follows:
#include "oneclass.h"
#include "twoclass.h"