cmake find_path not working for simple file - cmake

I'm trying to find a problem why cmake is not able to find a custom openssl version, therefore I debugged the original findOpenssl.cmake.
There they search for the ssl.h file. So, I created a small cmake file which tries to find out the issue:
project(CMAKETEST)
cmake_minimum_required(VERSION 3.16)
set(OPENSSL_CUSTOM_PATH "/home/user/Documents/CMakeTest/openssl/include/openssl/ssl.h")
message(STATUS CUSTOMOPENSSLPATH: ${OPENSSL_CUSTOM_PATH})
find_path(TEST123
NAMES ${OPENSSL_CUSTOM_PATH}
)
message(STATUS ${TEST123})
I created an empty ssl.h file in the above folder, but cmake is not able to find the file. TEST123 is always NOT-FOUND.
Solution:
set(OPENSSL_CUSTOM_PATH "/home/user/Documents/CMakeTest/openssl/include/openssl")
find_path(TEST123 NAMES ssl.h PATHS "${OPENSSL_CUSTOM_PATH}")
Update
This more concrete example does not work as expected:
project(CMAKETEST)
cmake_minimum_required(VERSION 3.16)
set(OPENSSL_CUSTOM_PATH "/home/user/Documents/CMakeTest/openssl/")
find_path(TEST123
NAMES openssl/ssl.h HINTS "${OPENSSL_CUSTOM_PATH}"
PATH_SUFFIX include
NO_DEFAULT_PATH
)
message(STATUS ${TEST123})
when removing NO_DEFAULT_PATH then it finds the system openssl library in /usr/include
Update 2
https://github.com/Kitware/CMake/blob/master/Modules/FindOpenSSL.cmake#L195-L204
find_path(OPENSSL_INCLUDE_DIR
NAMES
openssl/ssl.h
${_OPENSSL_ROOT_HINTS_AND_PATHS}
HINTS
${_OPENSSL_INCLUDEDIR}
${_OPENSSL_INCLUDE_DIRS}
PATH_SUFFIXES
include
)
finds first the path in /usr/include, if I add NO_DEFAULT_PATH it finds it. Probably it was because some caching that it was not found during I wrote this question.

It isn't working because you use it incorrectly, for your case it should be like this:
set(OPENSSL_CUSTOM_PATH "/home/user/Documents/CMakeTest/openssl/include/openssl")
find_path(TEST123 NAMES ssl.h PATHS "${OPENSSL_CUSTOM_PATH}")
Or simply find_path(TEST123 ssl.h PATHS "${OPENSSL_CUSTOM_PATH}")
In your update you have a error PATH_SUFFIX should be PATH_SUFFIXES.

Related

Relative paths not recognized with CMake

I'm new to C++ and I would like to use the Pytorch library in C++. The tutorial can be seen here https://pytorch.org/cppdocs/installing.html
I have an issue with my /home/local/CLionProjects/MachineAI/CMakeLists.txt file
cmake_minimum_required(VERSION 3.2)
project(MachineAI)
set(CMAKE_PREFIX_PATH ${CMAKE_SOURCE_DIR}/libtorch)
find_package(Torch REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} "${TORCH_LIBRARIES}" )
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14)
This produces a lot of errors but they mostly seem to have the same problem. It's not able to find a specific file. Here's an example:
CMake Error at libtorch/share/cmake/Caffe2/Caffe2Config.cmake:14 (include):
include could not find requested file:
public/utils.cmake
The error is suggesting the wrong path is provided. If I take a look inside the libtorch/share/cmake/Caffe2/Caffe2Config.cmake, the problem line is:
include("public/utils.cmake")
It cannot find the file even though the file is located at the correct relative path libtorch/share/cmake/Caffe2/public/utils.cmake
If I replace the path with an absolute path, the error goes away:
include("/home/local/CLionProjects/MachineAI/libtorch/share/cmake/Caffe2/public/utils.cmake")
Here is the screenshot of relevant files for better orientation:
I would like to know if there's a way to fix the CMakeLists.txt file at the top so that Caffe2Config.cmake will be able to find the files through the relative path.

CMake doesn't add /usr/include to include_directories list

