I am trying to use Cmake to build a program that uses CGAL. In my CMakeLists.txt file I have this:
find_package(CGAL REQUIRED QUIET COMPONENTS Core)
Running cmake produces this message:
CMake Warning at /usr/local/lib/cmake/CGAL/CGALConfig.cmake:92 (message):
CGAL_DATA_DIR cannot be deduced, set the variable CGAL_DATA_DIR to set the
default value of CGAL::data_file_path()
Call Stack (most recent call first):
CMakeLists.txt:30 (find_package)
I'm not sure what CGAL::data_file_path() is supposed to be and I can't locate it so far in the CGAL documentation. Does anyone know something about this?
If you open the CGAL documentation page and type the text "data_file_path" into the search field in the upper right corner, you'll get:
std::string CGAL::data_file_path (const std::string & filename)
returns the full path of a data file from CGAL.
The data files are located in the data directory of a CGAL release or in the directory Data/data from a git branch checkout. That function uses as prefix the environment variable CGAL_DATA_DIR if set, and the value of the macro CGAL_DATA_DIR otherwise. When using cmake and a standard CGAL setup, linking the target using that function with the target CGAL::Data will automatically set the macro CGAL_DATA_DIR pointing to the data directory of the CGAL version used. The function will attempt to open the file at the returned location and will print a warning message via std::cerr if the file could not be opened.
Also you can find examples of using the data_file_path function in the CGAL examples directory (which is not installed by default AFAIK).
If you don't call this function in your code, then you can ignore the CMake warning you're asking about - that's what I do for a long time. Also you can get rid of this warning, if you set the CGAL_DATA_DIR macro in the CMakeLists.txt, for example:
set(CGAL_DATA_DIR ".")
There are other ways to set this directory prefix as well - via an environment variable CGAL_DATA_DIR, or as an option in the CMake call etc.
Related
I use some libraries that I don't want built as part of every project that uses them. A very understandable example is LLVM, which has 78 static libraries. Even having the cmake code to find and import these in every cmakefile is excessive.
The obvious solution seems to be to use the "include" command, and to factor out relevant chunks of cmake script into *.cmake files, and set up a CMAKE_MODULE_PATH environment variable.
Except it just plain doesn't work. Cmake doesn't find the file I specify in the include command.
On the off-chance, I even tried specifying the path in the environment variable several ways - once with backslashes, once with forward slashes... - and I restarted the command prompt each time and checked that the environment variable was present and correct.
In the cmake manual, it kind of implies that a "file" is different from a "module" - only a module gets the automatic add-the-extension-and-search-the-path treatment. But there is no explanation of what the difference is. I guessed that the missing extension might be enough (as with standard modules) but clearly it isn't.
Searching the manual for "module" isn't much help as the word seems to be overloaded. For example, a module is also a dynamic library loaded using LoadLibrary/dl_open.
Can anyone explain what the difference is between a file and a module in this context, and how I create my own module so that the cmake include command can find and use it?
I'm using cmake 2.8.1 on Windows.
EDIT
I'm pretty confident that the problem here is not understanding how cmake is supposed to work. I think what I should be doing is writing something that find_package can work with.
As things stand though, I'm still some way from being able to answer my own question.
I believe that a CMake 'module' is simply a file that can be used with the find_package directive. That is, when you run find_package(Module), it searches for a file in the MODULE_PATH that is named FindModule.cmake.
That said, if you include a file without the extension, it too will search through your MODULE_PATH for that file.cmake. In a CMake project I'm working on, I have a very similar directory structure as to what you propose.
+ root/
+ CMakeLists.txt
+ cmake/
| + FindMatlab.cmake
| + TestInline.cmake
| + stdint.cmake
+ src/
+ include/
In CMakeLists.txt I have:
set (CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package (Matlab) # runs FindMatlab.cmake
include(TestInline) # defines a macro:
test_inline (CONFIG_C_INLINE)
include(stdint) # simply executes flat CMake code
Perhaps your issue is that you are trying to define the Module path from the environment. Instead, try to simply append to it within the very CMakeList you try to access the modules/files.
I had this same question after reading the CMake include() command documentation. It states:
Load and run CMake code from the file given. [...snip for brevity...] If a module is specified instead of a file, the file with name .cmake is searched first in CMAKE_MODULE_PATH, then in the CMake module directory.
This leaves a lot of interpretation as to what CMake considers a module vs. a file, because a CMake module is a file on the file system after all. So what's the difference?
The CMake source code is the only place I could find the answer. Basically CMake considers the argument to include() to be a file if it looks like an absolute path. This means:
On Linux/Unix
The argument starts with either '/' or '~'
On Windows
The argument's second character is ':' (as in C:)
The argument starts with '\'
CMake assumes anything else that doesn't meet the above criteria is a Module. In which case it appends '.cmake' to the argument and searches the CMAKE_MODULE_PATH for it.
File is CMake listfile, example is CMakeLists.txt. Use following command to get the list of command used in
cmake --help-command-list
Module is a cmake file (*.cmake) which contain cmake commands.
As Matt B. put, the CMAKE_MODULE_PATH is not environment variable of your shell, but cmake variable.
To append your module path to CMAKE_MODULE_PATH
LIST(APPEND CMAKE_MODULE_PATH ${YourPath})
Or if you perfer your modules to be used first
LIST(INSERT CMAKE_MODULE_PATH 0 ${Yourpath})
when using
find_package(OpenSSL MODULE REQUIRED)
I got the following output
-- Found OpenSSL: /usr/local/lib/libcrypto.so (found version "2.0.0")
but when i use
find_package(OpenSSL REQUIRED PATHS /usr/local/lib/libcrypto.so)
I am getting an error.
Could not find a package configuration file provided by "OpenSSL" with any of the following names: OpenSSLConfig.cmake openssl-config.cmake
can anyone explain why this is happening and also is it the coorect way of using the find_package in the config mode.
You are essentially using 2 different behaviors.
# This way is using Basic Signature and Module Mode
# https://cmake.org/cmake/help/latest/command/find_package.html?highlight=find_package#basic-signature-and-module-mode
find_package(OpenSSL MODULE REQUIRED)
"
The command has two modes by which it searches for packages: "Module" mode and "Config" mode. The above signature selects Module mode. If no module is found the command falls back to Config mode, described below. This fall back is disabled if the MODULE option is given.
In Module mode, CMake searches for a file called Find.cmake. The file is first searched in the CMAKE_MODULE_PATH, then among the Find Modules provided by the CMake installation. If the file is found, it is read and processed by CMake. It is responsible for finding the package, checking the version, and producing any needed messages. Some find-modules provide limited or no support for versioning; check the module documentation.
"
So essentially in the first one you are using the FindOpenSLL cmake module.
"https://cmake.org/cmake/help/latest/module/FindOpenSSL.html?highlight=openssl"
Where as in the second one you are saying to not use the module CMake has written for you. So of course it is confused as to where to look for.
How does PROTOBUF_GENERATE_CPP know where to pick up the protoc binary from?
I have compiled protobuf locally and would like to point my CMakeLists.txt to the installed binary ( myfolder/protobuf-install/bin/protoc ) and not the system binary ( /usr/bin/protoc )
Normally for Boost, I would just set the BOOST_ROOT to my installed folder and it will find all the include_directories, libraries, etc.
How should it be done for Protobuf. I dont see any prefix option in the FindProtobuf.cmake.
set( Protobuf_SRC_ROOT_FOLDER "${CMAKE_SOURCE_DIR}/myfolder/")
find_package(Protobuf MODULE REQUIRED)
The error is
file STRINGS file "/usr/include/google/protobuf/stubs/common.h" cannot be read.
Call Stack (most recent call first):
CMakeLists.txt:17 (find_package)
Ofcourse, the above path is in myfolder/ and not in the system folder. But why is protobuf looking for includes in the system path, when I have explicitly declared the root path as myfolder/
Module FindProtobuf.cmake has a nice description of how to hint it with various things. E.g., hinting with executable could be performed with setting Protobuf_PROTOC_EXECUTABLE variable:
The following cache variables are also available to set or use:
...
Protobuf_PROTOC_EXECUTABLE
The protoc compiler
cmake -DProtobuf_PROTOC_EXECUTABLE=myfolder/protobuf-install/bin/protoc
Also, common CMAKE_PREFIX_PATH variable works well, see that question: Hinting Find<name>.cmake Files with a custom directory.
I am trying to compile openimageio(oiio) on Linux but it's a mess since I know almost nothing about cmake. I don't want and I can't install them on my computer directly in the /usr/local/ directory and that's the problem. I successfully compiled dependencies by executing these bash commands in each library directory :
export workingdir=<path_to_my_project>
./configure --prefix=$workingdir/sdks/deploy
make install
And this works fine, my headers are in a include directory and my libraries are in a lib directory.
Here is the structure of my project :
../<path_to_my_project>
/sdks
/build
/oiio
/png # Successfully compiled
/jpeg # Successfully compiled
/zlib # Successfully compiled
/boost # Successfully compiled
/ilmbase # Successfully compiled
/openexr # Successfully compiled
/deploy
/lib # all .a, .la and .so of successfully compiled libraries
/include # all headers of successfully compiled libraries
The problem is that there is no ./configure available in the oiio library directory so I don't know how to set the prefix path, when I execute the make command, I have errors like this :
CMake Error at /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:108 (message):
Could NOT find PNG (missing: PNG_LIBRARY) (found version "1.6.21")
Call Stack (most recent call first):
/usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:315 (_FPHSA_FAILURE_MESSAGE)
/usr/share/cmake/Modules/FindPNG.cmake:105 (find_package_handle_standard_args)
src/libOpenImageIO/CMakeLists.txt:120 (find_package)
So I set variables and it makes no errors but this is not clean and I'm not sure that my libraries are correctly referenced (If I mes up the variable content, it is still working...).
set (PNG_PNG_INCLUDE_DIR "<workingdir>/sdks/deploy/include/libpng16")
set (PNG_LIBRARY_DIR "<workingdir>/sdks/deploy/lib")
Then I tried to create my own FindXXX.cmake files but some don't have a Root variable for the library so anyway I'm not sure if it correctly found the needed files, moreover, it makes errors :
CMake Error at src/cmake/modules/FindPNG.cmake:104 (include):
include could not find load file:
<workingdir>/sdks/build/oiio/src/cmake/modules/FindPackageHandleStandardArgs.cmake
Call Stack (most recent call first):
src/libOpenImageIO/CMakeLists.txt:120 (find_package)
But it finds the cmake file it anyway since other errors are correctly referenced to my file and if I print something in the cmake file it shows up when I run the make command.
Up to know, the command I am running in the oiio directory is make but I would like something that tells to the find_library function to looks other where. I could recall the function with other parameters but I can't use my own FindXXX.cmake files.
In the oiio repository, in the INSTALL file, paragraph line 43, it says to set environment variable for custom libraries, like PNGDIR, but should it point to the deploys directory or the build directory ? And they say to see CMake configuration output, maybe to know what environment variables to set, but I don't know what file they are talking.
I tried so set PNGDIR but it doesn't work, how to know if the variable name should be PNGDIR ? It can also be PNGROOT ?
export PNGDIR=<workingdir>/sdks/deploy # doesn't work
export PNGDIR=<workingdir>/sdks/build/png # doesn't work
It would be nice if someone could help me, I need this library to be compiled to use it, hope someone understood me.
Use CMAKE_PREFIX_PATH to indicate paths where find_library, find_path et al. should have a look (documentation)
Stuff like PNGDIR should no longer be used and is considered legacy that is kept for backwards compatibility. Patches for FindXXX provided by CMake to add XXX_DIR or XXX_ROOT are rejected by the CMake developers.
How do I build a VS2015 x64 project using glew 1.13.0 and CMake 3.4.0?
I prepared a minimal demo that can be found here: https://bitbucket.org/Vertexwahn/cmakedemos/src/2fbbc02b2c0567319d7be070b34391b1ef35048d/GlewDemo/?at=default
CMakeLists.txt:
cmake_minimum_required ( VERSION 2.8)
project ( GlewDemo )
find_package(GLEW REQUIRED)
set ( SRCS main.cpp )
add_executable(GlewDemo ${SRCS})
target_link_libraries(GlewDemo glew32s)
I downloaded the prebuilt binaries from here: http://sourceforge.net/projects/glew/files/glew/1.13.0/glew-1.13.0-win32.zip/download
And set the path of GLEW_INCLUDE_DIR to the corresponding directory ("C:\Users\no68koc\Downloads\glew-1.13.0\include")
But CMake gives me some errors:
CMake Error at C:/Program Files (x86)/CMake/share/cmake-3.4/Modules/FindPackageHandleStandardArgs.cmake:148 (message):
Could NOT find GLEW (missing: GLEW_LIBRARY)
Call Stack (most recent call first):
C:/Program Files (x86)/CMake/share/cmake-3.4/Modules/FindPackageHandleStandardArgs.cmake:388 (_FPHSA_FAILURE_MESSAGE)
C:/Program Files (x86)/CMake/share/cmake-3.4/Modules/FindGLEW.cmake:44 (find_package_handle_standard_args)
CMakeLists.txt:4 (find_package)
Configuring incomplete, errors occurred!
See also "C:/build/vs2015/GlewDemo/CMakeFiles/CMakeOutput.log".
How does it work properly?
Error message
Could NOT find GLEW (missing: GLEW_LIBRARY)
is a standard message generated by FindXXX.cmake script (called via find_package(XXX)), that it is failed to set(deduce) some CMake variables, so whole package is assumed to be not found.
Most of FindXXX.cmake scripts descibes(in the comment), which variables are set by the script for user.
But only several of them describes, how user can help script in case when the script failed to find needed package at all, or if user wants script to find specific package installation instead of default one.
There is no universal approach in helping to the FindXXX.cmake script, in most cases one should analize code of the script for know variables, which can help.
In the given case (with GLEW package) analizing CMake-provided FindGLEW.cmake script reveals, that both find_path() call (which set GLEW_INCLUDE_DIR variable) and find_library() call (which set GLEW_LIBRARY variable) use no hints (HINT or PATH options) for search. But there are standard hints, which are used by both of this commands. One of these hints is ${CMAKE_PREFIX_PATH}/include directory for find_path and similar directory for find_library.
So you can use
list(APPEND CMAKE_PREFIX_PATH "C:\Users\no68koc\Downloads\glew-1.13.0")
for hint to find_library() and find_path() to search under this directory too.
Alternatively, you may set CMAKE_PREFIX_PATH variable in CMake cache either in GUI (e.g. inside Visual Studio) or via command line:
cmake -DCMAKE_PREFIX_PATH:PATH=C:\Users\no68koc\Downloads\glew-1.13.0
(Note, that using list(APPEND ...) instead of set(...) within CMakeLists.txt does not override variable in case it is set in cache too).
You may use another, 3d-party FindGLEW.cmake script
You can download it into your project (e.g., to cmake/FindGLEW.cmake) and issue
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
for tell find_package() to use this script instead of default one.
Given script uses
${GLEW_LOCATION}
directory (and its subdirectories) as hint for searching in find_path() and find_library() (under PATH command's option). So you can set GLEW_LOCATION variable to installation directory:
set(GLEW_LOCATION "C:\Users\no68koc\Downloads\glew-1.13.0")
for make things work. Alternatively(and preferrably), this variable can be set in cache.
Also, given FindGLEW.cmake script uses
$ENV{GLEW_LOCATION}
directory as hint. This means that setting GLEW_LOCATION environment variable will also helps.
CMake cannot locate your GLEW. Thus you have to hint CMake.
Either include GLEW to some place, where CMake looks for components. Installing GLEW comes to mind.
Or you define the variables manually. You already did that for GLEW_INCLUDE_DIR. You have to define GLEW_LIBRARY, too.
It must be the path to the library named glew32, glew, or glew32s. With Unices it should be lib*.so maybe with some additional version numbers. With Windows it should be *.dll or *.lib.