g++ compilation using 'include' statement with non-relative paths (C++) - 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

Related

Error compiling C++ source utilizing the Boost.Math library

I'm trying to use a couple of functions from the Boost Math library in some C++ code using the G++ compiler but I've been unsuccessful. This is on macOS.
I downloaded and extracted the Boost tar.gz from here and placed it into my source folder.
Within my C++ I've tried
#include "boost_1_63_0/boost/math/distributions/chi_squared.hpp" and
#include <boost_1_63_0/boost/math/distributions/chi_squared.hpp>.
The quotation version partially works but the chi_squared.hpp file includes fwd.hpp using the bracket (#include <...>) notation and that breaks my compilation with error In file included from main.cpp:9: ./boost_1_63_0/boost/math/distributions/chi_squared.hpp:12:10: fatal error: 'boost/math/distributions/fwd.hpp' file not found #include <boost/math/distributions/fwd.hpp>.
To compile I've used an assortment of commands, all unsuccessfully:
g++ -L /boost_1_63_0/boost/math/distributions main.cpp
g++ -I"/boost_1_63_0/boost/math/" main.cpp
g++ -I "/boost_1_63_0/boost/math/" main.cpp
g++ main.cpp -lboost_math
What is the correct include statement and G++ command that I need to use?
Resolved using
#include "/Users/[me]/[project_dir]/boost_1_63_0/boost/math/distributions/chi_squared.hpp"
and
g++ -I/Users/[me]/[project_dir]/boost_1_63_0/ main.cpp

Including isolated Qt objects in .cpp file

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++.

Confusion between including header files and source files in main program

I have heard that we should write the declarations in a header file and the definition in a source file, with both the source and the header having the same name. And then just include the header in the source.
Here is an example myFile.h:
void printer (void);
Here is the implementation of printer in myFile.cpp:
#include "myFile.h"
#include <iostream>
using namespace std;
void printer ()
{
cout<< "I am a printer";
}
Here is my main.cpp:
#include "myFile.h"
int main ()
{
printer();
return 0;
}
Now when I run the program, I get the expected error: undefined reference to printer. But when I see code on github or other projects I see that usually they have included the header file and not the source file. I also tried using the header guards ifndef but still the same error came.
The main program is successfully compiled if:
If i include myFIle.cpp in myFile.h
If i include just myFile.cpp in main
What I the general practice while doing the same?
You should include your myFile.cpp in the linking process:
g++ myFile.cpp main.cpp
The error message undefined reference to printer is actual a linker error, not a compiler error.
Explanation
If you use only g++ main.cpp compiler won't create code from myFile.cpp. He knows that there should be a function with the signature void printer(void), but he doesn't now yet where this function is. He completely ignores this fact, since you can provide pre-compiled object files ("myFile.o") and link those later:
g++ myFile.cpp -c # compile myFile.cpp
g++ main.cpp -c # compile myFile.cpp
g++ myFile.o main.o # link both files together.
-c will tell g++ only to compile the files, but not link them together to an executable. This is done by a linker (g++ will probably call ld in your configuration). The linker will create an executable which contains all needed libraries like libc++ and actual code.
IDE remarks
If you use an IDE make sure that all needed files are included in the project. This includes all header and source files and linkage options for additional libraries.
When yourself define a header file and want to include it, you should enclose it "", such as :
#include "myFile.h"
#include "myFile.h" // would be better.
It seems you forgot the " surrounding the include.
You should use
#include "myFile.h"
or
#include <myFile.h>
the later is rather for system libraries. Both forms differ in the way the search the file.
You find more details on
http://msdn.microsoft.com/en-us/library/36k2cdd4%28v=vs.71%29.aspx

Adding an include path to the parent directory in GCC

I'm wanting to include files from the parent directory in a project I am working on. All of the header files are in the parent directory, is there any way of using -I on the commandline to search for includes in the parent directory without using an absolute path?
I know I can solve these issues using a makefile and I will probably end up doing this, but I'd like to know if there is a quick commandline trick I can use as this situation pops up a lot when I am making quick prototype code.
Currently I am trying to compile using:
g++ -Wall -I../ simple.cpp
but this seems to not work properly. Will I also need to change the includes in simple.cpp from #include include_file.hpp to #include ../include_file.hpp ?
Hmm...
g++ -Wall -I.. simple.cpp
and
// Somewhere in simple.cpp
#include <include_file.hpp>
should work.

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.