I'm trying to build a CMake project with a customed arm-linux-..g++ compiler. This project is using some third-party library (libzmq for the manner of sake). Now the problem is that when I install libzmq, it puts the header file in /usr/include, but my compiler doesn't search for .h files there.
I tried the following:
find_package(PkgConfig)
pkg_check_modules(LIBZMQ REQUIRED libzmq)
// Now I have a variable ${LIBZMQ_INCLUDEDIR} populated with /usr/include - checked it
include_directories(
${LIBZMQ_INCLUDEDIR}
)
...
The problem is, that CMake won't add the /usr/include path to the list of -I.. in the flags.make, I guess it's because CMake assumes that this path is in the search path of the compiler anyway.
How do I deal with this?

Can't seem to include Glut to my cmake project Ubuntu [duplicate]

I've been stuck for a while now and I can't figure out how to get freeglut working. I thought I knew what it was asking me to do, so I added that set(prefix_path) line but it didn't do anything. Am I supposed to write my own freeglut-config.cmake or what?
Note: I am using the freeglut for MinGW package from this website
CMake File:
cmake_minimum_required(VERSION 3.7)
project(HW1)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES Triangle.cpp)
set(CMAKE_PREFIX_PATH "C:/freeglut")
find_package(GLEW REQUIRED STATIC)
find_package(FREEGLUT REQUIRED)
find_package(OPENGL REQUIRED)
include_directories(${FREEGLUT_INCLUDE_DIRS} ${GLEW_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIRS})
link_directories(${FREEGLUT_LIBRARY_DIRS} ${GLEW_LIBRARY_DIRS} ${OPENGL_LIBRARY_DIRS})
add_definitions(${FREEGLUT_DEFINITIONS} ${GLEW_DEFINITIONS} ${OPENGL_DEFINITIONS})
add_executable(HW1 ${SOURCE_FILES})
target_link_libraries(HW1 ${FREEGLUT_LIBRARIES} ${GLEW_LIBRARIES} ${OPENGL_LIBRARIES})
Full error:
CMake Error at CMakeLists.txt:8 (find_package):
By not providing "FindFREEGLUT.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "FREEGLUT",
but CMake did not find one.
Could not find a package configuration file provided by "FREEGLUT" with any
of the following names:
FREEGLUTConfig.cmake
freeglut-config.cmake
Add the installation prefix of "FREEGLUT" to CMAKE_PREFIX_PATH or set
"FREEGLUT_DIR" to a directory containing one of the above files. If
"FREEGLUT" provides a separate development package or SDK, be sure it has
been installed.
If your application is GLUT-compatible, that it doesn't use any extension of freeglut, then it is better to search GLUT instead of FREEGLUT:
find_package(GLUT REQUIRED)
"Find" script used by this command is already shipped into CMake distro, and it searches freeglut too.
(Note, that with that command variables for include directories and linking libraries are GLUT_INCLUDE_DIR and GLUT_LIBRARY correspondingly).
If your application requires exactly freeglut (that is, uses some of its extensions incompatible with other GLUT implementations), you need to ship your package with FindFREEGLUT.cmake script and adjust CMAKE_MODULE_PATH variable correspondingly:
# Assuming you have <source-dir>/cmake/FindFREEGLUT.cmake
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
find_package(FREEGLUT REQUIRED)
You may find existing script in the net, or write it by yourself, like here.
In any case, if you have freeglut installed into non-system location, you need to hint CMake about that. E.g., by adjusting CMAKE_PREFIX_PATH.

cmake include directories issue with cygwin

I want to add include directories to my project, which are defined in some environment variable SOME_DIR. SOME_DIR is set to 'D:\some_dir'.
Here's how I've added it in CMakeLists.txt:
include_directories($ENV{SOME_DIR}/include)
After generating Unix Makefiles via cygwin, compiler can't find header files from this directory. So, I've added some debug outputs to check list of included directories like this:
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
foreach(dir ${dirs})
message(STATUS "dir='${dir}'")
endforeach()
Output is:
dir='/cygdrive/d/myproject/D:/some_dir/include'
My question is: What should I do so that cmake include correct path, i.e. 'D:/some_dir/include'?

Find package Eigen3 for CMake

