How to list variables loaded by pkg-config in cmake - cmake

In Cmake when we do find_package to look up a package, how we can find the list of variables that it loads
for example
some have this format:
.._LIBRARIES
some have this format:
.._LIBS
how we can list the variables and the assigned values in that package?

Related

Why doesn't cmake find_package(VTK) find VTK_INCLUDE_DIRS after building VTK from source and installing?

I’m running cmake version 3.23.0-rc1, on ubuntu 20.04.
I built vtk-8.2 from source; cmake, make, then ‘make install’. Now I am trying to find the VTK package for my own application, using cmake’s find_package(VTK). The application’s CMakeLists.txt contains this:
find_package(VTK)
message("VTK_FOUND: ${VTK_FOUND}")
message("VTK_INCLUDE_DIRS: ${VTK_INCLUDE_DIRS}")
message("VTK_LIBRARIES: ${VTK_LIBRARIES}")
Result is that VTK_FOUND=1, VTK_LIBRARIES contains many entries, but VTK_INCLUDE_DIRS is blank/empty. Why would this be?
I do see file /usr/local/lib/cmake/vtk-8.2, which contains many *.cmake files. But I don’t see a corresponding /usr/local/include/cmake directory, despite the presence of /usr/local/include/vtk-8.2. Is that expected? Here is the output:
VTK_FOUND: 1
VTK_INCLUDE_DIRS:
VTK_LIBRARIES: VTK::WrappingTools;VTK::ViewsQt;VTK::ViewsInfovis;VTK::CommonColor;VTK::ViewsContext2D;VTK::loguru;VTK::TestingRendering;VTK::TestingCore;VTK::vtksys;VTK::RenderingQt;VTK::PythonContext2D;VTK::RenderingVolumeOpenGL2;VTK::RenderingOpenGL2;VTK::glew;VTK::opengl;VTK::PythonInterpreter;VTK::Python;VTK::RenderingLabel;VTK::octree;VTK::RenderingLOD;VTK::RenderingImage;VTK::RenderingContextOpenGL2;VTK::IOVeraOut;VTK::hdf5;VTK::IOTecplotTable;VTK::IOSegY;VTK::IOParallelXML;VTK::IOPLY;VTK::IOOggTheora;VTK::theora;VTK::ogg;VTK::IONetCDF;VTK::netcdf;VTK::IOMotionFX;VTK::pegtl;VTK::IOParallel;VTK::jsoncpp;VTK::IOMINC;VTK::IOLSDyna;VTK::IOInfovis;VTK::libxml2;VTK::zlib;VTK::IOImport;VTK::IOGeometry;VTK::IOVideo;VTK::IOMovie;VTK::IOExportPDF;VTK::libharu;VTK::IOExportGL2PS;VTK::RenderingGL2PSOpenGL2;VTK::gl2ps;VTK::png;VTK::IOExport;VTK::RenderingVtkJS;VTK::RenderingSceneGraph;VTK::IOExodus;VTK::exodusII;VTK::IOEnSight;VTK::IOCityGML;VTK::pugixml;VTK::IOAsynchronous;VTK::IOAMR;VTK::InteractionImage;VTK::ImagingStencil;VTK::ImagingStatistics;VTK::ImagingMorphological;VTK::ImagingMath;VTK::GUISupportQtSQL;VTK::IOSQL;VTK::sqlite;VTK::GUISupportQt;VTK::GeovisCore;VTK::libproj;VTK::InfovisLayout;VTK::ViewsCore;VTK::InteractionWidgets;VTK::RenderingVolume;VTK::RenderingAnnotation;VTK::ImagingHybrid;VTK::ImagingColor;VTK::InteractionStyle;VTK::FiltersTopology;VTK::FiltersSelection;VTK::FiltersSMP;VTK::FiltersPython;VTK::FiltersProgrammable;VTK::FiltersPoints;VTK::FiltersVerdict;VTK::verdict;VTK::FiltersParallelImaging;VTK::FiltersImaging;VTK::ImagingGeneral;VTK::FiltersHyperTree;VTK::FiltersGeneric;VTK::FiltersFlowPaths;VTK::FiltersAMR;VTK::FiltersParallel;VTK::FiltersTexture;VTK::FiltersModeling;VTK::FiltersHybrid;VTK::RenderingUI;VTK::DomainsChemistry;VTK::CommonPython;VTK::WrappingPythonCore;VTK::ChartsCore;VTK::InfovisCore;VTK::FiltersExtraction;VTK::ParallelDIY;VTK::diy2;VTK::IOXML;VTK::IOXMLParser;VTK::expat;VTK::ParallelCore;VTK::IOLegacy;VTK::IOCore;VTK::doubleconversion;VTK::lz4;VTK::lzma;VTK::utf8;VTK::FiltersStatistics;VTK::eigen;VTK::ImagingFourier;VTK::ImagingSources;VTK::IOImage;VTK::DICOMParser;VTK::jpeg;VTK::metaio;VTK::tiff;VTK::RenderingContext2D;VTK::RenderingFreeType;VTK::freetype;VTK::kwiml;VTK::RenderingCore;VTK::FiltersSources;VTK::ImagingCore;VTK::FiltersGeometry;VTK::FiltersGeneral;VTK::CommonComputationalGeometry;VTK::FiltersCore;VTK::CommonExecutionModel;VTK::CommonDataModel;VTK::CommonSystem;VTK::CommonMisc;VTK::CommonTransforms;VTK::CommonMath;VTK::CommonCore
find_package(VTK) no longer sets VTK_INCLUDE_DIRS variable. If you look into description part of vtk-config.cmake (script CMake/vtk-config.cmake.in contains template of that file), then you find no note about VTK_INCLUDE_DIRS.
Since VTK_LIBRARIES variable contains IMPORTED targets (in form of VTK::foo), linking with the content of that variable using target_link_libraries will automatically provide include directories.

