📖
Wiki
Back to my personal website
  • Home
  • Equipment and Devices
    • 3D Printer
    • Laser Cutter
    • Motion Capture System
    • Sensors
      • RGB-D Cameras
      • Velodyne LiDAR
      • Zed Camera
      • RealSense D435i
      • IMU
    • eGPU
    • Nvidia AGX Xavier
    • CPU Benchmark
    • Installation Checklist
  • Development
    • Linux
      • Shell
      • GDB
      • Git
      • Tmux
      • Network
      • Tricks
      • Debug FAQ
    • CMake
      • Catkin Tools
      • CMakeLists
      • CMake Variables
      • CMake Commands
      • CMake: find_package()
    • ROS
      • Gazebo
      • wstool
      • roslaunch
      • rosbag
      • multi-threaded spinner
    • ROS2
      • Convert ROS1 bag to ROS2 bag
    • C++
      • C++ 11
      • C++ Examples
      • C++ Debug
      • Factory Method
      • Timing
    • Google Tools
      • GLog
      • GFlags
      • GTest
      • Style Guide
      • Clang Format
    • PCL
      • Point Type
      • Methods
      • Architecture
      • Code Explained
    • Open3D
      • Python API
      • Registration
      • Visualization
      • Tools
    • OpenCV
      • Documentation
      • Modules
    • Other Libraries
      • Eigen
      • Ceres
      • g2o
      • GTSAM
    • Website
  • Algorithm
    • SLAM
      • K-D Tree
      • Octree
      • Bag of Words
      • Distance Measures
      • Coordinate Systems
      • LOAM
      • Iterative Closest Point
      • Generalized ICP
      • Mahalanobis Distance
    • Computer Science
      • Computational Model
      • Sorting
      • Analysis
      • Complexity Classes (P, NP)
      • Divide and Conquer
      • Greedy Algorithm
      • Dynamic Programming
      • Tree
      • Graph
    • Computer Vision
      • Camera Models
      • Distortion
      • Motion Models
      • Shutter
      • Image Sensors
      • Epipolar Geometry
      • Multiple-View Geometry
    • Datasets
      • RGB-D Datasets
      • Point Cloud Datasets
      • LiDAR SLAM Datasets
  • Math
    • Optimization
      • Convex Optimization
      • Descent Methods
    • Probability
      • Moment
      • Covariance Matrix
      • Stochastic Process
    • Topology
      • References
      • Concepts
      • Topological Spaces
      • Representation of Rotations
      • Representation of 3-sphere
    • Algebra
      • Linear Algebra
      • Matrix Factorization
      • Condition Number
      • Matrix Lie Group
    • Differential Geometry
      • Manifold
      • Submanifold
      • Quotient Manifolds
      • Tangent Space
  • Quadrotor
    • PX4 Development
    • Companion Computer
    • Drone Hardware
    • Propeller Lock
    • Debug
  • Favorites
    • Bookmarks
Powered by GitBook
On this page
  • What You Should Know & Your Actions
  • More Technical Details
  • Module mode
  • Config mode
  • References
  • Commands
  • Actions Needed After A Package Is Found

Was this helpful?

  1. Development
  2. CMake

CMake: find_package()

What You Should Know & Your Actions

When we need to add an external project as the dependency, we will use command find_package in CMakeLists.txt to let CMake know where the header files and libraries are located, such that they can be found and linked properly later on.

It is ideal that the developer of the external project provides a <package>Config.cmake file (or a <lower-case-name>-config.cmake file) for us/users, and this file will be cached into database (in the default installation path) after we sudo make install this external project. You can check if they are available by the locate command.

# example commands
locate OpenCVConfig.cmake
locate gflags-config.cmake

# the results (if available)
/usr/share/OpenCV/OpenCVConfig.cmake
/usr/lib/x86_64-linux-gnu/cmake/gflags/gflags-config.cmake

If they are available, you only need to write one single line in the CMakeLists.txt file. For example,

find_package(PCL)   # it will work given that PCLConfig.cmake is available

Unfortunately, there are certain packages that do not provide (they should!) this CMake configuration file (or the files are not adopted by Ubuntu/apt). In this case, we need to use Find<package>.cmake file instead to locate this external project. We can write it on our own, but it is often the case that someone has done it before. So go ahead and find an available one to use.

