Including isolated Qt objects in .cpp file - c++

I want to use a library that utilizes the QT-class QVector2D to calaculate B-splines (library: https://github.com/ejmahler/SplineLibrary). But I can't figure out how to get the includes / linking right using a simple .cpp file and compiling with g++.
This is my attempt
// test.cpp
// My attempt at including the QVector2D class
#include </home/user/Qt/5.8/gcc_64/include/QtCore/qconfig.h>
#include </home/user/Qt/5.8/gcc_64/include/QtCore/qglobal.h>
#include </home/user/Qt/5.8/gcc_64/include/QtGui/qtguiglobal.h>
#include </home/user/Qt/5.8/gcc_64/include/QtGui/qvector2d.h>
// For spline library
#include <SplineLibrary/spline_library/spline.h>
#include <SplineLibrary/spline_library/vector.h>
#include <SplineLibrary/spline_library/splines/uniform_cr_spline.h>
int main()
{
std::vector<QVector2D> splinePoints{
QVector2D( 0, 1),
...
};
UniformCRSpline<QVector2D> mySpline(splinePoints);
QVector2D interpolatedPosition = mySpline.getPosition(0.5f);
}
Compiling with g++ 5
$ g++ -std=c++17 test.cpp -o test
gives
/home/user/Qt/5.8/gcc_64/include/QtCore/qglobal.h:63:28: fatal error:
QtCore/qconfig.h: No such file or directory compilation terminated.
I have verified that the file qconfig.h exists and that it is in the path as included.
I'm guessing my error is either in how I try to include the QT-headers, that I need to link it somehow.
How do I properly include a single Qt component (in this case QVector2D) and compile the project using g++?

First of all, you should never specify absolute paths in you includes. If someone else wants to use your code, they would need to modify all the files to point to the correct headers on their system. Apart from that you're using internal headers that you're not supposed to include yourself. At the very top of the Qt documentation for QVector2D you can find what header you're supposed to include to use the QVector2D class.
So test.cpp should look like this:
#include <QVector2D>
// For spline library
#include <SplineLibrary/spline_library/spline.h>
#include <SplineLibrary/spline_library/vector.h>
#include <SplineLibrary/spline_library/splines/uniform_cr_spline.h>
int main()
{
std::vector<QVector2D> splinePoints{
QVector2D( 0, 1),
...
};
UniformCRSpline<QVector2D> mySpline(splinePoints);
QVector2D interpolatedPosition = mySpline.getPosition(0.5f);
}
Compiler flags
Now, since you have a custom installation path for Qt5.8, the compiler can't find the header in the default search path, so when compiling this file you need to tell the compiler where to search for the Qt headers. As indicated by the line QT += Gui in the documentation I linked above, QVector2D is part of the QtGui sublibrary, so you need to include the headers in the directory /home/user/Qt/5.8/gcc_64/include/QtGui/. The compiler flag to do so is -isystem /home/user/Qt/5.8/gcc_64/include/QtGui.
However, the QtGui headers themselves depend on QtCore headers, but their path is given relative to the /home/user/Qt5.8/gcc_64/include directory, so in order for the compiler to find the header files the QtGui headers depend on you also need to add the compiler flag -isystem /home/user/Qt/5.8/gcc_64/include. Btw this is also the reason why you got the error QtCore/qconfig.h: No such file or directory compilation terminated., there is no such file QtCore/qconfig.h in the directory where test.cpp is located, nor is there one in the system include path, and you didn't give the compiler the additional path where to look for it.
So the compilation should be successful when executing g++ -std=c++14 -isystem /home/user/Qt/5.8/gcc_64/include -isystem /home/user/Qt/5.8/gcc_64/include/QtGui -fPIC -c test.cpp (assuming that the compiler previously didn't have any problem to find SplineLibrarys includes).
Linker flags
The previous command just compiles test.cpp (note the -c flag), but doesn't produce a binary that you can run. The linker has the same problem as the compiler - it doesn't know where to find the precompiled Qt libraries to link against unless you tell it where to look for them. The flag to do so is -L/home/user/Qt/5.8/gcc_64/lib.
In addition to telling the linker where to look for the precompiled libraries, you also need to tell it which ones you're using. As I've mentioned before, QVector2D is part of the QtGui sublibrary, so you need to add -lQt5Gui. Since QtGui depends on QtCore, -lQt5Core also needs to be added.
Assuming you used the default installer, your installation of Qt only includes dynamic libraries, so you also need to tell the linker to store the information where to find the library files in the created binary. The flag you need to add for this is -Wl,-rpath=/home/user/Qt/5.8/gcc_64/lib.
So putting everything together, the final command you need to run is g++ -std=c++14 -fPIC -isystem /home/user/Qt/5.8/gcc_64/include -isystem /home/user/Qt/5.8/gcc_64/include/QtGui -L /home/user/Qt/5.8/gcc_64/lib -Wl,-rpath=/home/user/Qt/5.8/gcc_64/lib test.cpp -lQt5Core -lQt5Gui.
If you use clang instead of gcc, the same command runs just fine if you replace g++ by clang++.

Related

What is a fast way to find the necessary libraries to link against when playing around with a library

What's a good way to find the necessary libraries needed to link against when making a toy executable to play around with another library?
I'll get the appropriate compile command from the compile_commands.json file (generated by CMake), but I still have to manually figure out which libraries I need the executable to link to.
For example: if I have a file called main.cpp:
#include <some_cool_library.hpp>
#include <iostream>
int main() {
some_cool_library::some_cool_type obj{"35"};
return 0;
}
I'll grab the appropriate compile command from the compile_commands.json file that was generated in the project that utilized some_cool_library.hpp (this is so I can pass the correct -I flag(s) to compiler without having to think at all).
Then I'll compile it (making the appropriate compile command modifications):
/usr/bin/clang++ -DBOOST_ALL_NO_LIB -DBOOST_ASIO_HAS_STD_CHRONO -DHAS_ZLIB -DWEBSOCKETPP_STRICT_MASKING -I<some-dir0> -I<some-dir1> -I<some-dir2> -isystem /usr/local/include -Wall -Wno-invalid-partial-specialization -O3 -DNDEBUG -pthread -std=gnu++17 -o prog /home/user/main.cpp && ./prog
Lastly I'll get some output that spits back a bunch of linker errors where I have to manually inspect each one and link the appropriate library. Is there a better way to find these libraries?
The standard way to learn how to use a library is to read that library's documentation.
In some cases, pkg-config can be used to get the necessary compiler and linker flags. This is not guaranteed to work, but there is a reasonable chance of it working if CMake seems to automagically handle the library as a dependency.

g++ compilation using 'include' statement with non-relative paths (C++)

I am trying to compile a c++ code with a third party library using g++ as a compiler.
My main.cpp needs to include the header file core.hpp while the core.hpp needs to include cvdef.h whereas cvdef.h need to include interface.h.
The paths for these three headers in the include statements are as follows:
#include "opencv2/core.hpp"
#include "opencv2/core/cvdef.h"
#include "opencv2/core/hal/interface.h"
See file structure in image below.
When I compile my main.cpp it finds the core.hpp. The core.hpp, however, cannot seems to find cvdef.h as it is looking within the 'core'-folder for the 'opencv2'-folder (which is a level below).
Without changing the paths in the include statement, how would I go about this?
My current compile statement using g++ under Windows is:
g++ main.cpp -o main
It seems that OpenCV2 wants to look for the header files in standard locations.
You can add to the list of standard locations by using the -I (upper-case i) option, specifying the path to add.
In your case you should be able to do it with
g++ main.cpp -o main -Iopencv2/core

SDL2_image not found

I am trying to compile the following code which has the headers:
#include <SDL2/SDL.h>
#include <SDL2_image/SDL_image.h>
However after running the following makefile:
g++ -std=c++11 src/main.cpp -lSDL2 -lSDL2_image
I get the following error:
fatal error: SDL2_image/SDL_image.h: No such file or directory
#include <SDL2_image/SDL_image.h>
Any suggestions? Not entirely sure about my installation of SDL_image. I am running this on Ubuntu.
This problem can be solved through installing libsdl2-image-dev package:
apt install libsdl2-image-dev
Run apt-file search SDL_image.h
The result will tell you the location of the include file.
For instance, /usr/include/SDL2/SDL_image.h was returned.
So, when you want to include SDL_image.h, write everything after the include/ in between < >.
Thus, includes should look like the following:
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
See the question's comments for the original discussion regarding this solution.
From SDL documentation, it says that add 'lSDL_image' to the end of the compile line.
cc -o myprogram mysource.o `sdl-config --libs` -lSDL_image
or
gcc -o myprogram mysource.c `sdl-config --libs` -lSDL_image
Here is the reference -> https://www.libsdl.org/projects/docs/SDL_image/SDL_image.html
Section 2.2 Compiling.
So for SDL2, you just need to change 'lSDL_image' to 'lSDL2_image'.
For Windows + SDL2-2.0.8 + SDL_image-2.0.4 + Codeblocks you've got the add both Runtime Binaries and Development Libraries to the compiler and linker. Or else, you'll get the error SDL2_image not found, even with having the dll in your program's directory, this occurs. Hopefully others find this helpful; I had to figure it out myself. Example: If your resources are separate, you'll be adding the two plus your standard SDL2 paths to your compiler and linker. Warning: SDL2_image.h has it's headers assuming that the headers are in the same folder as the SDL2 framework. If you get errors about the image header, include the sub-folder SDL2 from SDL framework in the path and then you should be including SDL2 in the program as: include <SDL.h> rather than include <SDL2/SDL.h>.

hypertable library linking problem

i have installed hypertable in /opt/hypertable/current/ and i run an example program from hypertable...
#include <Common/Compat.h>
#include <iostream>
#include <fstream>
#include <string>
#include <Common/System.h>
#include <Common/Error.h>
#include <Hypertable/Lib/Client.h>
#include <Hypertable/Lib/KeySpec.h>
using namespace Hypertable;
int main(int argc, char* argv[]) {
ClientPtr client_ptr;
TablePtr table_ptr;
TableMutatorPtr mutator_ptr;
KeySpec key;
const char* install_dir = "/opt/hypertable/current/";
client_ptr = new Client( System::locate_install_dir(install_dir) );
}
i got this error
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/testes.d" -MT"src/testes.d" -o"src/testes.o" "../src/testes.cpp"
../src/testes.cpp:1: fatal error: Common/Compat.h: No such file or directory
i used eclipse CDT for my development and i linked using project Properties->c/c++build->setting->Libraries->LibrarySetPath(-L) and i have inked the HyperCommon also in -l this i set it as /opt/hypertable/current/include/ can any one tell me y i am getting this error...
There are two different paths you need to set when building software: the include path and the library path. You seem to be confusing them.
The include path is the path to find all the .h files. If you have an include path problem, it will manifest at compile time (when building each individual .o file), which is what you are seeing. "Common/Compat.h: No such file or directory" means you are likely missing an include path.
The library path is the path to find the DLL/shared object files at link time. If you have a library path problem, it will manifest at link time (when creating the final executable from the .o files). You are not up to that stage of compilation.
So doing LibrarySetPath and setting -l or -L is a linker/library thing; you want to fix the include path.
Most likely, you want to add /opt/hypertable/current/include/ to the include path (in Eclipse). On the GCC command line, this will be done with -I /opt/hypertable/current/include/, NOT with -L.
you want to add /opt/hypertable/current/include/ThriftBroker/gen-cpp to the include path
你还得一起编译/opt/hypertable/current/include/ThriftBroker/gen-cpp下的cpp文件

Compilation failing - no #include - boost

I'm trying to compile a third-party library, but g++ is complaining about the following line:
typedef boost::shared_ptr<MessageConsumer> MessageConsumerPtr;
The strange thing is, there is no #include directive in the file - and it is clearly supposed to be this way; there are about 60 files with the same (or very similar) issues. Clearly if there was an #include directive referencing the relevant boost header this would compile cleanly.
My question is: how can I get g++ to somehow automagically find the relevant symbol (in all instances of this issue, it is a namespace that can't be found - usually std:: or boost::) by either automatically processing the relevant header (or some other mechanism).
Thanks.
Edit
My current g++ call looks like:
g++ -fPIC -O3 -DUSING_PCH -D_REENTRANT -I/usr/include/boost -I./ -c MessageInterpreter.cpp -o MessageInterpreter.o
You can use the -include command line option:
g++ -include boost/shared_ptr.hpp ...
From the man page:
-include file
Process file as if "#include "file"" appeared as the first line of
the primary source file. However, the first directory searched for
file is the preprocessor's working directory instead of the
directory containing the main source file. If not found there, it
is searched for in the remainder of the "#include "..."" search
chain as normal.
Create your own wrapper .h file that includes the boost .h and then the broken .h .
Or (very fragile) ensure that you precede every use of the broken .h with boost .h .
Perhaps the third-party library is designed in such a way that you should always include a certain "main" header file in order to get the dependencies right.
Otherwise, you can add #include <boost/shared_ptr.hpp> before including the third-party header file that is giving the error message.