C++: Where to place files using #include <> with angle brackets - c++

Context:
I am trying to run the code for a thin-plate spline provided by Jarno Elonen at http://elonen.iki.fi/code/tpsdemo/. It requires the installation of OpenGL + GLUT and the Boost uBlas library. I have downloaded the code, but I have been unable to run it because the compiler can't locate the GLUT and Boost files.
I'm hoping that someone can get the code on the website to run (and not just address the immediate trouble I'm facing), and tell me the exact steps to follow to get it to run. (I don't mind if you dumb it down completely, I'm a beginner :) )
What I have done so far:
Downloaded and extracted tpsdemo-1.2.tar.gz from the website above
Downloaded FreeGLUT (because various online forums told me I should be doing this as GLUT itself is outdated...): Freeglut 3.0.0 from freeglut.sourceforge.net/index.php#download.
Downloaded Boost: boost_1_61_0.zip from www.boost.org/users/history/version_1_61_0.html.
I don't know what to do from here... where should I put these files so that the code from tpsdemo-1.2 can access them? I have tried putting it in the same directory, but this seems to require using #include "filename" with quotation marks instead of the #include <filename> with angle brackets which is in the provided code. If I do alter it like this, then it seems like I will have to change all include statements in GLUT and Boost (which currently use angle brackets) which is not a small task. (I don't really want to be modifying too much code...) What's the correct way to do this? I have tried using the -Idir tag while compiling but this runs into other problems, although I don't know if this problem is to do with GLUT/Boost (which is why I'd like to see if anyone else can get the code to run!)

wedge brackets in a#include are for denoting files that exist on a system or framework level. As such you never get them there by moving them into the "right" place, but instead you specify which directories are to be considered "system" or "framework" level. The exact method in the end is depending on the compiler used, but all major compilers out there understand the -I${PATH_TO_INCLUDE_DIRECTORY command line option notation. -I… may be specified multiple times to specify multiple directories.
It is a good style to use wedge bracketed includes exclusively for headers that are 3rd party to a project and/or for headers that form the framework of a project. For headers that belong to modules of a project itself quotation marks should be used.

Related

How can I link a library that contains conditional types/variables definition based on global variables defined through CMake?

Introduction
I am trying to use Toulbar2 as a C++ library in my CMake project, however I am having much trouble linking it to my main executable.
I found many similar questions on this topic, both here and on other similar website, but none of them helped me with my specific issue. I tried literally everything and I did not menage to make it work, I was hoping that some of you may help me with that.
I am running Ubuntu 18.04, CMake version 3.23 and in my project I am using the standard C++11. I am a proficient programmer, but I am just an beginner/intermediate user of both C++ and CMake.
What I've already tried to do
I cannot list all my attempts, so I will only mention those I think are my best ones, to give you an idea of what I may be doing wrong.
1) In my first attempt, I tried to use the same approach I used for any non-standard library I imported, i.e. using find_package() in CMakeLists.txt to then link the found LIBRARIES and include the found INCLUDE_DIRS. However, I soon realised that Toulbar2 provides neither a Find<package>.cmake or <name>Config.cmake file. So, this approach could not work.
2) My second attempt is the one that in my opinion brought me the closest to the solution I hoped for. You can easily compile Toulbar2 as a dynamic library using the command: cmake -DLIBTB2=ON .. in an hypothetical build directory you previously created. After compiling with make you have your .so file in build/lib/Linux. After installation, you can make CMake find this library by itself using the command find_library. So, my CMakeLists.txt ended up looking like this:
[...]
find_library(TB2_LIBRARIES tb2)
if(TB2_LIBRARIES)
set(all_depends ${all_depends} ${TB2_LIBRARIES})
else(TB2_LIBRARIES)
add_compile_definitions("-DNO_TB2")
message("Compiling without Toulbar2, if you want to use it, please install it first")
endif(TB2_LIBRARIES)
[...]
target_link_libraries(main ${all_depends})
[...]
This code works to some extent, meaning that CMake correctly finds the library and runs the linking command, however if I try to #include <toulbar2lib.hpp> the header is not found. So I figured out I should have told CMake where to find that header, so I ended up adding a
include_directories(/path/to/header/file's/directory)
However, I still have another problem. The header is found, but a lot of names used in the header are not found at compilation time. The reason is that in Toulbar2 some variables/types are defined conditionally by using preprocessing directives like #ifdef or #ifndef, and in turn the global variables used in these conditions are defined through CMake at compilation time. If you are interested in an example, I can mention the Cost type that is used in the mentioned header file. I see that there's a piece missing in the puzzle here, but I cannot figure out which one. Since I pre-compiled the library those definitions should exist when I include the header file, because I am correctly linking the correspondent library that contains those definitions.
3) My third attempt is less elegant than the the other two I mentioned, but I was desperately trying to find a solution. So, I copied the whole toulbar2 cloned folder inside my project and I tried to add it as a subdirectory, meaning that my main CMakeLists.txt contains the line:
add_subdirectory(toulbar2)
It provides a CMakeLists.txt too, there should be no problem in doing it. Then I include the src directory of toulbar2, that contains the header file I need, and I should be okay. Right? Wrong. I got the same problem that I had before with (2), i.e. some variables/types conditionally defined were not actually defined when I tried to compile my project, even though the subproject toulbar2 was correctly (no errors) compiled.
I just wanted to mention that any answer is welcome, however if you could help me figure out an elegant solution (see 1 or 2) for this problem it would be way better, as this code is intended to be published soon or later. Thank you in advance for your help.
Solution 2) looks fine. You just need to add the following compilation flags -DNDEBUG -DBOOST -DLONGDOUBLE_PROB -DLONGLONG_COST when compiling your project with toulbar2lib.hpp. See github/toulbar2 README.md how to compile without cmake for those flags (except WCSPFORMATONLY that should not by used in this context).

