Including headers in C++ - c++

In C++, does one need to copy any needed header files into the directory of the main C++ file?
Ex. I have OpenCV installed globally, and the Python bindings are working well. However, if I write:
#include "opencv2/highgui/highgui.hpp"
I receive a "not found" error. Do I need to copy these from their global install location to the project dir? I'm certain there must be a well-established set of practices for this, so I don't want to poke around in the dark on my own.

It depends on which operating system and build tool chain you are using, but as an example using linux, gcc and cmake, this article shows how to build with opencv.
http://docs.opencv.org/trunk/doc/tutorials/introduction/linux_gcc_cmake/linux_gcc_cmake.html
As you can see with the find_package directive, cmake is searching for the opencv include files.
Obviously, you can specify include path directly with g++ -I, but having cmake find it for you has the advantage that it will have a better chance of being found if you compile on a different system. It will also give you an error if it can't find the files.
Lastly, you should ensure that you have the "dev" files, as opposed to just the library. The dev files will have headers to include. While, the library will only have shared objects (*.so) and archives (*.a) that can be used for static or runtime linking.

If it is installed globally, you need to inform the compiler to look globally, i.e.,
#include <opencv2/highgui/highgui.hpp>

Related

Locating "undefined" references in a C/C++ Project

I am building a C++ project on my Ubuntu 64bit system using a provided Makefile, and this project also provides an API library for developers.
The compilation was successful, no errors at all, but when I try to include in my files the API libraries provided in the "api" folder, then g++ complains about undefined references.
It is not a problem about dependencies (I already built the project succesfully), in fact the missing references are about classes and functions provided by the project, but they are in some specific (sub-)folders (I don't know which ones!), I guess in some .so files, and g++ is not finding them, probably because it does not know they are in those specific subfolders.
It is not the first time this happens when trying to use APIs from any project, then I think I am missing something or I am doing something wrong in general when trying to use the libraries provided in a project.
In particular, the main problem is that I don't know how to tell the compiler where some classes or data structures are declared, and moreover I don't know how to locate them in order to know where they are.
Usually, a workaround I use to avoid this problem is to run make install (as root or using sudo) so that libraries and APIs are installed in standard folders (like /usr/include or /usr/lib) and if I do this thend I can include the API libraries using #include <library>, but in this last case it didn't work either, because perhaps some required files containing the not found classes/structures are not properly installed in the right folders in the system.
Another workaround I used sometimes is to try to put all the project files in the same folder instead of using the project folder structure, but clearly this is not good! :-)
But I noticed that several other people managed to use the APIs, then apparently they know some way of finding the files containing the "undefined" references and including them in the compilation.
Then my general question is: given a "classic" C++ project based on "Makefile" files and with usual folder names like src, lib, build, bin, etc., if I want to write C++ files using the libraries provided by the project, but the compiler complains about undefined references, how can I find the files (.so or .o or .cpp) containing such references? Is there any tool to find them? And how can I tell the compiler where they are? Should I use some command-line option for g++ or should I use the #include macro in some smart way?
PS I also tried to use the pkc-config linux tool to get right options to use for compilation and they were available, but the compiler still complains about the undefined references.
Some more degails about the project i tried:
For interested people a link to the project is below:
https://github.com/dreal/dreal3
And instructions on how to build it:
http://dreal.github.io/download/
Look into the -rpath linker option - specifically with the "$ORIGIN" argument. That lets you find libraries relative to your executable location so you don't have to install them to the standard locations but just need to put them somewhere known, relative to the executable. That should help you with one piece of the puzzle.
Note: -Wl, can be used to pass arguments to the linker via g++.
As for pointing the compiler/linker at a library so it can resolve undefined references by using that library, use the -l (that's lowercase L) option to specify the library name and -L to specify directories to search for libraries.
As for looking into a library (.so) file to see what symbols are in there, you have a few tools at your disposal: objdump, nm, readelf and objcopy.

Is it correct to manually copy header .hpp files into my project_root/boost library?

I was reading the documentation and found it quite vague:
To compile anything in Boost, you need a directory containing the boost/ subdirectory in your #include path.
Since all of Boost's header files have the .hpp extension, and live in
the boost/ subdirectory of the boost root, your Boost #include
directives will look like:
#include <boost/whatever.hpp>
or
#include "boost/whatever.hpp"
depending on your preference regarding the use of angle bracket
includes.
Am I supposed to always create a subdirectory named "boost" in my project root and then manually copy each .hpp file I need from my boost installation/header directory into the project_root/boost directory?
I could also see telling Eclipse to automatically scan my boost root installation/include directory for the headers, thus avoiding the manual copy. Also, I could see making a soft link to the boost root installation/include directory into the project boost folder so as to include everything without having to make a single manual copy.
One difference I see is including the boost header files in my projects versus not including them in my project and referring to them externally
I am not sure which of these strategies is right. Which is the best practice here?
The correct option for smallish development projects is probably the one you suggest here:
"I could also see telling Eclipse to automatically scan my boost root installation/include directory for the headers, thus avoiding the manual copy." (Specifically, adding your boost installation's include directory to your compiler/Eclipse search path.)
That is what the boost documentation means by having a directory containing boost/ in your #include path.
For small individual projects, you don't really want to be messing around creating hand-built links to boost includes for each project if your boost installation rarely changes, unless that's a part of your broader build strategy across projects. I've worked in organisations where this is done for good reasons, basically to enable you to set up different build instances pointing at different versions of boost (or other third party libraries) by just switching some symbolic links, rather than messing around with the make dependencies and paths.
So setting up sym links to boost's include, lib, etc. inside your project might be an option if you want that level of flexibility.
However, manually copying the boost header files into your project each time is not a good way to do it.
It's unusual,- and certainly not good practice-, to copy library headers to your projects, and it's not necessary at all.
Use the -I option to tell the compiler which additional pathes to search for include files.
Concerning Eclipse CDT, you can add the additional include pathes using the C++-Build Options of your project properties.
Referring to them externally.
Copying library files into application projects is nothing but copy-n-pasting code at a higher level. Don't do it. It typically leads to an extremely unstructured software architecture. You should even take the opposite direction: modularise your project's own code to create your own internal libraries, which your project then treats exactly like Boost libraries or the standard library. This is what your application project's files should look like:
#include <your_own_library/whatever.h>
#include <boost/whatever.hpp>
#include <string>
class ApplicationSpecificClass
{
// ...
};
Thinking in terms of libraries and APIs will improve your software-engineering skills significantly. It only requires that you learn more about your build environment and the options featured by your compiler and linker (both to create libraries and to use them). Learning how to use Boost libraries is a good start, because most of them are header-only libraries, which makes everything easier.

How to install third party libraries

I'm sorta new to C++ and I've decided to try and use odeint to do some simulations because python is too slow for my needs.
I found this package, which I want to play with. I'm just not totally sure how to install or where to place these libraries. Is there something for C++ similar to python's pip install?
Side note: I'm trying to do this using Eclipse Kepler, but I'm not married to that idea.
I recommend not putting the code into your own project - that is a rather quick and dirty solution. The correct way to use a library in C++ (in fact, in any programming language that I know) is to keep all libraries separate from your own projects, at a separate location on your filesystem.
You then tell your environment where to find the library files and tell your project to use them. It's always the same basic idea, whether you are using Makefiles or Visual Studio project files.
Look at the documentation of this library. It says:
odeint is a header-only library, no linking against pre-compiled code
is required
This means that the "library files" I just mentioned are just header files. That makes it much easier for you, because you don't have to deal with linker options. In C++, the location where additional (project-external) header files can be found is usually called the "include path".
Your new problem should therefore be: How to tell Eclipse Kepler my include path?
Entering this new problem into Google (as "eclipse kepler include path") yields a few interesting results. It will eventually lead you to the Eclipse documentation about include paths, where you can learn how to edit the C++ include path.
Now that everything is set up, you can finally use the library's header files in your projects via lines like the following:
#include <boost/numeric/odeint.hpp>
Do you notice the < >? They make a big difference, because they are the C++ way of saying "this is not part of my project, please get it from my include path". Just like headers which are part of the language (e.g. <vector> or <iostream>).
All of this may appear troublesome at first, and perhaps you even gain little from it at the beginning, but in the long run, for many different projects and many different libraries, it's the only way to prevent chaos.
Since odeint is a header only library you can place it with your own source code. Simply copy odeint's boost directory where your main.cpp is (assuming you have a main.cpp, but you should get the idea):
your_sources/
main.cpp
boost/
numeric/
odeint/
odeint.hpp
Now you can use the library by including
#include "boost/numeric/odeint.hpp"

Boost C++ libraries installation

I have just downloaded the boost libraries from the boost website and extracted them to my desktop. I was hoping to just have a quick look at them and have them installed on my machine and perhaps use them in the future when I am more accustomed to C++.
When I extracted it, I was confused with all of the extracted files. There is all of the headers in the boost directory but tutorials mention running bootstrap.bat (I'm using Windows).
So I am asking this: do I simply extract the headers to my compilers include directory like normal to get boost up and running or do I need to do something else?
As I understand it from searching about, apparently "most" of boost is just templates and can be used simply by including the headers, but what about the rest?
Am I totally barking up the wrong tree?
Thanks for any help
Since you mentioned you run Windows, take a look at this automated installer:
► http://www.boostpro.com/download/
Also, some general advice:
do I simply extract the headers to my compilers include directory
No! Do not pollute your compiler's includes with third-party includes; make a separate directory specifically for a particular library. You'll then need to tell your specific IDE in what directory it can find the library headers.
I usually use boostpro's installer, it is less work. I vaguely remember having to set up the BOOST_ROOT environment variable on one of my systems to use it.
The libraries that contained compiled source should be included in the installer.
If you don't use the installer (or don't set up your build correctly), and try to use the libraries that need it you will likely get some linker errors when you try and compile your program. Usually if you take those linker errors and plop them in google it tells you pretty quick which libraries you need to include in your build system. I use CMake for that and have been very happy..
Just add the root boost directory to include paths of your compiler/IDE (so if you have Boost extracted to C:\Boost, the compiler will use that path, not C:\Boost\boost).
Don't do any copying of the boost folder to your compiler's include directory, because it may make upgrading Boost harder in the future.
Also if you plan to use any of boost's compiled libraries, add Boost's lib directory to compiler's library search paths. Configuring the compiling step is a matter of putting the right toolset parameter to boost's build tool. If you have your command line environment configured properly, bootstrap should run and compile the builder without any problems, and the Boost builder should properly detect your toolset, so no parameters will be necessary.
As you do such configuration only once every time you do a clean install of your favorite compiler, it's not as hard or daunting as it seems.

Is it possible to include a library from another library using the Arduino IDE?

I'm trying to write an Arduino library (effectively a C++ class) which itself references another library I have installed in my Mac's ~/Documents/Arduino/libraries directory.
At the top of the .cpp of the library I'm writing, I've tried
#include <ReferencedLibrary.h>
and
#include "ReferencedLibrary.h"
... neither of which work. I can successfully #include <ReferencedLibrary.h> from sketches in my ~/Documents/Arduino directory. Am I missing something or is this a limitation of the Arduino IDE/makefile? Is there a workaround?
I have been able to include a library in another Arduino library by using a relative path. For example, to include the AbstractSwitch library into the DigitalSwitch library, assuming that both of these libraries live in their own separate folders within Arduino's standard library folder, you can use the following include statement:
#include "../AbstractSwitch/AbstractSwitch.h"
In other words, your include statement should read:
#include "../LibraryFolder/LibraryHeaderFile.h"
The documentation here https://github.com/arduino/Arduino/wiki/Build-Process states:
The include path includes the sketch's
directory, the target directory
(/hardware/core//) and
the avr include directory
(/hardware/tools/avr/avr/include/),
as well as any library directories (in
/hardware/libraries/) which
contain a header file which is
included by the main sketch file.
This means that if you #include "ReferencedLibrary.h" from your main sketch file, this causes that file's libraries directory to get added to the include path for other libraries to include. A bit of a hack but it does work on my Mac.
This issue was solved in the Arduino 1.6.6 release. The release notes of 1.6.6 mention that library to library dependencies have been fixed.
Library to library dependencies: when your sketch imports a library, and that library uses another, the IDE will find out without you having to add a useless #include to your sketch
Updating your version to 1.6.6 or newer will resolve your problem.
Using the Arduino environement, as I understand it, you cannot access your own library from another of your own libraries. There is no way to add paths, so there is simply no way for the compiler to find the code. That makes it hard to write libraries that use code in another of your libraries. My web research indicates this has been a problem for years but to my knowledge has not been solved. I suspect there are difficulties in the implementation details or perhaps a desire to keep the system simple at the expense of capability.
Of course, you can always cut and paste code into each new library, but that's exceedingly sub-optimal. You can also write one huge library with all of your code in one pair of .h and .cpp files. That's also not very satisfactory, but I've done it on occasion.
There is a work around, however, for using standard Arduino libraries in your own library that you're placing in your sketchbook/libraries directory. Since sketches include paths to the standard library locations, and link the standard library code, you can include the header file for the standard library of interest in your sketch. Below that, also in your sketch, include your own library header file. The standard library will then become available to your library as well as to your sketch.
Not recommended method: It is possible to add basically any external library code to Arduino IDE build by knifing boards.txt file. Headers in c/cpp flags and libraries in ld flags. This may be useful for library dev using external tools (cmake/QT creator for me today).
I modified /home/pekka/arduino-1.8.5/hardware/teensy/avr/boards.txt by adding "/coderoot" to gcc include path and E_OS_arduino define, modified lines below:
teensy36.build.flags.cpp=-fno-exceptions -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -I/coderoot -DE_OS_arduino
teensy36.build.flags.c=-I/coderoot -DE_OS_arduino