[2026] CMake find_package for C++ | Boost, OpenSSL, pkg-config & Custom Find Modules
이 글의 핵심
CMake find_package tutorial: CONFIG vs MODULE, imported targets, Boost/OpenSSL/Qt examples, optional deps, and multi-library HTTP server—SEO keywords find_package CMake.
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.
다음은 mermaid를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
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
아래 코드는 cmake를 사용한 구현 예제입니다. 조건문으로 분기 처리를 수행합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
find_package(Boost REQUIRED)
if(Boost_FOUND)
message(STATUS "Boost found: ${Boost_VERSION}")
else()
message(FATAL_ERROR "Boost not found")
endif()
Optional packages
아래 코드는 cmake를 사용한 구현 예제입니다. 조건문으로 분기 처리를 수행합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
find_package(SomeLib)
if(SomeLib_FOUND)
target_link_libraries(myapp PRIVATE SomeLib::SomeLib)
else()
message(WARNING "SomeLib not found, using fallback")
endif()
Specify version
아래 코드는 cmake를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# 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
아래 코드는 cmake를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
find_package(Boost REQUIRED COMPONENTS
filesystem
system
thread
)
target_link_libraries(myapp PRIVATE
Boost::filesystem
Boost::system
Boost::thread
)
2. Main library examples
Boost
아래 코드는 cmake를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
find_package(Boost 1.70 REQUIRED COMPONENTS filesystem system)
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE
Boost::filesystem
Boost::system
)
OpenSSL
아래 코드는 cmake를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
find_package(OpenSSL REQUIRED)
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE
OpenSSL::SSL
OpenSSL::Crypto
)
Qt5
아래 코드는 cmake를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
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
아래 코드는 cmake를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
find_package(GTest REQUIRED)
add_executable(tests test.cpp)
target_link_libraries(tests PRIVATE
GTest::gtest
GTest::gtest_main
)
OpenCV
아래 코드는 cmake를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
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
아래 코드는 cmake를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
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
아래 코드는 cmake를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# 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를 활용한 상세한 구현 코드입니다. 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
# 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
아래 코드는 cmake를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# 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.
아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
# 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.
아래 코드는 cmake를 사용한 구현 예제입니다. 조건문으로 분기 처리를 수행합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# 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.
아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# 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.
아래 코드는 cmake를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
# 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. 아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# 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
아래 코드는 cmake를 사용한 구현 예제입니다. 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
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
아래 코드는 cmake를 사용한 구현 예제입니다. 조건문으로 분기 처리를 수행합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
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
아래 코드는 cmake를 사용한 구현 예제입니다. 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
# 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
아래 코드는 cmake를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
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
아래 코드는 cmake를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# 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를 활용한 상세한 구현 코드입니다. 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
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
다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
#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.