Linking a new third party library to a c++ program while working with eclipse on Ubuntu

I recently downloaded a third party library called spline-master from github and the file provides a header file called spline.h. I wanted to use this header file so as to create a spline. I am currently using eclipse oxygen for c/c++. I was pretty new to this and have been stuck on this problem since the last few days. I tried changing so many things to link this file. The file can be seen in my project tree and it's there in the includes but when I write #include"spline.h" it throws me an error telling "there exists no such file or directory".
Can anyone please let me know how I can go about this problem? All the applications are of the latest version including Ubuntu. I would have attached a couple of screenshots so that you can have a better idea about the problem I am facingenter image description here
Thanking you.
Regards,
Sumanth
enter image description here
There are 2 main ways to include a header file, and you need to know where your spline.h is located in order to know which one you can use.
#include "spline.h"
Enclosing in quotes will tell the preprocessor that the path you have supplied is relative to the location of the code file you are including the file into. Your compiler can't find the file which means it must be located in a directory different to the code file you are working on.
#include <spline.h>
This is probably the version you want to use. This version will tell the preprocessor to look for spline.h in any header directories you have defined in your project. Again, it considers the path relative to the header directory.

Where are CMAKE_HOST_APPLE / CMAKE_HOST_UNIX / CMAKE_HOST_WIN32 set?

I've started digging in under the hood so that I can better understand the inner workings of CMake. I've been going through the files in the Modules directory in order to understand how/why/when things happen when running CMake.
I've so far been unable to determine how/where the CMAKE_HOST_APPLE/CMAKE_HOST_UNIX/CMAKE_HOST_WIN32 variables are set.
Can anyone enlighten me?
On a related note, I've been going through the Modules files in a haphazard manner since I don't know the order in which they are initiated/processed.
Is there anywhere that describes this flow or at the very least indicates a starting point so that I can figure out the rest from there?
Those variables are set in CMake's code surrounded by platform dependent #ifdef checks, so you can say they are set during compile time of CMake itself.
I also had some difficulties locating the source file in question, because the code to add those default variable definitions has just recently moved from cmMakefile::AddDefaultDefinitions() to cmState::Snapshot::SetDefaultDefinitions() (see this commit).
Here is an example from cmState.cxx:
#if defined(__APPLE__)
this->SetDefinition("APPLE", "1");
this->SetDefinition("CMAKE_HOST_APPLE", "1");
#endif
For more information on how CMake does work see:
CMake: In which Order are Files parsed (Cache, Toolchain, …)?
How to frame the concept behind CMake?
About CMake
The Architecture of Open Source Applications: CMake

Codeblocks can't find header files

