How to create proper Find***.cmake file - cmake

I wrote a simple Find***.cmake file for my project which works fine on Windows,
if(WIN32)
find_path(Shaderc_INCLUDE_DIR
NAMES shaderc/shaderc.hpp
PATH "$ENV{VULKAN_SDK}/Include")
find_library(Shaderc_LIBRARY
NAMES shaderc_combined
PATH "$ENV{VULKAN_SDK}/Lib")
elseif(UNIX)
find_path(Shaderc_INCLUDE_DIR
NAMES shaderc/shaderc.hpp
PATH "$ENV{SHADERC_DIR}/include")
find_library(Shaderc_LIBRARY
NAMES libshaderc_combined
PATH "$ENV{SHADERC_DIR}/lib")
endif()
set(Shaderc_INCLUDE_DIRS ${Shaderc_INCLUDE_DIR})
set(Shaderc_LIBRARIES ${Shaderc_LIBRARY})
, but throws an error on Linux. The error message is:
CMake Error: The following variables are used in this project, but
they are set to NOTFOUND. Please set them or make sure they are set
and tested correctly in the CMake files: Shaderc_LIBRARY
If I copy this code to my main CMakeLists file it compiles fine on Linux as well. What I'm doing wrong? Is it a bad practice to use environment variables on Linux for this purpose?
Thanks for your help!

Well, judging from the code, your module looks in directories specified by environmental variables.
Instead, you should make it search in well-known places, like /usr/lib or /usr/local/lib.

Related

CMake output path for compile pdb files

I'm trying to specify the output path for program database (pdb) files of static libraries in CMake. I think CMake calls them compile pdbs, as opposed to linker pdbs.
From CMake's documentation I found out that I can specify the pdb output directory by COMPILE_PDB_OUTPUT_DIRECTORY. That works as expected. I can also specify the name of the pdb file by COMPILE_PDB_NAME. That also works as expected. However, I am getting an extraneous configuration string appended between the directory and the name, which does not seem to be controlled by either of the previous two. That is, the final output path is of the form C:\mypdboutputpath\RelWithDebInfo\mypdbname.pdb, where RelWithDebInfo corresponds to the current configuration. However, my outputpath already contains my own configuration specifier (my library output directory is of the form lib\msvc64-relwithdebinfo). I've been trying to set both global and target-specific pdb-names and directories, but they do not affect whether the configuration-string is appended or not.
How to get rid of the appended configuration string in the pdb output path?
Although Visual Studio is multi-configuration, my approach is to use CMake as if it were single-configuration, i.e. the configuration is chosen when running CMake.
What helped me was setting the property COMPILE_PDB_OUTPUT_DIRECTORY_${CFG} instead of COMPILE_PDB_OUTPUT_DIRECTORY. For your example, it would probably be COMPILE_PDB_OUTPUT_DIRECTORY_RELWITHDEBINFO.
I didn't find anything about that in the CMake docs, but since the same thing works for the LIBRARY_OUTPUT_DIRECTORY property.
The CMake docs specifically mention this behavior for this property, so I thought it was worth it to try it with COMPILE_PDB_OUTPUT_DIRECTORY as well, and it did work. Hopefully it's not some undefined behavior that will change in the future. FWIW I tested it with CMake 3.18.1
Probably too late for the OP, but perhaps it may help some other poor soul like me.

Forcing a particular MPI compiler with CMake

I want to set a particular MPI compiler (mpiifort) with CMake. Well, not the compiler, but get the libraries and include directories from it. But there is also mpif90 in the path, which uses gfortran under the hood, and has a different set of include dirs and libraries. It seems the FindMPI module in CMake insists on locating mpif90 first and therefore sets the wrong paths.
I've tried setting MPI_Fortran_COMPILER=mpiifort in the command line, or setting FC=mpiifort, but none works. So far the only workaround I've found is creating a symlink mpif90 -> mpiifort in the current directory and adding _MPI_PREFIX_PATH=.. Any other ideas?
EDIT: I had tried the environment variable MPI_Fortran_COMPILER, but I had to set the CMake variable instead. So this worked:
FC=ifort CC=icc cmake -D MPI_Fortran_COMPILER=mpiifort ...
According to the source here, if setting MPI_Fortran_COMPILER does not work, then you could simply set MPI_Fortran_LIBRARIES and MPI_Fortran_INCLUDE_PATH.

CPack NSIS, generate installer for Windows

