Skip to content

Fix: CMake Could Not Find Package Configuration File

FixDevs ·

Quick Answer

How to fix the CMake error 'Could not find a package configuration file' for find_package, covering CMAKE_PREFIX_PATH, dev packages, vcpkg, Conan, module mode, toolchain files, and cross-compilation.

The Error

You run cmake to configure a project and get:

CMake Error at CMakeLists.txt:12 (find_package):
  Could not find a package configuration file provided by "OpenCV"
  (requested version 4.5) with any of the following names:

    OpenCVConfig.cmake
    opencv-config.cmake

  Add the installation prefix of "OpenCV" to CMAKE_PREFIX_PATH or set
  "OpenCV_DIR" to a directory containing one of the above files.  If "OpenCV"
  provides a separate development package or SDK, be sure it has been
  installed.

Or a variation like:

CMake Error at /usr/share/cmake-3.28/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
  Could NOT find Boost (missing: filesystem system) (found version "1.74.0")
CMake Warning at CMakeLists.txt:8 (find_package):
  By not providing "FindSomeLib.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "SomeLib",
  but CMake did not find one.

These all point to the same root problem: CMake’s find_package() call cannot locate the library you need.

Why This Happens

CMake uses find_package() to locate external libraries and their headers, link flags, and compiler definitions. This command operates in two distinct modes, and understanding them is critical to fixing this error.

Config mode searches for a file named <Package>Config.cmake or <package>-config.cmake. The library itself ships this file when it is installed. CMake looks for it in a set of standard directories plus any paths you specify via CMAKE_PREFIX_PATH or <Package>_DIR.

Module mode searches for a file named Find<Package>.cmake. These finder scripts ship with CMake itself (in its Modules/ directory) or can be provided by your project. Module mode runs first by default; if it fails, CMake falls back to config mode.

The error occurs when both modes fail. Common reasons:

  • The library is not installed at all.
  • The library is installed, but its development files (headers and CMake config files) are missing. On Linux, you often need the -dev or -devel package.
  • The library is installed in a non-standard location that CMake does not search by default.
  • You are using a package manager like vcpkg or Conan but have not told CMake where it stores packages.
  • You are cross-compiling, and the host system’s libraries are being searched instead of the target sysroot.
  • The library provides config files for a different version of CMake or uses a non-standard naming convention.

Fix 1: Install the Missing Library and Its Dev Package

The most common cause is that the library simply is not installed, or only the runtime package is present without the development headers and CMake configuration files.

On Ubuntu/Debian:

sudo apt-get update
sudo apt-get install libopencv-dev

On Fedora/RHEL/CentOS:

sudo dnf install opencv-devel

On Arch Linux:

sudo pacman -S opencv

On macOS with Homebrew:

brew install opencv

On Windows with vcpkg (covered more in Fix 5):

vcpkg install opencv4:x64-windows

The key detail on Linux is the -dev or -devel suffix. The base package contains shared libraries for running applications, but find_package() needs the header files and .cmake configuration files that only ship in the development package. If you have ever run into apt-get unable to locate package errors while installing these, fix your package sources first.

To verify the development files are actually present after installation:

dpkg -L libopencv-dev | grep cmake

You should see paths like /usr/lib/x86_64-linux-gnu/cmake/opencv4/OpenCVConfig.cmake. If that file does not exist, the dev package did not install correctly.

Fix 2: Set CMAKE_PREFIX_PATH

If the library is installed in a non-standard location (e.g., /opt/opencv, $HOME/.local, or a custom build directory), CMake will not find it automatically. Tell CMake where to look:

cmake -DCMAKE_PREFIX_PATH=/opt/opencv ..

You can specify multiple paths separated by semicolons:

cmake -DCMAKE_PREFIX_PATH="/opt/opencv;/opt/boost_1_82_0" ..

Alternatively, set it as an environment variable:

export CMAKE_PREFIX_PATH=/opt/opencv:/opt/boost_1_82_0
cmake ..

Note: When using the environment variable, paths are separated by colons on Linux/macOS and semicolons on Windows. When passing it as a CMake variable with -D, always use semicolons regardless of platform.

You can also set this permanently in your CMakeLists.txt, though this is generally not recommended because it hardcodes machine-specific paths:

list(APPEND CMAKE_PREFIX_PATH "/opt/opencv")
find_package(OpenCV REQUIRED)

Pro Tip: If you built the library from source with cmake --install, the default install prefix is /usr/local on Linux. CMake searches /usr/local by default, so it should be found automatically. If you used a custom --prefix, you need to add that path to CMAKE_PREFIX_PATH.

Fix 3: Set the Package-Specific DIR Variable

Each package can be found by setting <Package>_DIR to the directory containing its config file. This is more targeted than CMAKE_PREFIX_PATH:

cmake -DOpenCV_DIR=/opt/opencv/lib/cmake/opencv4 ..

The value must point to the exact directory containing OpenCVConfig.cmake, not just the installation prefix. To find where that file lives:

find / -name "OpenCVConfig.cmake" 2>/dev/null

On Windows:

Get-ChildItem -Path C:\ -Recurse -Filter "OpenCVConfig.cmake" -ErrorAction SilentlyContinue

Common locations by platform:

PlatformTypical config file path
Ubuntu/Debian/usr/lib/x86_64-linux-gnu/cmake/<pkg>/
Fedora/RHEL/usr/lib64/cmake/<pkg>/
macOS (Homebrew)/opt/homebrew/lib/cmake/<pkg>/
Windows (vcpkg)C:/vcpkg/installed/x64-windows/share/<pkg>/
Custom build<install_prefix>/lib/cmake/<pkg>/

Fix 4: Understand Config Mode vs. Module Mode

The error message itself tells you which mode CMake tried. If it mentions <Package>Config.cmake, it used config mode. If it mentions Find<Package>.cmake, it used module mode.

You can force a specific mode:

# Force config mode only
find_package(OpenCV REQUIRED CONFIG)

# Force module mode only
find_package(OpenCV REQUIRED MODULE)

When to use config mode: The library provides its own *Config.cmake file. Most modern C++ libraries do this. Config mode is more reliable because the library author controls the file.

When to use module mode: The library does not provide CMake config files, but CMake ships a Find<Package>.cmake module for it. Examples include FindThreads, FindZLIB, FindOpenSSL, and FindCURL.

If a library has no config file and no built-in find module, you have three options:

  1. Write your own Find<Package>.cmake and add its directory to CMAKE_MODULE_PATH.
  2. Use pkg-config (see Fix 6).
  3. Use find_library() and find_path() directly instead of find_package().

Here is a minimal custom find module:

# cmake/FindMyLib.cmake
find_path(MYLIB_INCLUDE_DIR mylib.h
  PATHS /usr/local/include /opt/mylib/include
)

find_library(MYLIB_LIBRARY mylib
  PATHS /usr/local/lib /opt/mylib/lib
)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MyLib
  REQUIRED_VARS MYLIB_LIBRARY MYLIB_INCLUDE_DIR
)

if(MYLIB_FOUND)
  set(MYLIB_LIBRARIES ${MYLIB_LIBRARY})
  set(MYLIB_INCLUDE_DIRS ${MYLIB_INCLUDE_DIR})
endif()

Then in your main CMakeLists.txt:

list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
find_package(MyLib REQUIRED)
target_include_directories(myapp PRIVATE ${MYLIB_INCLUDE_DIRS})
target_link_libraries(myapp PRIVATE ${MYLIB_LIBRARIES})

Fix 5: Use vcpkg to Manage Dependencies

vcpkg is a cross-platform C/C++ package manager from Microsoft that integrates directly with CMake. It eliminates most find_package issues by handling installation and path configuration automatically.

Install vcpkg:

git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh   # Linux/macOS
# .\bootstrap-vcpkg.bat  # Windows

Install your library:

./vcpkg install opencv4 boost-filesystem

Tell CMake to use vcpkg’s toolchain file:

cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake ..

This single flag makes all vcpkg-installed packages visible to find_package(). No additional CMAKE_PREFIX_PATH or _DIR variables needed.

You can set this permanently by adding a CMakePresets.json to your project:

{
  "version": 3,
  "configurePresets": [
    {
      "name": "default",
      "toolchainFile": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Release"
      }
    }
  ]
}

Then configure with:

cmake --preset default

If you previously had build failures with pip on C extension packages, you may already be familiar with the pattern of needing system-level dev libraries. vcpkg solves the same problem for C++ projects in a more portable way.

Common Mistake: When using vcpkg on Windows, make sure you install the correct triplet. Running vcpkg install opencv4 installs the x86-windows triplet by default. If your project targets 64-bit, use vcpkg install opencv4:x64-windows explicitly. Mismatched triplets cause find_package to fail silently.

Fix 6: Use pkg-config as a Fallback

Some libraries do not ship CMake config files but do provide .pc files for pkg-config. You can bridge this gap in CMake using the built-in PkgConfig module:

find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBFOO REQUIRED IMPORTED_TARGET libfoo)

target_link_libraries(myapp PRIVATE PkgConfig::LIBFOO)

If pkg-config cannot find the .pc file, set PKG_CONFIG_PATH:

export PKG_CONFIG_PATH=/opt/libfoo/lib/pkgconfig:$PKG_CONFIG_PATH
cmake ..

To check what pkg-config sees:

pkg-config --list-all | grep libfoo
pkg-config --cflags --libs libfoo

The IMPORTED_TARGET keyword (available since CMake 3.6) creates a proper CMake target with all include directories and link flags set automatically. This is cleaner than manually extracting _CFLAGS and _LDFLAGS variables.

Note: pkg-config support varies by platform. It works well on Linux, is available on macOS through Homebrew, and is less common on Windows. For cross-platform projects, prefer vcpkg or Conan over pkg-config.

