CMake is an open-source, cross-platform family of tools designed to build, test and package software. It is intended to be used in conjunction with the native build environment, which differentiates CMake from many cross-platform systems. CMake is widely used because it allows developers to more easily create, tailor and test software by simplifying some of the most challenging aspects of the process, including system introspection and executing complex builds.
While building with CMake can be fun and rewarding, you may encounter a few obstacles along your path that stall your progress. This webinar will teach you how to interpret CMake errors and explore some of the most common configuration issues you may encounter when trying to build a CMake project. We’ll deliver actionable troubleshooting tips to help you overcome, even avoid, these obstacles.
2. About ICS
2
Established in 1987, Integrated Computer
Solutions, Inc. (ICS) delivers innovative
software solutions with a full suite of
services to accelerate development of
successful next-gen products.
ICS is headquartered outside Boston in
Waltham, Mass. with offices in California,
Canada and Europe. Currently 160 people.
Boston UX is ICS’ design studio,
specializing in intuitive touchscreen and
multimodal interfaces for high-impact
embedded and connected devices.
4. [Optional] Source Path. Contains the CMakeLists.txt. If not provided it will use the current working
directory
1. You want to run some application or library
2. The program is only available as source or not pre-built for your platform
3. Using it will require building it first
4. A CMakeLists.txt file is in the projects root directory
5. Start by running the command below
Let’s Build a CMake Project
4
cmake -S coolproject/ -B build
[Optional] Build Path, if not
provided it will use the current
working directory
5. 1. Read the build related documentation
2. The project may expect a build flag or other option to be set now
3. Writing your own CmakeLists; Set defaults for required variables💡
The Configuration Expects Some Options
5
💡 CmakeLists.txt💡
if(NOT MY_NEEDED_VARIABLE)
set(MY_NEEDED_VARIABLE 4)
endif()
6. THE
PROBLEM
CMake Error at CMakeLists.txt:2 (cmake_minimum_required):
CMake 3.21 or higher is required. You are running version 3.4
6
Your CMake is Too Old
Example error:
9. THE
PROBLEM
Can’t Find a Package
Example error:
CMake Error at src/CMakeLists.txt:10 (find_package):
Could not find a package configuration file provided by "foo" with any of the following
names:
fooConfig.cmake
foo-config.cmake
Add the installation prefix of "foo" to CMAKE_PREFIX_PATH or set
"foo_DIR" to a directory containing one of the above files. If "foo"
provides a separate development package or SDK, be sure it has been
installed.
-- Configuring incomplete, errors occurred!
A required package cannot be found
9
10. THE
SOLUTION
Solution 1
● When building a new project it’s common to not have all
the dependencies installed
● This is the -dev package if your on a debian based system
● For Windows you will need to add the location of the
cmake files to the PATH.
● Is path with foo-config/ fooConfig.cmake / FindFoo in the
prefix or set in the environment ?
Is the dependency installed?
10
11. THE
SOLUTION
Solution 2
● This directory must contain either:
○ A Configuration File for Foo
○ A Find File for Foo
● Foo will now be able to be found
Tell CMake where the package is
11
12. TIPS
If this is our project we might want to consider using PATHS in our find package call
find_package(foo REQUIRED PATHS ~/.local/lib/cmake ~/another/path)
Tip: Can’t Find A Package (our project)
● PATHS will be added to the searched paths
● A PATH should contain either:
○ A Configuration File for Foo
○ A Find File for Foo
● Foo will now be able to be found at configuration
time
Tell CMake where the package is
12
13. THE
PROBLEM
No CMake Files
Example error:
CMake Error at src/CMakeLists.txt:10 (find_package):
Could not find a package configuration file provided by "foo" with any of
the following names:
fooConfig.cmake
foo-config.cmake
Add the installation prefix of "foo" to CMAKE_PREFIX_PATH or set
"foo_DIR" to a directory containing one of the above files. If "foo"
provides a separate development package or SDK, be sure it has been
installed.
-- Configuring incomplete, errors occurred!
No CMake files are shipped to find the package
13
14. THE
SOLUTION
Solution 1
● Many projects include pkgconfig (.pc) files
● We can use them in cmake and they follow the prefix paths rules
● First find_package(PkgConfig REQUIRED)
● Then we can use the pkg_check_modules function to look for pkgconfig
information
○ pkg_check_modules(FOO REQUIRED IMPORTED_TARGET foo)
○ Variables starting with the VarPrefix will be populated with the
pkgconfig provided info FOO_FOUND, FOO_LIBRARIES,
FOO_INCLUDE_DIRS …
○ You can link later with the Alias PkgConfig::FOO
Use Pkg-config info
14
15. THE
SOLUTION
Solution 2
In the previous solution if No PkgConfig Info was found you need to manually set the variables
before using them:
● target_include_directories (target PUBLIC ${FOO_INCLUDE_DIRS})
● target_link_libraries( target PUBLIC ${FOO_LIBRARIES})
💡 Always use variables to store the included path and libraries.
💡 Remember to set default values if possible
Manually set the lib info
15
16. TIPS
Tip: Write a FindFoo.cmake file
You could write you own Findfoo.cmake file to be able to
make a find package call for the library.
● The Find needs to find libraries, includes then expose
them
● Must also set Foo_Found to True
● Include the new file before you call find package.
● Could already exist worth doing a quick search.
Make your own FindFoo.cmake
16
17. LET´S
TRY
AGAIN
Let’s Build with Setting our Foo_Dir
cmake -S . -Bbuild -DFoo_Dir=/home/chris/.local/lib/cmake/Foo
17
Let’s try it again
18. THE
PROBLEM
Can’t Find a Package
Example error:
CMake Error at CMakeLists.txt:61 (find_package):
Found package configuration file:
/path/to/foo/lib/cmake/Foo/FooConfig.cmake
but it set Foo_FOUND to FALSE so package "Foo" is considered to be NOT
FOUND. Reason given by package:
Failed to find required Foo component "Bar".
Expected Config file at
"/path/to/foo/lib/cmake/FooBar/FooBarConfig.cmake"
Exists
…
It says it found it but its not found
18
19. THE
SOLUTION
Solution 1
● This directory must contain sub directories with:
○ A valid Config for the package / component
○ A valid Find module for the package / component
● Foo will now be able to be found Along with its
components.
When you run your configure step add
-DCMAKE_PREFIX_PATH=”${CMAKE_PREFIX_PATH};/path/to/foo/lib/cmake/”
Add the path to your CMake prefix path
19
20. THE
SOLUTION
Solution 1a
● This directory must contain sub directories with:
○ A valid Config for the package / component
○ A valid Find module for the package / component
● Foo will now be able to be found Along with its
components.
If this is our project we might want to consider adding the prefix path from the prior solution to
list of prefix paths.
list(APPEND CMAKE_PREFIX_PATH ~/.local/lib/cmake ~/another/path)
Tell CMake where the package is
20
21. LET´S
TRY
AGAIN
Let’s Build with Setting our CMAKE_PREFIX_PATH
cmake -S . -Bbuild
-DCMAKE_PREFIX_PATH=”${CMAKE_PREFIX_PATH}:/home/chr
is/.local/lib/cmake/Foo”
21
Let’s try it again
22. THE
PROBLEM
No Compatible Version of the Package
Example error:
CMake Error at CMakeLists.txt:101 (find_package):
Could not find a configuration file for package "Foo" that is compatible
with requested version "X.Y.Z".
The following configuration files were considered but not accepted:
/usr/lib/cmake/Foo/FooConfig.cmake, version: A.B.C
/lib/cmake/Foo/FooConfig.cmake, version: A.B.C
-- Configuring incomplete, errors occurred!
A Required package cannot be found
22
23. THE
SOLUTION
● Find and install a version that is compatible with the
thing your building
● This could replace the previous version or not.
Solution 1
Install a compatible version
23
24. THE
SOLUTION
Solution 2
● Try to set the Foo_DIR first
● Foo will now be able to be found
When you run your configure step add
-DFoo_DIR=... Or -DCMAKE_PREFIX_PATH=...
Tell CMake where the package is
24
25. LET´S
TRY
AGAIN
Let’s Build with Setting our Foo_Dir to
cmake -S . -Bbuild -DFoo_Dir=/home/chris/.local/lib/cmake/Foo
25
Let’s try it again
26. THE
PROBLEM
Can’t Find a Package
Example error:
CMake Error at CMakeLists.txt:15 (target_link_libraries):
Target "myTarget" links to:
Foo
but the target was not found. Possible reasons include:
* There is a typo in the target name.
* A find_package call is missing for an IMPORTED target.
* An ALIAS target is missing.
…
Can’t Find Link Target for a library
26
27. THE
SOLUTION
Solution 1
● Is there a find_package call for this library ?
Does a find the package call exist for the library
27
28. THE
SOLUTION
Solution 2
● Finding the correct names for found package libraries can
be done by done by reading the documentation for the
package or looking at other items using this library
● Check the Alias match if the lib says use Zlib::Zlib then you
should use the full alias when linking
Did you find the package Foo and link foo or the incorrect library
name.
Double check the spelling
28
30. THE
PROBLEM
Building installs the package
Example error:
Unable to install files /usr/local/ …..
…
When building an install is attempted to a place I can’t access
30
32. THE
SOLUTION
You can change where CMake tries to install files.
Solution 2
● -DCMAKE_INSTALL_PREFIX=installDirectory
● The install directory will be relative to the CMAKE
SOURCE DIR
Set the install prefix
32
33. THE
SOLUTION
You can change where CMake tries to install files.
Solution 3
● Build using: cmake -- build build --target install
--prefix installDir
● The installDir will be relative to dir you ran cmake
in
Change the prefixDir at build time
33
34. THE
PROBLEM
CMake Can’t Compile a Simple Test Project
Example error:
CMake Error at /usr/share/cmake-3.10/Modules/CMakeTestCCompiler.cmake:52 (message):
The C compiler
"Some compiler path"
is not able to compile a simple test program.
…
Often when you cross compile
34
35. THE
SOLUTION
We can tell cmake to build a dynamic or static library as the test,
When cross compiling we should change it to STATIC_LIBRARY
Solution 1
● Place the line below before any project calls
● set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
Change what it’s trying to build
35
36. THE
SOLUTION
We can tell cmake to skip the compiler tests
Solution 2
● Skip the C test, set(CMAKE_C_COMPILERS_WORKS 1)
● Skip the C++ test, set(CMAKE_CXX_COMPILERS_WORKS 1)
Skip the tests
36
37. THE
SOLUTION
CMake can use toolchain file and others to pre populate some variables
Solution 3
● Check out the settings for the setup in your ide and be sure the items are
correct.
● Check for CmakePreset.json or CMakeUserPresets.json files in the src dir
these can alter cmake variables based upon your os or build setup
● Try building using the CLI this will make it less likely that you have a toolchain
or preset being loaded
Ide is loading a toolchain or setting some variables incorrectly
37