I´m trying to run packet generator within a VS project, it crashes while compiling because of the use of absolute path on installation from Targets and Files.
ABSOLUTE path INSTALL DESTINATION forbidden (by caller): ...
I checked twice and all installation directories are relative. I set quite a lot of variables as sub-folders of ${PROJECT_BINARY_DIR} (which should be relative) such as:
set(INSTALL_DIR ${PROJECT_BINARY_DIR}/bin)
set(LIB_DIR ${PROJECT_BINARY_DIR}/bin/lib)
set(EXT_DIR ${PROJECT_BINARY_DIR}/bin/ext)
...
does CMAKE/CPACK interpret those variables as absolute paths?
If so, is there a way to make CPack working properly with those variables?
How do I use CPack when sub-relative path are involved?
thanks
Ok I see, the ${PROJECT_BINARY_DIR} is interpreted as an ABSOLUTE path, from there all sub-folder of it will be rejected.
To avoid this problem I surrounded the install variables in if else blocks, and if it is the case of packaging then a relative folder will be used as follows:
if(PACK)
set(INSTALL_DIR bin)
set(LIB_DIR bin/lib)
set(EXT_DIR /bin/ext)
...
else(PACK)
set(INSTALL_DIR ${PROJECT_BINARY_DIR}/bin)
set(LIB_DIR ${PROJECT_BINARY_DIR}/bin/lib)
set(EXT_DIR ${PROJECT_BINARY_DIR}/bin/ext)
...
endif(PACK)
this solves it, but it is really dirty, waiting for a better function on new CPack version.
ciao
This fatal error is meant to tell you installation root should be specified at the moment when user executes the installer. I guess somewhere in your cmake config might have code like this:
INSTALL (TARGET myApp DESTINATION ${SOME_INSTALL_PATH}/bin )
If you assign SOME_INSTALL_PATH an absolute path when cmake cache is generated, you incur the CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION error, which gave you the "ABSOLUTE path INSTALL DESTINATION forbidden (by caller)" message.
To solve this problem, either always use relative path for installation DESTINATION or assign only package prefix to SOME_INSTALL_PATH variable.
For reference, following is the link to INSTALL command.
http://www.cmake.org/cmake/help/v3.0/variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.html
There was also a similar question asked on the CMake mailing list.
http://public.kitware.com/pipermail/cmake/2013-May/054656.html

Installed library cannot be found by CMake

I have the following problem when running CMake.
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
DIRECTFB_INCLUDE_DIR (ADVANCED)
used as include directory in directory /u/menie482/workspace/AtariTEXPLORE
used as include directory in directory /u/menie482/workspace/AtariTEXPLORE/rl_common
used as include directory in directory /u/menie482/workspace/AtariTEXPLORE/rl_agent
used as include directory in directory /u/menie482/workspace/AtariTEXPLORE/rl_env
DIRECTFB_LIBRARY (ADVANCED)
linked by target "experiment" in directory /u/menie482/workspace/AtariTEXPLORE
Actually, I have checked that the DirectFB is already installed when running
locate libdirectfb
So, what shall I do to let CMake know where DIrectFB is? An inconvenient constraint is that I cannot do sudo on this machine..
Thanks!
I guess, you are trying to use something like find_package(directfb) in your CMakeLists.txt file. That can only run if you have /usr/share/cmake/Modules/directfb.cmake (Ubuntu 12.04).
My second guess is you are using something like pkg_module(directfb) in your CMakeLists.txt file. That can only run if you have directfb.pc somewhere.
Otherwise
Where are you setting the variables DIRECTFB_INCLUDE_DIR and DIRECTFB_LIBRARY.
As an alternate step, try using find_library(). You will have to give exact path of libdirectfb.so and do something like
find_library(DIRECT_FB NAMES directfb PATHS path/directfb.so )
target_link_libraries( MyLibraryOrMyExecutable ${DIRECT_FB} )

Cmake cannot find environment variable

I'm building OpenHEVC (https://github.com/OpenHEVC/openHEVC) with cmake on windows 7 to a VS2010 project.
In the CMakeLists.txt at the root directory, I find the line:
include_directories(. ${SDL_INCLUDE_DIR} wrapper_hm/src/Lib)
The "${SDL_INCLUDE_DIR}" I think should be the SDL library(http://www.libsdl.org/download-1.2.php).
My problem is, after downloading SDL library and setting up a new environment variable called "SDL_INCLUDE_DIR" Containing SDL's path (I can "echo %SDL_INCLUDE_DIR%" in a commandline). CMake just keeps giving me this (even after restart Cmake):
'''
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
SDL_INCLUDE_DIR
used as include directory in directory C:/Users/Administrator/Desktop/Pure265/openHEVC-master/openHEVC-master
used as include directory in directory C:/Users/Administrator/Desktop/Pure265/openHEVC-master/openHEVC-master/wrapper_hm
Configuring incomplete, errors occurred!
'''
I'm confused why cmake can't find the environment variable.
(
I'm new to Cmake, But I checked it here : http://www.cmake.org/Wiki/CMake_Useful_Variables
That ${SDL_INCLUDE_DIR} should be reflected to the env variables.
)
${SDL_INCLUDE_DIR} is not an environment variable. It is simply a CMake variable that probably gets set in FindSDL.cmake script. You can see that because environment variables have $ENV{variable_name} sintax.
You should install a development version of SDL library. If you look into FindSDL.cmake script you will see where the script searches for header and lib files. As far as I can tell you have to set SDLDIR environment variable to point to the root folder of SDL library.