CMake find_package for C++ | Boost, OpenSSL, pkg-config & Custom Find Modules
이 글의 핵심
Use find_package to locate libraries portably: versions, components, CONFIG vs MODULE, and production patterns for optional dependencies.
What is find_package? why you need it
Problem Scenario: External Library Link Hell
Problem: I’m trying to use the Boost library. The header path is /usr/include/boost and the library is /usr/lib/libboost_filesystem.so. However, on macOS, it is installed with Homebrew and is located in /opt/homebrew/include, and on Windows, it is located in C:\boost. Hardcoding paths for each platform makes maintenance impossible.
Solution: find_package automatically finds libraries installed on your system and provides header path, library path, and version information. Just use find_package(Boost REQUIRED) and CMake will automatically find it and create a target such as Boost::filesystem.
flowchart LR
subgraph find["find_package(Boost)"]
search["Search system path"]
end
subgraph system["system"]
linux["/usr/lib/libboost*.so"]
mac["/opt/homebrew/lib"]
win["C:/boost/lib"]
end
subgraph result["Result"]
target["Create Boost filesystem target"]
vars["Boost_FOUND, Boost_VERSION variables"]
end
search --> linux
search --> mac
search --> win
linux --> target
mac --> target
win --> target
search --> vars
index
- Basic usage
- Main library examples
- Config vs Module mode
- Write a custom FindModule
- Frequently occurring problems and solutions
- Production Patterns
- Complete example: Multi-library integration
1. Basic usage
Required packages
find_package(Boost REQUIRED)
if(Boost_FOUND)
message(STATUS "Boost found: ${Boost_VERSION}")
else()
message(FATAL_ERROR "Boost not found")
endif()
Optional packages
find_package(SomeLib)
if(SomeLib_FOUND)
target_link_libraries(myapp PRIVATE SomeLib::SomeLib)
else()
message(WARNING "SomeLib not found, using fallback")
endif()
Specify version
# minimum version
find_package(Boost 1.70 REQUIRED)
# exact version
find_package(Boost 1.75 EXACT REQUIRED)
# Version range (CMake 3.19+)
find_package(Boost 1.70...1.80 REQUIRED)
Specify component
find_package(Boost REQUIRED COMPONENTS
filesystem
system
thread
)
target_link_libraries(myapp PRIVATE
Boost::filesystem
Boost::system
Boost::thread
)
2. Main library examples
Boost
find_package(Boost 1.70 REQUIRED COMPONENTS filesystem system)
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE
Boost::filesystem
Boost::system
)
OpenSSL
find_package(OpenSSL REQUIRED)
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE
OpenSSL::SSL
OpenSSL::Crypto
)
Qt5
find_package(Qt5 REQUIRED COMPONENTS Core Widgets)
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE
Qt5::Core
Qt5::Widgets
)
# Autorun Qt MOC
set_target_properties(myapp PROPERTIES
AUTOMOC ON
AUTOUIC ON
AUTORCC ON
)
Google Test
find_package(GTest REQUIRED)
add_executable(tests test.cpp)
target_link_libraries(tests PRIVATE
GTest::gtest
GTest::gtest_main
)
OpenCV
find_package(OpenCV REQUIRED)
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE ${OpenCV_LIBS})
target_include_directories(myapp PRIVATE ${OpenCV_INCLUDE_DIRS})
Using pkg-config
find_package(PkgConfig REQUIRED)
pkg_check_modules(CURL REQUIRED libcurl)
pkg_check_modules(SQLITE REQUIRED sqlite3)
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE
${CURL_LIBRARIES}
${SQLITE_LIBRARIES}
)
target_include_directories(myapp PRIVATE
${CURL_INCLUDE_DIRS}
${SQLITE_INCLUDE_DIRS}
)
3. Config vs Module mode
Config mode (recommended)
This is if the library provides a SomeLibConfig.cmake or somelib-config.cmake file. Most modern libraries provide Config files.
find_package(fmt REQUIRED)
# If fmt provides fmtConfig.cmake, it will be found automatically.
target_link_libraries(myapp PRIVATE fmt::fmt)
Browse Path:
<prefix>/lib/cmake/<name>/<prefix>/share/<name>/- Path specified in
CMAKE_PREFIX_PATH
Module mode
This is the case when using the Find<Name>.cmake module provided by CMake.
find_package(CURL REQUIRED)
# Use CMake's FindCURL.cmake module
target_link_libraries(myapp PRIVATE CURL::libcurl)
Browse Path:
CMAKE_MODULE_PATH- CMake built-in module path
Select mode
# Config mode only
find_package(SomeLib CONFIG REQUIRED)
# Module mode only
find_package(SomeLib MODULE REQUIRED)
# Automatic (Config first, if not, Module)
find_package(SomeLib REQUIRED)
4. Writing a custom FindModule
FindMyLib.cmake example
# cmake/FindMyLib.cmake
# Find header
find_path(MyLib_INCLUDE_DIR
NAMES mylib/mylib.h
PATHS /usr/include /usr/local/include
)
# Find library
find_library(MyLib_LIBRARY
NAMES mylib
PATHS /usr/lib /usr/local/lib
)
# Check version (optional)
if(MyLib_INCLUDE_DIR)
file(READ "${MyLib_INCLUDE_DIR}/mylib/version.h" VERSION_CONTENT)
string(REGEX MATCH "MYLIB_VERSION \"([0-9.]+)\"" _ "${VERSION_CONTENT}")
set(MyLib_VERSION ${CMAKE_MATCH_1})
endif()
# Process results
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MyLib
REQUIRED_VARS MyLib_LIBRARY MyLib_INCLUDE_DIR
VERSION_VAR MyLib_VERSION
)
# Create target
if(MyLib_FOUND AND NOT TARGET MyLib::MyLib)
add_library(MyLib::MyLib UNKNOWN IMPORTED)
set_target_properties(MyLib::MyLib PROPERTIES
IMPORTED_LOCATION "${MyLib_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${MyLib_INCLUDE_DIR}"
)
endif()
use
# CMakeLists.txt
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
find_package(MyLib REQUIRED)
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE MyLib::MyLib)
5. Frequently occurring problems and solutions
Problem 1: Could not find package
Symptom: CMake Error: Could not find a package configuration file provided by "SomeLib".
Cause: The library is not installed or is in a location that CMake cannot find.
# Solution 1: Install package
sudo apt install libboost-dev # Linux
brew install boost # macOS
vcpkg install boost # vcpkg
# Solution 2: Specify CMAKE_PREFIX_PATH
cmake -DCMAKE_PREFIX_PATH=/custom/install/path ..
# Solution 3: Environment variables
export CMAKE_PREFIX_PATH=/usr/local:$CMAKE_PREFIX_PATH
cmake ..
# Solution 4: Package-specific hint variables
cmake -DBoost_ROOT=/usr/local/boost ..
Issue 2: Version mismatch
Symptom: Could not find a configuration file for package "Boost" that is compatible with requested version "1.80".
Cause: The installed version is lower than the required version.
# Solution 1: Relax version requirements
find_package(Boost 1.70 REQUIRED) # 1.80 → 1.70
# Solution 2: Conditional after version check
find_package(Boost 1.70)
if(Boost_VERSION VERSION_LESS 1.80)
message(WARNING "Boost 1.80+ recommended, found ${Boost_VERSION}")
endif()
Issue 3: Missing components
Symptom: Unable to find the requested Boost libraries. Boost component "filesystem" not found.
Cause: Component not installed.
# Linux
sudo apt install libboost-filesystem-dev
# macOS
brew install boost
# Windows (vcpkg)
vcpkg install boost-filesystem
Problem 4: Config vs Module confusion
Symptom: find_package succeeds, but target is not created.
Cause: Searched in Module mode, but the variable name is different.
# Module mode (FindCURL.cmake)
find_package(CURL REQUIRED)
# Variables: CURL_INCLUDE_DIRS, CURL_LIBRARIES
target_include_directories(myapp PRIVATE ${CURL_INCLUDE_DIRS})
target_link_libraries(myapp PRIVATE ${CURL_LIBRARIES})
# Config mode (CURLConfig.cmake)
find_package(CURL REQUIRED)
# Target: CURL::libcurl
target_link_libraries(myapp PRIVATE CURL::libcurl)
Issue 5: Multiple versions installed
Symptom: Wrong version selected.
# Specify a specific version path
cmake -DBoost_ROOT=/usr/local/boost-1.80 ..
# Or add priority path to CMAKE_PREFIX_PATH
cmake -DCMAKE_PREFIX_PATH="/usr/local/boost-1.80;/usr/local" ..
6. production pattern
Pattern 1: Optional dependencies
option(USE_OPENSSL "Use OpenSSL for encryption" ON)
if(USE_OPENSSL)
find_package(OpenSSL)
if(OpenSSL_FOUND)
target_link_libraries(myapp PRIVATE OpenSSL::SSL)
target_compile_definitions(myapp PRIVATE USE_OPENSSL)
else()
message(WARNING "OpenSSL not found, using fallback")
endif()
endif()
Pattern 2: Version checking and feature branching
find_package(Boost 1.70 REQUIRED COMPONENTS filesystem)
if(Boost_VERSION VERSION_GREATER_EQUAL 1.75)
message(STATUS "Using Boost 1.75+ features")
target_compile_definitions(myapp PRIVATE BOOST_NEW_API)
endif()
Pattern 3: Select one of several packages
# OpenSSL first, if not mbedTLS
find_package(OpenSSL)
if(OpenSSL_FOUND)
target_link_libraries(myapp PRIVATE OpenSSL::SSL)
target_compile_definitions(myapp PRIVATE USE_OPENSSL)
else()
find_package(mbedTLS REQUIRED)
target_link_libraries(myapp PRIVATE mbedTLS::mbedtls)
target_compile_definitions(myapp PRIVATE USE_MBEDTLS)
endif()
Pattern 4: Print package information
find_package(Boost REQUIRED COMPONENTS filesystem)
message(STATUS "Boost version: ${Boost_VERSION}")
message(STATUS "Boost include: ${Boost_INCLUDE_DIRS}")
message(STATUS "Boost libraries: ${Boost_LIBRARIES}")
Pattern 5: Custom navigation path
# Add project local FindModule path
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
# custom prefix path
list(APPEND CMAKE_PREFIX_PATH "/opt/mylibs")
find_package(MyLib REQUIRED)
7. Complete example: multi-library integration
Project: HTTP Server (Boost + OpenSSL + spdlog)
cmake_minimum_required(VERSION 3.20)
project(HttpServer VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Required packages
find_package(Boost 1.70 REQUIRED COMPONENTS
system
thread
filesystem
)
find_package(OpenSSL REQUIRED)
# Optional package
find_package(spdlog)
# executable file
add_executable(http_server
src/main.cpp
src/server.cpp
src/request_handler.cpp
)
# link
target_link_libraries(http_server PRIVATE
Boost::system
Boost::thread
Boost::filesystem
OpenSSL::SSL
OpenSSL::Crypto
)
# Use spdlog if available
if(spdlog_FOUND)
target_link_libraries(http_server PRIVATE spdlog::spdlog)
target_compile_definitions(http_server PRIVATE USE_SPDLOG)
else()
message(WARNING "spdlog not found, using std::cout")
endif()
# header path
target_include_directories(http_server PRIVATE
${CMAKE_SOURCE_DIR}/include
)
main.cpp
#include <boost/asio.hpp>
#include <openssl/ssl.h>
#ifdef USE_SPDLOG
#include <spdlog/spdlog.h>
#define LOG(msg) spdlog::info(msg)
#else
#include <iostream>
#define LOG(msg) std::cout << msg << '\n'
#endif
int main() {
LOG("HTTP Server starting...");
boost::asio::io_context io;
// Server logic...
return 0;
}
Package-specific variable names
| package | target | Variable (Module mode) |
|---|---|---|
| Boost | Boost::filesystem | Boost_FOUND, Boost_INCLUDE_DIRS, Boost_LIBRARIES |
| OpenSSL | OpenSSL::SSL, OpenSSL::Crypto | OPENSSL_FOUND, OPENSSL_INCLUDE_DIR, OPENSSL_LIBRARIES |
| CURL | CURL::libcurl | CURL_FOUND, CURL_INCLUDE_DIRS, CURL_LIBRARIES |
| ZLIB | ZLIB::ZLIB | ZLIB_FOUND, ZLIB_INCLUDE_DIRS, ZLIB_LIBRARIES |
| GTest | GTest::gtest, GTest::gtest_main | GTEST_FOUND, GTEST_INCLUDE_DIRS, GTEST_LIBRARIES |
Recommended: Use target (Boost::filesystem) whenever possible. It is more type safe than variables, and PUBLIC/PRIVATE propagation is automatic.
organize
| concept | Description |
|---|---|
| find_package | Automatic discovery of external libraries |
| REQUIRED | Required packages (error if missing) |
| COMPONENTS | Specifying library components |
| Config Mode | Use <Name>Config.cmake (recommended) |
| Module mode | Using Find<Name>.cmake |
| Target | Boost::filesystem format (recommended) |
| Variable | Boost_LIBRARIES format (legacy) |
find_package is a core feature of CMake that allows you to find and link external libraries platform-independent.
FAQ
Q1: find_package vs pkg-config?
A: find_package finds Config/Module files in a CMake native way, and pkg-config reads .pc files on Unix. Find_package is recommended because newer libraries provide CMake Config files.
Q2: Target vs variable?
A: Use target (Boost::filesystem). It is more type safe than variables (${Boost_LIBRARIES}), and PUBLIC/PRIVATE propagation is automatic. Config mode provides targets, and Module mode often provides variables.
Q3: What if we leave out REQUIRED?
A: No error is generated if the package is not found, and the <Name>_FOUND variable is set to FALSE. Use for optional dependencies.
Q4: What is CMAKE_PREFIX_PATH?
A: Additional paths where CMake will look for the package. Used to find libraries installed in non-standard locations. Separate multiple paths with a semicolon: -DCMAKE_PREFIX_PATH="/opt/lib1;/opt/lib2".
Q5: What if find_package fails?
A:
- Check if the library is installed (
apt list --installed,brew list) - Add installation path to
CMAKE_PREFIX_PATH - Use package-specific hint variables (
Boost_ROOT,Qt5_DIR, etc.) - Debugging the search process with
CMAKE_FIND_DEBUG_MODE=ON
Q6: What is the find_package learning resource?
A:
- CMake find_package official documentation
- “Professional CMake: A Practical Guide”
- CMake Package Registry
One line summary: find_package allows you to automatically find and link external libraries. Next, you might want to read Conan Package Management.
Good article to read together (internal link)
Here’s another article related to this topic.
- C++ CMake Complete Guide | Cross-platform build·latest CMake 3.28+ features·presets·modules
- C++ CMake Targets Complete Guide | Target-based build system
- C++ Conan Complete Guide | Modern C++ package management
- C++ vcpkg complete guide | Microsoft C++ Package Manager
Practical tips
These are tips that can be applied right away in practice.
Debugging tips
- If you run into a problem, check the compiler warnings first.
- Reproduce the problem with a simple test case
Performance Tips
- Don’t optimize without profiling
- Set measurable indicators first
Code review tips
- Check in advance for areas that are frequently pointed out in code reviews.
- Follow your team’s coding conventions
Practical checklist
This is what you need to check when applying this concept in practice.
Before writing code
- Is this technique the best way to solve the current problem?
- Can team members understand and maintain this code?
- Does it meet the performance requirements?
Writing code
- Have you resolved all compiler warnings?
- Have you considered edge cases?
- Is error handling appropriate?
When reviewing code
- Is the intent of the code clear?
- Are there enough test cases?
- Is it documented?
Use this checklist to reduce mistakes and improve code quality.
Keywords covered in this article (related search terms)
This article will be helpful if you search for C++, cmake, find-package, dependency, build, library, etc.
Related articles
- C++ CMake Targets Complete Guide | Target-based build system
- C++ CMake |
- C++ CMake Complete Guide | Cross-platform build·latest CMake 3.28+ features·presets·modules
- C++ Conan Complete Guide | Modern C++ package management
- CMake error |