1. 更新 locate 数据库 (必做!)

    • 操作: 打开终端,运行 sudo updatedb
    • 原因: 确保 locate 的数据库包含你刚刚安装的新库的文件信息。否则后续步骤可能什么也找不到。
  2. 初步定位:查找核心配置文件 (Config.cmake)

    • 操作: 运行以下命令

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      locate -i 'config.cmake' | grep -i 'opencv'

      # 结果为
      ~ ❯ locate -i 'config.cmake' | grep -i 'opencv'
      /home/xfy/opencv_versions/4.5.5/build/3rdparty/ade/ade-0.1.1f/sources/ade/cmake/adeConfig.cmake.in
      /home/xfy/opencv_versions/4.5.5/build/CPackConfig.cmake
      /home/xfy/opencv_versions/4.5.5/build/CPackSourceConfig.cmake
      /home/xfy/opencv_versions/4.5.5/build/OpenCVConfig.cmake
      /home/xfy/opencv_versions/4.5.5/build/opencv_python_config.cmake
      /home/xfy/opencv_versions/4.5.5/build/unix-install/OpenCVConfig.cmake
      /home/xfy/opencv_versions/4.5.5/opencv/cmake/OpenCVGenConfig.cmake
      /home/xfy/opencv_versions/4.5.5/opencv/cmake/OpenCVGenPkgconfig.cmake
      /home/xfy/opencv_versions/4.5.5/opencv/cmake/templates/OpenCVConfig.cmake.in
      /home/xfy/opencv_versions/4.5.5/opencv/samples/hal/c_hal/config.cmake
      /home/xfy/opencv_versions/4.5.5/opencv/samples/hal/slow_hal/config.cmake
      /usr/lib/x86_64-linux-gnu/cmake/opencv4/OpenCVConfig.cmake
      /usr/local/opencv/4.5.5/lib/cmake/opencv4/OpenCVConfig.cmake
      /var/lib/docker/overlay2/0809ea31aa8a06f4c911b20f04526b19005bfabdd262f23d6bb3a4ee464f4dbb/diff/home/myslam/3d/opencv-4.2.0/build/3rdparty/ade/ade-0.1.1f/sources/ade/cmake/adeConfig.cmake.in
      /var/lib/docker/overlay2/0809ea31aa8a06f4c911b20f04526b19005bfabdd262f23d6bb3a4ee464f4dbb/diff/home/myslam/3d/opencv-4.2.0/build/CPackConfig.cmake
      /var/lib/docker/overlay2/0809ea31aa8a06f4c911b20f04526b19005bfabdd262f23d6bb3a4ee464f4dbb/diff/home/myslam/3d/opencv-4.2.0/build/CPackSourceConfig.cmake
      /var/lib/docker/overlay2/0809ea31aa8a06f4c911b20f04526b19005bfabdd262f23d6bb3a4ee464f4dbb/diff/home/myslam/3d/opencv-4.2.0/build/OpenCVConfig.cmake
      /var/lib/docker/overlay2/0809ea31aa8a06f4c911b20f04526b19005bfabdd262f23d6bb3a4ee464f4dbb/diff/home/myslam/3d/opencv-4.2.0/build/opencv_python_config.cmake
      /var/lib/docker/overlay2/0809ea31aa8a06f4c911b20f04526b19005bfabdd262f23d6bb3a4ee464f4dbb/diff/home/myslam/3d/opencv-4.2.0/build/unix-install/OpenCVConfig.cmake
      /var/lib/docker/overlay2/0809ea31aa8a06f4c911b20f04526b19005bfabdd262f23d6bb3a4ee464f4dbb/diff/home/myslam/3d/opencv-4.2.0/cmake/OpenCVGenConfig.cmake
      /var/lib/docker/overlay2/0809ea31aa8a06f4c911b20f04526b19005bfabdd262f23d6bb3a4ee464f4dbb/diff/home/myslam/3d/opencv-4.2.0/cmake/OpenCVGenPkgconfig.cmake
      /var/lib/docker/overlay2/0809ea31aa8a06f4c911b20f04526b19005bfabdd262f23d6bb3a4ee464f4dbb/diff/home/myslam/3d/opencv-4.2.0/cmake/templates/OpenCVConfig.cmake.in
      /var/lib/docker/overlay2/0809ea31aa8a06f4c911b20f04526b19005bfabdd262f23d6bb3a4ee464f4dbb/diff/home/myslam/3d/opencv-4.2.0/samples/hal/c_hal/config.cmake
      /var/lib/docker/overlay2/0809ea31aa8a06f4c911b20f04526b19005bfabdd262f23d6bb3a4ee464f4dbb/diff/home/myslam/3d/opencv-4.2.0/samples/hal/slow_hal/config.cmake
      /var/lib/docker/overlay2/0809ea31aa8a06f4c911b20f04526b19005bfabdd262f23d6bb3a4ee464f4dbb/diff/usr/local/lib/cmake/opencv4/OpenCVConfig.cmake
      /var/lib/docker/overlay2/1f605c5b588ec93f0f1947a29092b374d5fd184eedbfea41eba42bc85f33b932/diff/usr/lib/x86_64-linux-gnu/cmake/opencv4/OpenCVConfig.cmake

      可以看到有很多,但是我知道我是安装到/usr/local/的所以看/usr/local/opencv/4.5.5/lib/cmake/opencv4/OpenCVConfig.cmake
      这一个

  3. 确定 find_package 名称

    由OpenCVConfig.cmake可以知道这里的名称大小写是OpenCV,所以应该是find_package(OpenCV REQUIRED)

    这里可以指定模块,也可以不指定,没有太大影响的。之前文章的例子里指定了模块的写法是find_package(OpenCV REQUIRED COMPONENTS core imgcodecs highgui)

  4. 然后通过gedit或者vim等等查看这个文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #  The OpenCV CMake configuration file
    #
    # ** File generated automatically, do not modify **
    #
    # Usage from an external project:
    # In your CMakeLists.txt, add these lines:
    #
    # find_package(OpenCV REQUIRED)
    # include_directories(${OpenCV_INCLUDE_DIRS}) # Not needed for CMake >= 2.8.11
    # target_link_libraries(MY_TARGET_NAME ${OpenCV_LIBS})
    #
    # Or you can search for specific OpenCV modules:
    #
    # find_package(OpenCV REQUIRED core videoio)
    #
    # You can also mark OpenCV components as optional:

    # find_package(OpenCV REQUIRED core OPTIONAL_COMPONENTS viz)
    #
    # If the module is found then OPENCV_<MODULE>_FOUND is set to TRUE.
    #
    # This file will define the following variables:
    # - OpenCV_LIBS : The list of all imported targets for OpenCV modules.
    # - OpenCV_INCLUDE_DIRS : The OpenCV include directories.
    # - OpenCV_COMPUTE_CAPABILITIES : The version of compute capability.
    # - OpenCV_ANDROID_NATIVE_API_LEVEL : Minimum required level of Android API.
    # - OpenCV_VERSION : The version of this OpenCV build: "4.5.5"
    # - OpenCV_VERSION_MAJOR : Major version part of OpenCV_VERSION: "4"
    # - OpenCV_VERSION_MINOR : Minor version part of OpenCV_VERSION: "5"
    # - OpenCV_VERSION_PATCH : Patch version part of OpenCV_VERSION: "5"
    # - OpenCV_VERSION_STATUS : Development status of this build: ""
    #
    # Advanced variables:
    # - OpenCV_SHARED : Use OpenCV as shared library
    # - OpenCV_INSTALL_PATH : OpenCV location
    # - OpenCV_LIB_COMPONENTS : Present OpenCV modules list
    # - OpenCV_USE_MANGLED_PATHS : Mangled OpenCV path flag
    #
    # Deprecated variables:
    # - OpenCV_VERSION_TWEAK : Always "0"

    翻译一下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    # ===================================================================================
    # OpenCV CMake 配置文件
    #
    # ** 文件自动生成,请勿修改 **
    #
    # 从外部项目使用:
    # 在你的 CMakeLists.txt 中,添加这些行:
    #
    # find_package(OpenCV REQUIRED)
    # include_directories(${OpenCV_INCLUDE_DIRS}) # 对于 CMake >= 2.8.11 已不再需要
    # target_link_libraries(MY_TARGET_NAME ${OpenCV_LIBS})
    #
    # 或者你可以搜索特定的 OpenCV 模块:
    #
    # find_package(OpenCV REQUIRED core videoio)
    #
    # 你也可以将 OpenCV 组件标记为可选:
    # find_package(OpenCV REQUIRED core OPTIONAL_COMPONENTS viz)
    #
    # 如果找到了模块,那么 OPENCV_<MODULE>_FOUND 会被设置为 TRUE。
    #
    # 该文件将定义以下变量:
    # - OpenCV_LIBS : OpenCV 模块的所有导入目标 (imported targets) 的列表。
    # - OpenCV_INCLUDE_DIRS : OpenCV 的包含目录。
    # - OpenCV_COMPUTE_CAPABILITIES : 计算能力 (Compute Capability) 的版本。
    # - OpenCV_ANDROID_NATIVE_API_LEVEL : 最低要求的 Android API 级别。
    # - OpenCV_VERSION : 此 OpenCV 构建的版本:"4.5.5"
    # - OpenCV_VERSION_MAJOR : OpenCV_VERSION 的主版本号:"4"
    # - OpenCV_VERSION_MINOR : OpenCV_VERSION 的次版本号:"5"
    # - OpenCV_VERSION_PATCH : OpenCV_VERSION 的修订版本号:"5"
    # - OpenCV_VERSION_STATUS : 此构建的开发状态:""
    #
    # 高级变量:
    # - OpenCV_SHARED : 将 OpenCV 作为共享库使用
    # - OpenCV_INSTALL_PATH : OpenCV 的位置
    # - OpenCV_LIB_COMPONENTS : 当前存在的 OpenCV 模块列表
    # - OpenCV_USE_MANGLED_PATHS : Mangled OpenCV 路径标志
    #
    # 已弃用变量:
    # - OpenCV_VERSION_TWEAK : 始终为 "0"

    可以看到这里说明了执行findpackage之后给哪些变量赋予了哪些值,也写了用法

    1
    2
    3
    4
    5
    6
    #  从外部项目使用:
    # 在你的 CMakeLists.txt 中,添加这些行:
    #
    # find_package(OpenCV REQUIRED)
    # include_directories(${OpenCV_INCLUDE_DIRS}) # 对于 CMake >= 2.8.11 已不再需要
    # target_link_libraries(MY_TARGET_NAME ${OpenCV_LIBS})

    这段注释虽然目的是指导用户,但它本身混合了新旧两种风格的痕迹,我们需要仔细解读:

    1. 旧方式 (Variable-Based) 的体现:
      • 明确的指令: 注释中明确给出了以下使用步骤:

        1
        2
        include_directories(${OpenCV_INCLUDE_DIRS})
        target_link_libraries(MY_TARGET_NAME ${OpenCV_LIBS})
      • 这是典型的旧式 CMake 用法。它依赖于 find_package 执行后设置的两个变量

        • ${OpenCV_INCLUDE_DIRS}: 包含了需要添加到编译器搜索路径的头文件目录。你需要手动调用 include_directories() (或现代的 target_include_directories()) 来使用它。
        • ${OpenCV_LIBS}: 包含了需要链接的库文件列表(可能是库文件的绝对路径,也可能在旧 CMake 中是链接器标志)。你需要手动将这个变量传递给 target_link_libraries()
    2. 新方式 (Target-Based) 的线索和提示:
      • 关键注释: include_directories(${OpenCV_INCLUDE_DIRS}) # Not needed for CMake >= 2.8.11

        • 这是最强烈的暗示。它告诉你,对于较新版本的 CMake (2.8.11 及以后,实际上现代 CMake 实践通常指 3.x 系列),手动添加 OpenCV_INCLUDE_DIRS不必要的。为什么?因为现代 CMake 的核心是目标 (Target)。当你链接到一个设计良好的导入目标 (Imported Target) 时,这个目标本身就封装了它所需的包含目录、链接库、编译定义等信息。CMake 会自动将这些信息传递给链接它的目标。
      • 变量 OpenCV_LIBS 的描述: OpenCV_LIBS : The list of all **imported targets** for OpenCV modules.

        • 这一点非常重要!虽然旧方式的使用示例中是 target_link_libraries(... ${OpenCV_LIBS}),但这里对 OpenCV_LIBS 变量内容的描述明确指出了它包含的是 “imported targets”。这意味着 ${OpenCV_LIBS} 变量里存放的不再仅仅是库文件名或路径,而是 CMake 能理解的、代表了 OpenCV 各个模块的目标名称列表(例如 OpenCV::core, OpenCV::imgproc 等)。
      • 结合以上两点,可以推断出新方式的用法(尽管这段注释没有直接写出来)

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        find_package(OpenCV REQUIRED COMPONENTS core imgproc highgui) # 假设需要这三个
        target_link_libraries(MY_TARGET_NAME PRIVATE OpenCV::core OpenCV::imgproc OpenCV::highgui)

        这里find_package可以不指定具体哪个模块而是用
        find_package(OpenCV REQUIRED)
        区别不大

        target_link_libraries推荐指定模块,不然就会把所有模块全都链接到项目上

        说是这样说,但是我指定模块运行失败,不知道是因为名字不对还是啥
        target_include_directories(my_app PUBLIC include)才成功的

总结:还是用文档里说的吧

1
2
3
4
5
6
7
8
#  从外部项目使用:
# 在你的 CMakeLists.txt 中,添加这些行:
#
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS}) # 对于 CMake >= 2.8.11 已不再需要
target_link_libraries(MY_TARGET_NAME ${OpenCV_LIBS})

其中include_directories可有可无