How to navigate in cmakelists.txt? [duplicate] - cmake

This question already has an answer here:
How do I specify relative paths in CMAKE?
(1 answer)
Closed 1 year ago.
I have project dependency packages in the directory
C:/Users/king/my/mytest/dds
mytest contains folders dds, Source, testapp
I use the following in my cmakelists.txt
find_package(Idlpp-cxx REQUIRED PATHS C:/Users/king/my/mytest/dds/Idlpp-cxx)
find_package(CycloneDDS REQUIRED PATHS C:/Users/king/my/mytest/dds/CycloneDDS)
find_package(CycloneDDS-CXX REQUIRED PATHS C:/Users/king/my/mytest/dds/CycloneDDS-CXX)
how can I set them to pick up automatically without hardcoding C:/Users/king/my/mytest/? which will differ from pc to pc....
I do cmake build in this folder
C:/Users/king/my/mytest/testapp
cmaklists.txt file is in
C:/Users/king/my/mytest/Source

New in version 3.12: Search paths specified in the <PackageName>_ROOT CMake variable and the <PackageName>_ROOT environment variable, where <PackageName> is the package to be found.
ref: https://cmake.org/cmake/help/latest/command/find_package.html#search-procedure

CMAKE_CURRENT_SOURCE_DIR can be used to pick any forward directory from the current directory
Idlpp-cxx PATHS ${CMAKE_CURRENT_SOURCE_DIR}/my/mytest/dds/idlpp-cxx)
worked for me

Related

Qt example project fails to build (No CMake configuration found)

I am trying to simply open Qt6.4.1 sensors example project, but it says that no CMake configuration found. I already made some simple Qt6 applications for Windows, and i have entire Qt6.4.1 package installed, so cant blame on bad installation. There is an error on line find_package(Qt6 REQUIRED COMPONENTS Core Gui Quick Sensors Svg) in CMakeLists.txt. Full error message:
C:\Qt\Examples\Qt-6.4.1\sensors\sensorsshowcase\CMakeLists.txt:12: error: By not providing "FindQt6.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "Qt6", but CMake did not find one. Could not find a package configuration file provided by "Qt6" with any of the following names: Qt6Config.cmake qt6-config.cmake Add the installation prefix of "Qt6" to CMAKE_PREFIX_PATH or set "Qt6_DIR" to a directory containing one of the above files. If "Qt6" provides a separate development package or SDK, be sure it has been installed.
Pass the path to the directory containing the Qt6 files via CMAKE_PREFIX_PATH cache variable during configuration.
Note: Make sure to specify the type of the variable as PATH or use forward slashes as path separator for this to work properly.
E.g. for me I'd need to pass
-D CMAKE_PREFIX_PATH=D:/Qt/6.4.1/msvc2019_64
to tell CMake to look into the directory containing the Qt6.4.1 files compiled with MSVC.
Make sure that the directory you pass contains the file lib/cmake/Qt6/Qt6Config.cmake; this is the file find_package(Qt6 REQUIRED COMPONENTS ...) is looking for.
You can also fix your project setup that previously failed by adding the cache variable.
cmake -D CMAKE_PREFIX_PATH=D:/Qt/6.4.1/msvc2019_64 path/to/build_dir
Note: Don't forget to add the -A ... option when configuring a VS project; CMake defaults to Win32 as architecture, at least on my system.
You could add this info to a CMAKE_PREFIX_PATH environment variable, if you don't want to specify the info cache variable for every single project using qt 6 that you want to set up on your machine.

How to determine whether cmake project included via add_subdirectory? [duplicate]