Set type PATH for a Semicolon-separated list of directories CMake variable

Is it legit to write
cmake -S. -Bbuild -DCMAKE_LIBRARY_PATH:PATH="path1;path2"
I mean CMAKE_LIBRARY_PATH is a:
Semicolon-separated list of directories specifying a search path for the find_library() command.
So is it ok to flag it as type PATH ?
src: https://cmake.org/cmake/help/latest/variable/CMAKE_LIBRARY_PATH.html
Actually, you don't need to specify the variable's type when running CMake from command line, since the TYPE property defines which widgets a CMake GUI tool uses for that variable:
Widget type for entry in GUIs.
But to answer your question: No, I think it's not OK to use the PATH type in that case, since then the GUI would present you with a file choose dialog, which allows to select only one directory.

Whether the cmake stage can generate source files?

I have such a requirement. I want to modify my source file according to the configuration file in the cmake stage. Is there a good way?
configure_file command is your friend.
First you create a template file filled with strings line ${MY_VAR} (called foo.ext.in by convention) and then pass into as the argument of configure_file. During configuration step, CMake will generate foo.ext file from your template, substituting any ${VARS} with corresponding values from CMake code scope.

CMake: show all modified variables

I would like to have a command or option to list all the modified cache variables of the current build configuration. While cmake -L[AH] is nice, it is also quite overwhelming and doesn't show which are non-default values.
There seems to be a variable property MODIFIED that sounds exactly like what I'm looking for - but the documentation is not very reassuring:
Internal management property. Do not set or get.
This is an internal cache entry property managed by CMake to track interactive user modification of entries. Ignore it.
This question also didn't help: CMAKE: Print out all accessible variables in a script
There are so many ways you could change or initialize variables in CMake (command line, environment variables, script files, etc.) that you won't be able to cover them all.
I just came up with the following script that covers the command line switches. Put the following file in your CMake project's root folder and you get the modified variables printed:
PreLoad.cmake
set(_file "${CMAKE_BINARY_DIR}/UserModifiedVars.txt")
get_directory_property(_vars CACHE_VARIABLES)
list(FIND _vars "CMAKE_BACKWARDS_COMPATIBILITY" _idx)
if (_idx EQUAL -1)
list(REMOVE_ITEM _vars "CMAKE_COMMAND" "CMAKE_CPACK_COMMAND" "CMAKE_CTEST_COMMAND" "CMAKE_ROOT")
file(WRITE "${_file}" "${_vars}")
else()
file(READ "${_file}" _vars)
endif()
foreach(_var IN LISTS _vars)
message(STATUS "User modified ${_var} = ${${_var}}")
endforeach()
This will load before anything else and therefore can relatively easily identify the user modified variables and store them into a file for later reference.
The CMAKE_BACKWARDS_COMPATIBILITY is a cached variable set by CMake at the end of a configuration run and therefor is used here to identify an already configured CMake project.
Reference
CMake: In which Order are Files parsed (Cache, Toolchain, …)?

CMake: collecting libraries

I am using CMake to build a simple C++ project, hereafter named P. The structure of P is quite simple:
P/src/
P/src/package1
P/src/packege2
P/src/...
P/src/main-app
I would like to collect the libraries in package1, package2, ... in a variable called P_LIBS.
In a first attempt, I tried to collect the libraries available in package1, package2, ... in the variable called P_LIBS initially set in the src/CMakeLists.txt file. However, the updates to P_LIBS made in the CMakeLists.txt of the subfolders are not propagated to the parent folder.
I would rather not write a list of libraries in the main CMakeLists.txt file. I would rather modify such variable while moving in the directory tree.
After a search on the internet I could not find any valid suggestion. If I look at the various Find files, I only see long listings of libraries in their main CMakeLists.txt file.
Is there a way to do what (I hope) I explained above?
Thanks to sakra's link I was able to 'propagate' names up to the parent folder. However, the names I add to the P_LIBS variable are later interpreted as 'library' names, not as reference to CMake targets. In other words, if
P_LIBS = {a, b}
the 'a' and 'b' are interpreted as the library names, i.e. CMake generates:
gcc [...] -l a -o exe
instead of
gcc [...] /path/to/a.o -o exe
(.o or other extensions)
You are propably constructing the targets list as a string, try to make them a list instead. For example:
# in package1/CMakeLists.txt
set(P_LIBS ${P_LIBS} a b PARENT_SCOPE)