Issue between Eigen, make and cmake (probably a cmake mistake) - c++

I encounter an issue when trying to build a little bit of code. (I'm on linux)
To make it simple:
Here is what I've got in my Position.h file (at the really begining, I think the next isn't necessary to solve that issue):
#include <Eigen/Dense>
And Here is my CMakeLists.txt:
project(p)
include_directories("./Eigen")
add_executable(
p
Eigen/Dense
Position.h # wich requires Eigen/Dense
Position.cpp
#other files
)
In the project directory there is two directories: build and Eigen
To create the Makefile, I go in the build directory, then, type cmake ... A Makefile is created, but when I try to make i got the error:
/path/to/Position.h:30:23: fatal error: Eigen/Dense: no such file or directory.
Position.h is from a code picked up from github (I can give you the link if wanted).
Please, can you give me a direction to search or maybe if you see what is wrong, what is my mistake
Thanks!

You can't give a header dependency as source files in add_executable(). And if Position.h does search Eigen/Dense you probably just need include_directories(.).
project(p)
include_directories(.)
add_executable(
p
Position.cpp
Position.h
#other files
)
But why don't you use find_module()?
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
find_package(Eigen3 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIR})
Reference
Unable to find Eigen3 with CMake

Related

Can't find library header CMake

I'm importing admesh library to my cmake project, I've followed the INSTALL instructions from the file in root directory of admesh and it was copied in usr/local/include / usr/local/lib. So, I've added this in my CMakeList:
find_path(ADMESH_INCLUDE_DIR stl.h HINTS "/usr/local/include/admesh")
FIND_LIBRARY(ADMESH_LIBRARY NAMES admesh)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ADMESH DEFAULT_MSG ADMESH_LIBRARY ADMESH_INCLUDE_DIR)
IF(ADMESH_FOUND)
message("admesh found")
SET( ADMESH_LIBRARIES ${ADMESH_LIBRARY} )
ENDIF(ADMESH_FOUND)
include_directories(${ADMESH_INCLUDE_DIR})
target_link_libraries(project PRIVATE admesh ${ADMESH_LIBRARIES})
but when I tried to build it give me this error:
fatal error: 'admesh/stl.h' file not found
#include <admesh/stl.h>
^~~~~~~~~~~~~~
1 error generated.
It prints admesh found so I think that there is something wrong in my CMakeList. How can I fix it?
Should be
find_path(ADMESH_INCLUDE_DIR admesh/stl.h HINTS "/usr/local/include")
or
find_path(ADMESH_INCLUDE_DIR admesh HINTS "/usr/local/include")
Usually /usr/local/include is in the system search include paths, thus all lines until arget_link_libraries(project PRIVATE admesh) can be removed.

Cmake C++ Project With Eigen Headers in src [duplicate]