After you find a good Find<package>.cmake file, we often place it under a folder named cmake or cmake-modules in the root directory of the current project (in parallel to include, src, etc.), and then add the path to this folder to a CMake variable CMAKE_MODULE_PATH (which is empty by default). With this setup, CMake will be able to look for your customized Find<package>.cmake file according to this CMake module path. What you need to do in CMakeLists.txt file is the following two lines of code.

list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake-modules")
find_package(Glog) # works given that FindGlog.cmake is placed under cmake-modules

Summary

  • The CMake command find_package has two modes (Config mode and Module mode) to find and load the CMake configuration of an external project.

  • In Config mode, it will look for a <package>Config.cmake or<lower-case-name>-config.cmake file in the default install path in Ubuntu system.

  • In Module mode, it will look for a Find<package>.cmake file in the path specified by variable CMAKE_MODULE_PATH ; this variable is empty unless set by user.

  • Module mode has higher priority than Config mode, which means that you can overwrite the default Config file by providing your own FindXXX file.

More Technical Details

Module mode

  • It will look for a file called Find<package>.cmake, first in CMAKE_MODULE_PATH (empty by default), and then under cmake installation path <CMAKE_ROOT>/Modules (e.g., /usr/share/cmake-3.5/Modules). Some example default modules include FindCUDA.cmake or FindOpenGL.cmake.

  • Therefore, to add our own cmake modules or overwrite system cmake modules, we can add Find<package>.cmake files in a folder called cmake and do the following in CMakeLists.txt, to make the best use of CMAKE_MODULE_PATH.

  • list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")

Config mode

  • It will look for a file called <package>Config.cmake or <lower-case-name>-config.cmake under CMAKE_INSTALL_PREFIX (default to /usr/local). These cmake files are installed when we do sudo make install for 3rd party libraries. Examples are as follows (excerpts from command output).

  • -- Installing: /usr/local/share/OpenCV/OpenCVConfig.cmake
    -- Up-to-date: /usr/local/share/sophus/cmake/SophusConfig.cmake
    -- Up-to-date: /usr/local/lib/cmake/Ceres/CeresConfig.cmake
    -- Up-to-date: /usr/local/lib/cmake/g2o/g2oConfig.cmake
    -- Up-to-date: /usr/local/lib/cmake/GTest/GTestConfig.cmake
    -- Up-to-date: /usr/local/lib/cmake/DBoW3/DBoW3Config.cmake
    -- Up-to-date: /usr/local/lib/cmake/Pangolin/PangolinConfig.cmake

References

Commands

Commonly used commands to figure out where packages are installed.

  • dpkg -L <package-name>

  • apt list <package-name>

  • locate <package>Config.cmake

To set flags

  • set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

  • set(CMAKE_BUILD_TYPE RelWithDebInfo)

  • cmake -DCMAKE_BUILD_TYPE=Debug

Note that all names marked by <xxx> should be replaced by their actual file names or package names. Case sensitive!

Actions Needed After A Package Is Found

In general, once a package is found, a new variable <package>_FOUND will be generated and set to true. Also, there will be a few more variables loaded into the compilation process, such as <package>_INCLUDE_DIR , <package>_INCLUDE_DIRS, <package>_LIBRARIES, <package>_LIBS. Then you can use them to let CMake know where to look for header files and libraries. For example,

find_package(Glog REQUIRED) # REQUIRED: will stop compilation if package is missing
include_directories(${GLOG_INCLUDE_DIRS})

add_executable (main src/main.cpp)
target_link_libraries (main ${GLOG_LIBRARIES})

Note that different projects may adopt different variable names. You need to make sure the spelling is completely correct. (Should it be LIBRARIES or LIBS?)

Typically, the variable names are expected to be documented in the official documentation of this external project. (They should!) If not, you will need to dig into <lower-case-name>-config.cmake or <package>Config.cmake or Find<package>.cmake files, which is where they are defined.

PreviousCMake CommandsNextROS

Last updated 3 years ago

Was this helpful?

According to and , find_package() has two modes: "Module" mode and "Config" mode. If no module is found and the MODULE option is not given, the command proceeds to Config mode.

the official documentation
this stackoverflow answer
stackoverflow: two modes in find_package
stackoverflow: could not find a package configuration error