CMake cannot find my Eigen3 package. I set an environment variable called
EIGEN3_INCLUDE_DIR
pointing to the path where FindEigen3.cmake is.
Then in the CMakelists.txt I wrote:
find_package( Eigen3 REQUIRED )
include_directories( EIGEN3_INCLUDE_DIR )
I get next message of error:
CMake Error at C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:91 (MESSAGE):
Could NOT find Eigen3 (missing: EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK)
(Required is at least version "2.91.0")
Call Stack (most recent call first):
C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:252 (_FPHSA_FAILURE_MESSAGE)
C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/FindEigen3.cmake:76 (find_package_handle_standard_args)
test/test_quaternion/CMakeLists.txt:25 (find_package)
Any idea on what I am missing or doing wrong?
Since Eigen3 is completely header only, all you ever need is the path to the include directory. And this one, you are already defining manually anyway. So there is no real need for a FindEigen3.cmake or FIND_PACKAGE call.
Simply use
INCLUDE_DIRECTORIES ( "$ENV{EIGEN3_INCLUDE_DIR}" )
or
SET( EIGEN3_INCLUDE_DIR "$ENV{EIGEN3_INCLUDE_DIR}" )
IF( NOT EIGEN3_INCLUDE_DIR )
MESSAGE( FATAL_ERROR "Please point the environment variable EIGEN3_INCLUDE_DIR to the include directory of your Eigen3 installation.")
ENDIF()
INCLUDE_DIRECTORIES ( "${EIGEN3_INCLUDE_DIR}" )
A few notes:
If you want to access the content of a CMake variable, make sure to use ${...}
$ENV{....} accesses environment variables.
The second example will stop with an error if the environment variable is not set (and, thus, EIGEN3_INCLUDE_DIR cmake variable is empty)
Be careful to use quotation marks around (evaluated) variables if they could contain whitespace. Otherwise, CMake will interpret it as a list.
If you want to use custom find modules, make sure to either place them in you CMake installation or, as #Fraser pointed out above, make sure to point CMAKE_MODULE_PATH to the directory where it is. Not sure, but it could be that CMake checks the current directory as well automatically (where your CMakeLists.txt resides. Anyhow, setting EIGEN3_INCLUDE_DIR is totally unrelated to the location of FindEigen3.cmake
However, it could be that your FindEigen3 script evaluates this variable to determine the location of your Eigen3 installation.
Alternatively, self-built CMake-based projects often provide a <PackageName>Config.cmake. If you point a variable called <PackageName>_DIR to the directory containing this file, you can use FIND_PACKAGE( <PackageName> ...) as normal. See documentation of FIND_PACKAGE for details.
Eigen >= 3.3 has direct CMake integration, so it seems yours isn't set up correctly.
Assume Eigen has been installed to /opt/eigen/3.3 with default settings. Append or prepend the the location /opt/eigen/3.3 to the environment variable CMAKE_PREFIX_PATH e.g in bash:
export CMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH:/opt/eigen/3.3"
Then CMake should pick it up.
If you are writing your own CMakeLists.txt that uses Eigen I suggest using code like this:
find_package (Eigen3 3.3 REQUIRED)
add_executable (example example.cpp)
target_link_libraries (example Eigen3::Eigen)
You should not use include_directories since CMake 3 was released -- the targets approach should be preferred whenever available.
First, make sure Eigen is properly installed. Refer to the INSTALL file that comes with the tarball.
Second, copy the cmake/FindEigen3.cmake file from the tarball to the directory containing your CMakeLists.txt.
In your CMakeLists.txt add:
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR})
find_package(Eigen3 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIR})
Now you should be able to do e.g. #include <Eigen/Core>.
All of this comes (mostly) from this source.
This approach has the advantage over e.g. include_directories("$ENV{EIGEN3_INCLUDE_DIR}") that it the uses CMake's standard mechanism for finding external dependencies, making it easier for someone else (or your future self) to pick up the project, possibly on another platform.
(However, it would be nice if Eigen itself installed an EigenConfig.cmake file, making it accessible through the find_package mechanism without any extra paths.)
I found another solution here (which referred to here) which uses the pkg-config file :
find_package(PkgConfig)
pkg_search_module(Eigen3 REQUIRED eigen3)
As a detailed explanation of the note 7 from the top answer of Johannes. By using the "Config mode" rather than "Module mode" of CMake find_packate(), only writing
find_package( Eigen3 REQUIRED )
include_directories( EIGEN3_INCLUDE_DIR )
in CMakeLists.txt is enough.
Please refer to the INSTALL guidance text file contained in the eigen source code directory (eg. extracted from eigen-3.3.7.tar.gz downloaded from official website), which said:
Method 2. Installing using CMake
********************************
Let's call this directory 'source_dir' (where this INSTALL file is).
Before starting, create another directory which we will call 'build_dir'.
Do:
cd build_dir
cmake source_dir
make install
The "make install" step may require administrator privileges.
You can adjust the installation destination (the "prefix")
by passing the -DCMAKE_INSTALL_PREFIX=myprefix option to cmake, as is
explained in the message that cmake prints at the end.
Just like installing usual CMake projects to your machine.
The difference from directly including the /usr/include/eigne3 or /usr/local/include/eigen3 directory is that, a configuration directory called eigen3/cmake will also be installed to /usr/share or usr/local/share. This configuration directory contains the Eigen3Config.cmake file, which can automatically be found by CMake to locate the eigen3 directory.
If you have not added Eigen Library to environment variable then do the following in CMakeLists.txt:
cmake_minimum_required(VERSION 3.9)
project(ProjectName)
set(CMAKE_CXX_STANDARD 11)
# set EIGEN_DIR variable to Eigen Library Path
set(EIGEN_DIR "C:\\Eigendir\\Eigen")
# include the directory
include_directories(${EIGEN_DIR})
add_executable(ProjectName main.cpp)
target_link_libraries(ProjectName ${EIGEN_DIR})
Another simple way that doesn't require adding an environment variable is to simply find eigen with the cmake find_path function https://cmake.org/cmake/help/v3.6/command/find_path.html. The example code finds the directory "Eigen" in paths "/usr/include/" and "/usr/local/include" with an additional search in subdirectory "eigen3".
find_path(EIGEN3_INCLUDE_DIRS "Eigen" paths "/usr/include" "/usr/local/include" path_suffixes "eigen3")
message(${EIGEN3_INCLUDE_DIRS})
if ( NOT EIGEN3_INCLUDE_DIRS )
message(FATAL_ERROR "CMake variable EIGEN3_INCLUDE_DIRS not found.")
endif()
include_directories ( "${EIGEN3_INCLUDE_DIRS}" )
You could try setting the CMAKE_MODULE_PATH to the location of Eigen subdirectory named "cmake":
cmake . -DCMAKE_MODULE_PATH=<Eigen root dir>/cmake/
I had a similar problem when run cmake .. && make on Google Colab on a project clone from github. I fixed it by editing CMakeLists.txt file and adding this line to it:
set(EIGEN3_INCLUDE_DIR "/usr/include/eigen3")
As you can see, my eigen3 was in /usr/include/eigen3 path (and I had installed it using !sudo apt-get install build-essential cmake libeigen3-dev)
When installing on Kubuntu 20.04 following steps from INSTALL:
Do:
cd build_dir
cmake source_dir
make install
using -DCMAKE_INSTALL_PREFIX=/usr/local/eigen-3.4.0 and sudo
FindEigen3.cmake is not installed. However, using
set(Eigen3_DIR "/usr/local/eigen/share/eigen3/cmake")
seem to work. FindEigen3.cmake is in the build directory
but it is not copied to the installation directory tree.
This worked:
Changed c++11 to c++14
Changed find_package(Eigen3 QUIET) to find_package(Eigen3 CONFIG)
Another simple way is:
if the Eigen library is in /opt/eigen/3.3/Eigen
include_directories(/opt/eigen/3.3)
which is equivalent to what Jai suggested
set(EIGEN_DIR "/opt/eigen/3.3")
include_directories(${EIGEN_DIR})
You need to read official documentation:
Click here
After install Eigen from tar and compile it correctly.
CMakeLists.txt will looks like this:
find_package(Eigen3 3.3 REQUIRED NO_MODULE)
add_executable(${PROJECT_NAME} something.cpp)
target_link_libraries(${PROJECT_NAME} Eigen3::Eigen)
It will be fine work.