I am having difficulty using a header-only library (Eigen) in my CMake project. When i take off all the portion related to Eigen library it compiles, but not sure how to build with (Eigen). Note that Eigen has a CmakeLists.txt in Eigen folder, and it has /src folder having (*.h and *.cpp) related to Matrix operation etc...
The structure of my program is as follow
Myproject (folder) is composed of :
CmakeLists.txt
/Build
/Source
The Source folder has bunch of my files (*.h and *.cpp) and the /Eigen (folder).
what i did is :
FIND_PACKAGE(PkgConfig REQUIRED)
PKG_CHECK_MODULES(GTK3 REQUIRED gtk+-3.0)
LIST(APPEND CMAKE_CXX_FLAGS
"-std=c++0x
-pthread
${CMAKE_CXX_FLAGS}
-g
-Wall -Wextra ")
ADD_LIBRARY(Eigen ${CMAKE_SOURCE_DIR}/Eigen)
TARGET_INCLUDE_DIRECTORIES(Eigen INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
$<INSTALL_INTERFACE:include/Eigen>
)
INCLUDE_DIRECTORIES(${GTK3_INCLUDE_DIRS})
ADD_DEFINITIONS(${GTK3_CFLAGS_OTHERS})
INCLUDE_DIRECTORIES(include)
ADD_LIBRARY(RTT
Def.cpp
Def.h
krnel.cpp
krnel.h
Mesh.cpp
Mesh.h
Mcom.cpp
Mcom.h
timer.h
Identifier.h)
ADD_EXECUTABLE(Rdrtst main.cpp)
TARGET_LINK_LIBRARIES(Rdrtst RTT ${GTK3_LIBRARIES} Eigen)
When i cd to /Build and type (Cmake ../Source )
I get the following :
[/../Build]$ cmake ../Source
-- Configuring done
CMake Error: Cannot determine link language for target "Eigen".
CMake Error: CMake can not determine linker language for target:Eigen
-- Generating done
-- Build files have been written to: /../../MyProject/Build
The eigen folder has the CMakeLists.txt with the following content :
include(RegexUtils)
test_escape_string_as_regex()
file(GLOB Eigen_directory_files "*")
escape_string_as_regex(ESCAPED_CMAKE_CURRENT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
foreach(f ${Eigen_directory_files})
if(NOT f MATCHES "\\.txt" AND NOT f MATCHES "${ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/[.].+" AND NOT f MATCHES "${ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/src")
list(APPEND Eigen_directory_files_to_install ${f})
endif()
endforeach(f ${Eigen_directory_files})
install(FILES
${Eigen_directory_files_to_install}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen COMPONENT Devel
)
add_subdirectory(src)
You are trying to include Eigen as a compiled library. However, as you have stated, Eigen is really a header only library and does not need to be compiled, just included. There should be no .cpp files at all.
Remove the line
ADD_LIBRARY(Eigen ${CMAKE_SOURCE_DIR}/Eigen)
as that is meant for static or shared libraries. Now that you're not building Eigen, you can remove the line
TARGET_INCLUDE_DIRECTORIES(Eigen ...
The Eigen CMakeLists file really just copies the Eigen header files to an include directory and doesn't compile anything. See this link for an example of how to use Eigen with CMake.
You just need the correct path in INCLUDE_DIRECTORIES (also make sure to include the correct folder or subfolder, depending if in your c++ file you are using #include Eigen/something.h or #include something.h )
So, remove the lines ADD_LIBRARY(Eigen ... and TARGET_LINK_LIBRARIES Eigen.
For troubleshooting, you can also include the absolute path of the Eigen folder , and then when you get it working, transform it in a relative path
This is a late answer, but it might help someone else. These are the precise steps I took in order to include the Eigen lib into my project with CMake files.
First, assuming your project already include the Eigen sub-directory, e.g., at src/third_party/eigen, copy-paste FindEigen3.cmake file into src/cmake.
Second, you might want to edit the FindEigen3.cmake to include your own location hints that you will provide from you CMake file. For example:
find_path( EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library
HINTS "${EIGEN3_ROOT}" "$ENV{EIGEN3_ROOT_DIR}" "${EIGEN3_INCLUDE_DIR_HINTS}"
# ... leave the rest as it is
)
Third, "include" the Eigen from your CMakeLists.txt by specifying the hint EIGEN3_ROOT and the location of the FindEigen3.cmake file:
message(STATUS "Trying to include Eigen library")
set(EIGEN3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/eigen)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
find_package(Eigen3 3.2.0 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIR})
message(STATUS "EIGEN: " ${EIGEN3_VERSION} " (internal)")
Forth, start using Eigen from within your project:
#include <Eigen/Dense>
using Eigen::MatrixXd;
// ...
MatrixXd m(2,2);
m(0,0) = 3;
m(1,0) = 2.5;
m(0,1) = -1;
m(1,1) = m(1,0) + m(0,1);
std::cout << m << std::endl;

Statically linking GLEW from source with cmake

I am somewhat new to cmake and completely new to glew, glfw, and the like. I'm following a youtube channel to learn more about game engines and programming.
My problem is linking the static glew library in my project using cmake.
First, I start with the glew source code from http://mcs.une.edu.au/doc/glew-devel/index.html.
I compile it by:
cd build; cmake ./cmake; make glew_s
This adds a lib directory into the build directory with libGLEW.a
A shortened version of my CMakeLists.txt looks like:
cmake_minimum_required (VERSION 3.5 FATAL_ERROR)
project (TestProject CXX)
set(CMAKE_CXX_FLAGS "-std=c++11")
###########################
# GLEW
###########################
add_subdirectory(${CMAKE_SOURCE_DIR}/Dependencies/GLEW)
target_link_libraries(${PROJECT_NAME} glew)
and in Dependencies/GLEW I have another CMakeLists.txt:
# Add glew source and header files
file(GLOB_RECURSE glew-lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/*)
file(GLOB_RECURSE glew-headers ${CMAKE_CURRENT_SOURCE_DIR}/include/GL/*)
add_library(glew ${glew-lib} ${glew-headers})
target_include_directories(glew PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include/GL")
I put a copy of the libGLEW.a file into the lib directory and the include directory is copied from the glew source code include directory. It holds the GL directory, which contains the header files glew.h, wglew.h, eglew.h, and glxew.h.
When I run cmake I get the error:
CMake Error: Cannot determine link language for target "glew".
CMake Error: CMake can not determine linker language for target: glew
The glew source code also has a src directory with glew.c in it, but if I put it in the libs directory and include it in the Dependencies/GLEW/CMakeLists.txt like:
# Add glew source and header files
file(GLOB_RECURSE glew-lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/*.c)
file(GLOB_RECURSE glew-headers ${CMAKE_CURRENT_SOURCE_DIR}/include/GL/*)
add_library(glew ${glew-lib} ${glew-headers})
target_include_directories(glew PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
I get the error:
CMake Error: Error required internal CMake variable not set, cmake may
be not be built correctly.
Missing variable is: CMAKE_C_COMPILE_OBJECT
CMake Error: Error required internal CMake variable not set, cmake may
be not be built correctly.
Missing variable is: CMAKE_C_CREATE_STATIC_LIBRARY
Lastly, I have tried just including the glew.c and headers in the root CMakeLists.txt like:
#########################
# GLEW
#########################
include_directories("${CMAKE_SOURCE_DIR}/Dependencies/GLEW/lib/")
include_directories("${CMAKE_SOURCE_DIR}/Dependencies/GLEW/include/GL/")
Here cmake will finish, but it won't be able to compile, saying classes do not name a type and/or are not declared in this scope.
Any help would be appreciated. I was under the impression that the libGLEW.a was the static library, and all I would have to do is link and compile it along with the headers, but that did not work.
First of all, I forgot to use
make install
after using make the first time, so I was using the incorrect libGLEW.a file.
After including the proper libGLEW.a file, my directory structure had
./Dependencies/GLEW/include/GL/*.h //header files
./Dependencies/GLEW/lib/libGLEW.a //source file
Finally, the TopLevel CMakeLists.txt is changed to include:
add_library(glew STATIC IMPORTED GLOBAL)
set_target_properties(glew PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/Dependencies/GLEW/lib/libGLEW.a )
set_target_properties(glew PROPERTIES INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/Dependencies/GLEW/include )
If I want to include the library from a lower CMakeLists.txt such as /Dependencies/GLEW/CMakeLists.txt Then I would have to first export the library from there and then import it at the topLevel CMakeLists.txt file.
Now, in order to use glew headers in my project I can just use #include .

My project can find one library header, but not another one

I have two C++ libraries, which I am using on Ubuntu. One of them, let's call it foo, I installed through apt-get, e.g. sudo apt-get install libfoo-dev. The other, let's call it bar, I installed by downloading the source files, and running make install. After these installations, I then have header files from foo in locations such as /usr/include/foo/foo.h, and header files from bar in locations such as /usr/local/include/bar/bar.h. From my knowledge, foo is a dependency of bar.
I then created my own C++ project, and included the line #include "bar/bar.h". But when compiling my project, I get an error saying error: foo.h: No such file or directory. If I click on the error in my debugger, it opens the file bar.h, and highlights the line #include <foo.h>. So, my project is able to find bar.h, but not foo.h. I do not mention either foo or bar in my CMakeLists.txt file.
So my questions are:
How does my project know how to find bar.h, when I have not told it where to find it in CMakeLists.txt?
What do I need to do to get my project to find foo.h and compile properly?
Thank you!
Edit: Here is my CMakeLists.txt file (the foo and bar libraries are none of the ones mentioned here):
cmake_minimum_required(VERSION 2.8.1)
set(CMAKE_CXX_FLAGS "-std=c++11 -O3")
project(Grasping_Simulator)
find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
find_package(GLUT REQUIRED)
find_package(Eigen3 REQUIRED)
find_package(Boost REQUIRED)
find_package(OpenCV REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDE_DIR} ${GLUT_INCLUDE_DIR} ${EIGEN3_INCLUDE_DIR} ${BOOST_INCLUDE_DIRS} ${OPENCV_INCLUDE_DIRS})
file(GLOB SRCS *.cpp *.h)
add_executable(${PROJECT_NAME} ${SRCS})
target_link_libraries(${PROJECT_NAME} ${GLEW_LIBRARY} ${GLUT_LIBRARY} ${OpenCV_LIBS} pthread GL boost_system)
You need to add the option -I/usr/include/foo/ to your compilation command.
By default, locations such as /usr/include/ and /usr/local/include are already in the include search path. However, your library bar does something naughty by using #include <foo.h>. Really, it should be using things like #include <foo/foo.h> (by the way if you can make this change that would be cleaner). That would allow the compiler to search all its include paths, including the path /usr/include/, and try appending /foo/foo.h - which would succeed. As it stands, there is nothing in the default include path which would work merely by appending /foo.h, so it fails to find it.
EDIT: Given your CMake code above, most likely you need to append a variable that contains the value /usr/include/foo to the include_directories line to achieve the desired effect (this being the inclusion of -I/usr/include/foo/ on the compilation line).

Can't Include LibXML2 Files in a CMake C++ Project (using QtCreator IDE)

I'm working on a Cmake based C++ project in QtCreator. I am trying to use mlpack in my project, but as soon as I include the line #include <mlpack/core.hpp> to my only source file, I get an error pertaining to some libxml files that are included by mlpack/core.hpp:
In file included from /usr/local/include/mlpack/core/util/save_restore_utility.hpp:26:0,
from /usr/local/include/mlpack/core.hpp:171,
from /home/revinci/code/workspaces/qt_ws/Semantic_Perception/src/features_slic.cpp:18:
/usr/include/libxml2/libxml/parser.h:15:31: fatal error: libxml/xmlversion.h: No such file or directory
#include <libxml/xmlversion.h>
Now, I went into /usr/include/libxml2/libxml/ and found parser.h with the line #include <libxml/xmlversion.h> in it.
So, I saw that xmlversion.h and parser.h are in the same folder and tried a hack: I changed the #include <libxml/xmlversion.h> in parser.h to #include "xmlversion.h" only to get the following error:
In file included from /usr/include/libxml2/libxml/parser.h:15:0,
from /usr/local/include/mlpack/core/util/save_restore_utility.hpp:26,
from /usr/local/include/mlpack/core.hpp:171,
from /home/revinci/code/workspaces/qt_ws/Semantic_Perception/src/features_slic.cpp:18:
/usr/include/libxml2/libxml/xmlversion.h:13:31: fatal error: libxml/xmlexports.h: No such file or directory
#include <libxml/xmlexports.h>
Which is basically telling me that it can't find xmlexports.h (included by xmlversion.h). More importantly, xmlexports.h is in the same directory as xmlversion.h and parser.h!
I tried the solution mentioned here and installed libxml2-dev (again) and libxslt1-dev, but my problem wasn't solved.
I think this may have something to do with specifying my include paths correctly. I've tried to add /usr/include/libxml2 to the various path environment variables (PATH, INCLUDE_PATH and CPATH) that are present in my build environment in QtCreator, but to no avail. My CMakeLists.txt looks like this:
project(Semantic_Perception)
cmake_minimum_required(VERSION 2.8)
#Vigra Headers
include_directories(
include
)
file(GLOB_RECURSE VigraImpex include/impex/)
add_library(VigraImpex ${VigraImpex})
#LibXml2 Headers
find_package(LibXml2 REQUIRED)
#Armadillo Headedrs
find_package(Armadillo REQUIRED)
include_directories(${ARMADILLO_INCLUDE_DIRS})
#Boost Headers
find_package(Boost 1.54.0 REQUIRED)
add_executable(features_slic src/features_slic.cpp)
target_link_libraries(features_slic
VigraImpex
${ARMADILLO_LIBRARIES}
)
BTW: LibXml2, Armadillo and Boost are all dependencies of the library I am trying to use - mlpack. The command find_pakcage(mlpack) won't work because there is no Findmlpack.cmake file on my system anywhere, and I couldn't find one on the internet either.