So a few hours ago I started learning c++ in codelite but I was getting frustated with, so I just got codeblocks and imported the project. But now whenever I try to compile it returns:
fatal error: imports.h: No such file or directory
This is my project hierarchy in codeblocks:
And this is what the project folder looks like:
What am I doing wrong?
I know this is years later, but I've recently seen students following what I deem is frankly bad advice such as what is given above. For those learning c++ this functionality is NOT for you. To add headers you should simply check that you are using double quotes, instead of angled brackets i.e.
#include "myheader.h"
and NOT
#include <myheader.h>
Angled brackets are meant for libraries (informally) and adding a simple header file for you basic classes does not require you to change default search directories. The problem comes when someone else tries to run your code (assuming you're doing this for uni) and their IDE isn't setup to search for a "library" (your header) where it shouldn't be. Double quotes tells the compiler the files exist in your current relative directory. This way you can keep your main, headers and header implementation in one directory. Fiddling with your IDE should only be done when necessary. KISS
You have to tell Codeblocks where to find the header files that you include. Try adding the full path to your '/Headers' in the include directories of codeblocks
Goto 'Codeblocks menu > Settings > Compiler > Search directories > Add'.
EDIT: Since your issue, however, is quite irrelevant to learning the C++ language itself, I suggest that you start with simpler programs, then move on to more complex ones. That, of course, unless you have previous experience with other programming languages
Since I haven't found any Makro for
#define 'hostname of device where compiler is located' // which is unique and not to be copied !
I have now successfully used and included
#include "myCompileEnv.h"
as a workaround with the comments above, which is located more central - above the project directories in CodeBlocks.

Using 3rd party header files with Rcpp

I have a header file called coolStuff.h that contains a function awesomeSauce(arg1) that I would like to use in my cpp source file.
Directory Structure:
RworkingDirectory
sourceCpp
theCppFile.cpp
cppHeaders
coolStuff.h
The Code:
#include <Rcpp.h>
#include <cppHeaders/coolStuff.h>
using namespace Rcpp;
// [[Rcpp::export]]
double someFunctionCpp(double someInput){
double someOutput = awesomeSauce(someInput);
return someOutput;
}
I get the error:
theCppFile.cpp:2:31: error: cppHeaders/coolStuff.h: No such file or directory
I have moved the file and directory all over the place and can't seem to get this to work. I see examples all over the place of using 3rd party headers that say just do this:
#include <boost/array.hpp>
(Thats from Hadley/devtools)
https://github.com/hadley/devtools/wiki/Rcpp
So what gives? I have been searching all morning and can't find an answer to what seems to me like a simple thing.
UPDATE 01.11.12
Ok now that I have figured out how to build packages that use Rcpp in Rstudio let me rephrase the question. I have a stand alone header file coolStuff.h that contains a function I want to use in my cpp code.
1) Where should I place coolStuff.h in the package directory structure so the function it contains can be used by theCppFile.cpp?
2) How do I call coolStuff.h in the cpp files? Thanks again for your help. I learned a lot from the last conversation.
Note: I read the vignette "Writing a package that uses Rcpp" and it does not explain how to do this.
The Answer:
Ok let me summarize the answer to my question since it is scattered across this page. If I get a detail wrong feel free to edit this or let me know and I will edit it:
So you found a .h or .cpp file that contains a function or some other bit of code you want to use in a .cpp file you are writing to use with Rcpp.
Lets keep calling this found code coolStuff.h and call the function you want to use awesomeSauce(). Lets call the file you are writing theCppFile.cpp.
(I should note here that the code in .h files and in .cpp files is all C++ code and the difference between them is for the C++ programer to keep things organized in the proper way. I will leave a discussion of the difference out here, but a simple search here on SO will lead you to discussion of the difference. For you the R programer needing to use a bit o' code you found, there is no real difference.)
IN SHORT: You can use a file like coolStuff.h provided it calls no other libraries, by either cut-and-pasteing into theCppFile.cpp, or if you create a package you can place the file in the \src directory with the theCppFile.cpp file and use #include "coolStuff.h" at the top of the file you are writing. The latter is more flexible and allows you to use functions in coolStuff.h in other .cpp files.
DETAILS:
1) coolStuff.h must not call other libraries. So that means it cannot have any include statements at the top. If it does, what I detail below probably will not work, and the use of found code that calls other libraries is beyond the scope of this answer.
2) If you want to compile the file with sourceCpp() you need to cut and paste coolStuff.h into theCppFile.cpp. I am told there are exceptions, but sourceCpp() is designed to compile one .cpp file, so thats the best route to take.
(NOTE: I make no guarantees that a simple cut and paste will work out of the box. You may have to rename variables, or more likely switch the data types being used to be consistent with those you are using in theCppFile.cpp. But so far, cut-and-paste has worked with minimal fuss for me with 6 different simple .h files)
3) If you only need to use code from coolStuff.h in theCppFile.cpp and nowhere else, then you should cut and paste it into theCppFile.cpp.
(Again I make no guarantees see the note above about cut-and-paste)
4) If you want to use code contained in coolStuff.h in theCppFile.cpp AND other .cpp files, you need to look into building a package. This is not hard, but can be a bit tricky, because the information out there about building packages with Rcpp ranges from the exhaustive thorough documentation you want with any R package (but that is above your head as a newbie), and the newbie sensitive introductions (that may leave out a detail you happen to need).
Here is what I suggest:
A) First get a version of theCppFile.cpp with the code from coolStuff.h cut-and-paste into theCppFile.cpp that compiles with sourceCpp() and works as you expect it to. This is not a must, but if you are new to Rcpp OR packages, it is nice to make sure your code works in this simple situation before you move to the more complicated case below.
B) Now build your package using Rcpp.package.skeleton() or use the Build functionality in RStudio (HIGHLY recommended). You can find details about using Rcpp.package.skeleton() in hadley/devtools or Rcpp Attributes Vignette. The full documentation for writing packages with Rcpp is in the Writing a package that uses Rcpp, however this one assumes you know your way around C++ fairly well, and does not use the new "Attributes" way of doing Rcpp.
Don't forget to "Build & Reload" if using RStudio or compileAttributes() if you are not in RStudio.
C) Now you should see in your \R directory a file called RcppExports.R. Open it and check it out. In RcppExports.R you should see the R wrapper functions for all the .cpp files you have in your \src directory. Pretty sweet.
D) Try out the R function that corresponds to the function you wrote in theCppFile.cpp. Does it work? If so move on.
E) With your package built you can move coolStuff.h into the src folder with theCppFile.cpp.
F) Now you can remove the cut-and-paste code from theCppFile.cpp and at the top of theCppFile.cpp (and any other .cpp file you want to use code from coolStuff.h) put #include "coolStuff.h" just after #include <Rcpp.h>. Note that there are no brackets around ranker.h, rather there are "". This is a C++ convention when including local files provided by the user rather than a library file like Rcpp or STL etc...
G) Now you have to rebuild the package. In RStudio this is just "Build & Reload" in the Build menu. If you are not using RStudio you should run compileAttributes()
H) Now try the R function again just as you did in step D), hopefully it works.
The problem is that sourceCpp is expressly designed to build only a single standalone source file. If you want sourceCpp to have dependencies then they need to either be:
In the system include directories (i.e. /usr/local/lib or /usr/lib); or
In an R package which you list in an Rcpp::depends attribute
As Dirk said, if you want to build more than one source file then you should consider using an R package rather than sourceCpp.
Note that if you are working on a package and perform a sourceCpp on a file within the src directory of the package it will build it as if it's in the package (i.e. you can include files from the src directory or inst/include directory).
I was able to link any library (MPFR in this case) by setting two environment variables before calling sourceCpp:
Sys.setenv("PKG_CXXFLAGS"="-I/usr/include")
Sys.setenv("PKG_LIBS"="-L/usr/lib/x86_64-linux-gnu/ -lm -lmpc -lgmp -lmpfr")
The first variable contains the path of the library headers. The second one includes the path of the library binary and its file name. In this case other dependent libraries are also required. For more details check g++ compilation and link flags. This information can usually be obtained using pkg-config:
pkg-config --cflags --libs mylib
For a better understanding, I recommend using sourceCpp with verbose output in order to print the g++ compilation and linking commands:
sourceCpp("mysource.cpp", verbose=TRUE, rebuild=TRUE)
I was able to link a boost library using the following global command in R before calling sourceCpp
Sys.setenv("PKG_CXXFLAGS"="-I \path-to-boost\")
Basically mirroring this post but with a different compiler option: http://gallery.rcpp.org/articles/first-steps-with-C++11/
Couple of things:
"Third party header libraries" as in your subject makes no sense.
Third-party headers can work via templated code where headers are all you need, ie there is only an include step and the compiler resolves things.
Once you need libraries and actual linking of object code, you may not be able the powerful and useful sourceCpp unless you gave it meta-information via plugins (or env. vars).
So in that case, write a package.
Easy and simple things are just that with Rcpp and the new attributes, or the older inline and cxxfunction. More for complex use --- and external libraries is more complex you need to consult the documentation. We added several vignettes to Rcpp for that.
Angle brackets <> are for system includes, such as the standard libs.
For files local to your own project, use quotes: "".
Also, if you are placing headers in a different directory, the header path should be specified local to the source file including it.
So for your example this ought to work:
#include "../cppHeaders/coolStuff.h"
You can configure the search paths such that the file could be found without doing that, but it's generally only worth doing that for stuff you want to include across multiple projects, or otherwise would expect someone to 'install'.
We can add it by writing path to the header in the PKG_CXXFLAGS variable of the .R/Makevars file as shown below. The following is an example of adding header file of xtensor installed with Anaconda in macOS.
⋊> ~ cat ~/.R/Makevars
CC=/usr/local/bin/gcc-7
CXX=/usr/local/bin/g++-7
CPLUS_INCLUDE_PATH=/opt/local/include:$CPLUS_INCLUDE_PATH
PKG_CXXFLAGS=-I/Users/kuroyanagi/.pyenv/versions/miniconda3-4.3.30/include
LD_LIBRARY_PATH=/opt/local/lib:$LD_LIBRARY_PATH
CXXFLAGS= -g0 -O3 -Wall
MAKE=make -j4
This worked for me in Windows:
Sys.setenv("PKG_CXXFLAGS"='-I"C:/boost/boost_1_66_0"')
Edit: Actually you don't need this if you use Boost Headers (thanks to Ralf Stubner):
// [[Rcpp::depends(BH)]]