This question already has answers here:
How to detect if current scope has a parent in CMake?
(3 answers)
How can I tell, within a CMakeLists.txt, whether it's used with add_subdirectory()? [duplicate]
(1 answer)
Closed 4 months ago.
I have a small CMake project that encapsulate a small C++ library. For this library, I want to enable almost all available warnings by default while developing it. However, if someone wants to make use of my library and therefore uses add_subdirectory to include my project, I would like to disable warnings for my library.
I know how to disable warnings, but I would like to know how one would go about detecting whether the CMake project is currently processed stand-alone or embedded in another CMake project.
CMake >= v3.21
There's a boolean flag PROJECT_IS_TOP_LEVEL, which seems to indicate exactly this.
For more general querying (not only the current project), there's also <PROJECT-NAME>_IS_TOP_LEVEL.
CMake pre < v3.21
Disclaimer: This answer assumes that project calls always happen in the first processed CMakeLists.txt file that is processed for every project.
The best way to check for this (to my knowledge) would be to test whether the variables CMAKE_SOURCE_DIR and PROJECT_SOURCE_DIR (note: no CMAKE_ prefix) refer to the same path.
From the docs 1, 2:
CMAKE_SOURCE_DIR
The path to the top level of the source tree.
This is the full path to the top level of the current CMake source tree.
PROJECT_SOURCE_DIR
This is the source directory of the last call to the project() command made in the current directory scope or one of its parents. Note, it is not affected by calls to project() made within a child directory scope (i.e. from within a call to add_subdirectory() from the current scope).
So the gist of it is that if the project is built stand-alone, top-level source directory, is the one that contains your own CMakeLists.txt file, which (as is normally the case) contains the project call of your own project. Assuming you don't have multiple project calls in your project (again: as is usually the case), that means that the directory in which the last project call happened (and which does not lie in a sun directory of your current directory, which according to the docs don't count) is the same as the top-level source directory. Therefore, the mentioned variables will refer to the same path.
If, however, your project is embedded in someone else's CMake project, their CMakeLists.txt location will define the top-level source directory. At some point, they will include your project, which starts by its own project call, updating PROJECT_SOURCE_DIR to the path to the directory in which your CMakeLists.txt file lies. Therefore, CMAKE_SOURCE_DIR != PROJECT_SOURCE_DIR.
TL;DR: This is the necessary check
if (CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
message(STATUS "Your project is standalone")
else()
message(STATUS "Your project is embedded")
endif()

CMake add system-wide prefix path [duplicate]

This question already has an answer here:
Hinting Find<name>.cmake Files with a custom directory
(1 answer)
Closed 2 years ago.
I want every CMake project that uses boost (or any other lib) to find it in custom directory, for example /home/someuser/mylibs or C:/mylibs.
To achieve this I may add in CMakeLists.txt following command:
list(APPEND CMAKE_PREFIX_PATH "/home/someuser/mylibs")
This is not very comfortable when I cooperate with different people on different projects. The question is: can I use some environment variable to set it or there's another way to do this?
The usual way is to add -DCMAKE_PREFIX_PATH=/path/to/boost/ when calling CMake to configure your project. But, of course, you can also set an environment variable, e.g. BOOST_DIR and then read it out using CMake:
list(APPEND CMAKE_PREFIX_PATH $ENV{BOOST_DIR})

CMake find_package path to package

Is there a variable that stores the path to the found package similar to the package version?
find_package(name)
message("name version: ${name_VERSION}") #something like this but only for path to package?
If corresponded XXXConfig.cmake file has been found in find_package(XXX) call, then variable XXX_CONFIG contains absolute path to that file.
Also, there is CACHE variable XXX_DIR which contains directory with the file. Because this is a cached variable, its value can be found in CMakeCache.txt file after running cmake.
More about find_package behavior can be found in documentation.

How to set a specific package path for CMakeLists.txt

My colleague wrote a CMakeLists.txt, which contains things as below:
find_package(OpenCV 3 REQUIRED
COMPONENTS
opencv_core
opencv_imgproc
opencv_imgcodecs
CONFIG
)
As the project needs these components of Opencv3, my colleague downloaded the whole Opencv3, of course, it works.
But the whole Opencv3 is too big, so I get only the necessary lib files: libopencv_core.so, libopencv_imgproc.so and libopencv_imgcodecs.so and try to replace the whole Opencv3. The three so files are put here: /opt/opencv3/.
I don't know how to tell the CMakeLists.txt to look for the components of Opencv3 at the specific path instead of the path by default.
I'm totally a newbie on writing CMakeLists.txt...
CMake find_package() finds and configure project dependencies in CMake using two modes of operation, Module and Config, as described in its documentation.
In Module mode (not your case), it looks for a Find<package>.cmake file inside CMAKE_MODULE_PATH. This file searches for header files and libraries and set the necessary CMake variables in case of success.
In your case it is using Config, as requested by the CONFIG keyword. In Config mode CMake looks for for a <name>Config.cmake file or <lowercase-name>-config.cmake.
These config files describe the version of the dependency and the location of header files and library modules.
So you should look for OpenCVConfig.cmake or opencv-config.cmake in CMAKE_PREFIX_PATH or in OpenCV_DIR.
Please note that you have to set(OpenCV_DIR ...) before calling find_package().