Fix 7: Use Conan for Dependency Management

Conan is another popular C/C++ package manager that integrates with CMake. It works differently from vcpkg by generating CMake files in your build directory.

Install Conan:

pip install conan

Create a conanfile.txt in your project root:

[requires]
opencv/4.5.5
boost/1.82.0

[generators]
CMakeDeps
CMakeToolchain

Install dependencies and configure:

conan install . --output-folder=build --build=missing
cmake -B build -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake
cmake --build build

The CMakeDeps generator creates *Config.cmake files for each dependency, and the CMakeToolchain generator sets up CMAKE_PREFIX_PATH automatically. Your find_package() calls work without any additional flags.

For projects that use conanfile.py instead:

from conan import ConanFile
from conan.tools.cmake import cmake_layout

class MyProjectConan(ConanFile):
    requires = "opencv/4.5.5", "boost/1.82.0"
    generators = "CMakeDeps", "CMakeToolchain"

    def layout(self):
        cmake_layout(self)

If you are familiar with other build systems like Gradle handling dependency resolution, Conan follows a similar model where dependencies are declared in a manifest file and resolved before the build starts.

Fix 8: Fix Cross-Compilation and Toolchain File Issues

When cross-compiling (e.g., building for ARM on an x86 host, or targeting embedded Linux), find_package() failures are common because CMake searches the host system paths by default instead of the target sysroot.

Set the correct sysroot in your toolchain file:

# toolchain-arm.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(CMAKE_SYSROOT /opt/arm-sysroot)
set(CMAKE_FIND_ROOT_PATH /opt/arm-sysroot)

set(CMAKE_C_COMPILER /opt/arm-gcc/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER /opt/arm-gcc/bin/arm-linux-gnueabihf-g++)

# Control where find_* commands search
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

The CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY line is critical. It tells find_package() to search only within the sysroot, preventing it from accidentally finding host libraries that would not work on the target.

Use the toolchain file:

cmake -DCMAKE_TOOLCHAIN_FILE=toolchain-arm.cmake ..

Common cross-compilation pitfalls:

  • Missing target libraries in sysroot. You need to install or cross-compile the library for your target architecture and place it in the sysroot. The host system’s /usr/lib/x86_64-linux-gnu/ is useless for ARM builds.
  • vcpkg with custom triplets. vcpkg supports cross-compilation through community triplets like arm-linux. Create a custom triplet file if yours is not available.
  • Mixed architectures. If find_package() finds a library but linking fails with architecture mismatch errors, CMake found a host library. Verify CMAKE_FIND_ROOT_PATH is set correctly.

If your cross-compilation setup involves Docker containers, be aware of permission issues with Docker volumes that can prevent CMake from reading config files in mounted sysroot directories.

Still Not Working?

If none of the fixes above resolved the issue, work through these steps:

Enable verbose find_package output. Add --debug-find to see exactly where CMake searches:

cmake --debug-find ..

This prints every directory CMake checks, making it obvious whether your path configuration is correct. On CMake 3.17+, you can also use:

set(CMAKE_FIND_DEBUG_MODE TRUE)
find_package(OpenCV REQUIRED)
set(CMAKE_FIND_DEBUG_MODE FALSE)

Check for version mismatches. If find_package(OpenCV 4.5 REQUIRED) fails but you have OpenCV 4.2 installed, CMake rejects it. Either install the correct version or relax the version requirement:

find_package(OpenCV 4.0 REQUIRED)  # Accept 4.0 or newer

Verify the config file is valid. Open the *Config.cmake file and check for hardcoded paths that do not exist on your system. This happens when you copy a build tree from another machine. Reinstalling the library usually fixes it.

Check file permissions. CMake needs read access to config files. If your library is installed in a root-owned directory and you run CMake as a regular user, permission issues can prevent CMake from reading the config files:

ls -la /usr/lib/cmake/opencv4/

Check your CMake version. Some config files use features from newer CMake versions. If you see errors about unknown CMake commands inside a config file, upgrade CMake:

# Install latest CMake on Ubuntu
sudo apt-get install -y gpg wget
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc | sudo gpg --dearmor -o /usr/share/keyrings/kitware-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/kitware.list
sudo apt-get update
sudo apt-get install cmake

Verify the library exports CMake targets correctly. If you built the library from source and installed it, but find_package() still fails, the library’s CMakeLists.txt might not include install(EXPORT ...) commands. Check the library’s documentation for CMake integration instructions, or fall back to pkg-config (Fix 6) or manual find_library() calls.

Clean the CMake cache. Stale cache entries can cause find_package() to skip searches. Delete the build directory and reconfigure:

rm -rf build
mkdir build && cd build
cmake ..

If you are working in a Docker build context and encountering this error, make sure your Dockerfile installs the dev packages before the CMake configure step, and that you are not accidentally using a multi-stage build that discards the dev packages before they are needed.

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles