如何使用CMake将Visual Studio项目与OpenCV(superpack)正确链接

时间:2012-04-04 13:22:10

标签: visual-studio-2010 opencv cmake

我目前正在对旧的VHS录像带进行数字化处理。对于后期处理,我想用C ++和&amp ;;实现自定义算法。 OpenCV的。我已经在Matlab中实现了一个很有前景的原型,但它只能处理单个图像(在我的版本中不能读取/写入视频文件(R2010a);而且,Matlab太慢了。)

可悲的是,我 - 一遍又一遍 - 坚持使用CMake。虽然我想知道......这不会那么困难。我经常遇到CMake问题,所以我会在这里详细介绍。我希望你不仅可以向我指出我在这里做错了什么,而且还对我对CMake的使用提出了一般建议。也许我做错了,我不知道。

这是我到目前为止所做的:

  1. 我从sourceforge下载了 OpenCV 2.3.1 superpack 。 superpack包含OpenCV源代码,包括 - 最重要的是 - 所有主要平台的.lib和.dll文件。出于这个原因,我不需要自己构建OpenCV。它已经完成了。我只需要使用/链接它。
  2. 我在C:\dev\vs2010sp1_win32\opencv\2.3.1
  3. 中安装(即提取到)超级包
  4. 我已将C:\dev\vs2010sp1_win32\opencv\2.3.1\OpenCVConfig.cmake.in重命名为OpenCVConfig.cmake
  5. 我为项目C:\dev\VhsDejitterizer创建了一个文件夹,其结构如下:
  6. 
    VhsDejitterizer/
        CMakeLists.txt (A)
        src/
            CMakeLists.txt (B)
            libvhsdejitter/
                CMakeLists.txt (C)
                vhsdejitter/
                    util.h
                    util.cpp
            main/
                CMakeLists.txt (D)
                main.cpp
    

    以下是各个CMakeLists.txt文件的内容。

    /CMakeLists.txt(A)

    CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
    
    PROJECT("VhsDejitterizer")
    
    CMAKE_POLICY(SET CMP0015 OLD)
    FIND_PACKAGE(OpenCV REQUIRED
                NO_MODULE
                PATHS "C:/dev/vs2010sp1_win32/opencv/2.3.1"
                NO_DEFAULT_PATH)
    
    ADD_SUBDIRECTORY("src")
    

    /src/CMakeLists.txt(B)

    ADD_SUBDIRECTORY("libvhsdejitter")
    ADD_SUBDIRECTORY("main")
    

    /src/libvhsdejitter/CMakeLists.txt(C)

    UNSET(source_files)
    FILE(GLOB_RECURSE source_files "*.h" "*.cpp")
    
    ADD_LIBRARY(libvhsdejitter STATIC ${source_files})
    TARGET_LINK_LIBRARIES(libvhsdejitter ${OpenCV_LIBS})
    
    UNSET(source_files)
    

    /src/main/CMakeLists.txt(D)

    UNSET(source_files)
    FILE(GLOB_RECURSE source_files "*.h" "*.cpp")
    
    ADD_EXECUTABLE(main ${source_files})
    TARGET_LINK_LIBRARIES(main libvhsdejitter ${OpenCV_LIBS})
    
    UNSET(source_files)
    

    配置和生成Visual Studio .sln(...)文件效果很好。事实上,我没有收到任何警告或错误:

    Configuring done
    Generating done
    

    但是,我在Visual Studio中构建“main”项目的尝试失败了:

    1>------ Build started: Project: main, Configuration: Debug Win32 ------
    1>Build started 04.04.2012 14:38:47.
    1>InitializeBuildStatus:
    1>  Touching "main.dir\Debug\main.unsuccessfulbuild".
    1>CustomBuild:
    1>  All outputs are up-to-date.
    1>ClCompile:
    1>  main.cpp
    1>LINK : fatal error LNK1104: cannot open file '@CMAKE_LIB_DIRS_CONFIGCMAKE@/libopencv_gpu.so.@OPENCV_VERSION@@OPENCV_DLLVERSION@@OPENCV_DEBUG_POSTFIX@.lib'
    1>
    1>Build FAILED.
    1>
    1>Time Elapsed 00:00:00.59
    ========== Build: 0 succeeded, 1 failed, 2 up-to-date, 0 skipped ==========
    

    进一步详情:

    • 操作系统:Windows 7 Pro 64位
    • IDE:Visual Studio 2010 SP1
    • CMake版本:2.8.4
    • 目标平台(即我正在编译/构建的内容):Windows 32位

    我的问题:

    1. 如何成功构建“主要”项目?即如何解决这个错误?
    2. 这些@VARIABLE_OR_SOMETHING@是什么?我试图找出它们的来源,似乎是在OpenCVConfig.cmake中设置的。但它们应该如何运作?它们是否应该由Visual Studio在“构建时”进行评估?如果是这样,他们如何评估?
    3. 您可能已经注意到我已经设置了相当复杂的文件夹结构。你对此有什么建议吗?你如何组织你的图书馆和项目?有最好的做法吗?他们在哪里记录?
    4. 谢谢你,最诚挚的问候,罗伯特

3 个答案:

答案 0 :(得分:1)

这些变量可能与CMake的configure_file命令有关,它允许您指定参数化模板文档(通常扩展名以.in结尾),您可以将CMake变量替换为文件来创建它。它们在configure_file调用时进行评估,这在运行CMake时发生。我认为正在发生的事情是,您将采用一个父CMake脚本,该脚本将使用这些变量的内容配置该文件,然后在add_subdirectory调用中使用它。我建议检查任何描述顶级运行进程的自述文件(或任何定义这些变量然后手动替换它们的文件)。

答案 1 :(得分:1)

我现在修好了。我想我可以肯定地说整个混乱不是我的错。很抱歉回答我自己的问题。


这是我首先尝试的(当然,这对我来说有效,但它可能适用于其他人):

正如Martin Foot在他的回答中指出的那样,* .in文件是模板,应该在CMake配置期间用适当的值填充。但是,我正在使用OpenCV superpack,其中包含所有二进制文件。出于这个原因,我没有执行过这样的配置步骤,因为我认为只有在你想编译的时候才需要这样做。

然而,似乎 - 即使您使用带有预构建二进制文件的superpack - 您必须配置项目才能生成OpenCVConfig.cmake。 Vadim Pisarevsky has stated that in the OpenCV bug tracker

出于某种原因,这对我不起作用。我像往常一样启动了Cmake GUI,将其指向OpenCV目录并点击“Configure”。我甚至在绝望中击中了“Generate”。然而,没有出现OpenCVConfig.cmake。

所以我不得不继续......


这实际上是有帮助的:

在最近提交的与OpenCVConfig.cmake相关的bug报告中,Sergiu Dotenco pointed out“当前提供的OpenCVConfig.cmake非常脆弱”等等。幸运的是,Sergio还提供了a custom FindOpenCV.cmake script。通过使用他的脚本,我终于能够生成一个可用的Visual Studio解决方案。

顺便说一句,这是我目前的顶级CMakeLists.txt:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

PROJECT("VhsDejitterizer")

SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules" ${CMAKE_MODULE_PATH})

SET(OPENCV_ROOT_DIR "C:/dev/vs2010sp1_win32/opencv/2.3.1")
#SET(OPENCV_USE_GPU_LIBS ON)
FIND_PACKAGE(OpenCV REQUIRED)

ADD_SUBDIRECTORY("src")

我已将Sergio的FindOpenCV.cmake脚本安装在项目的新cmake-modules/子文件夹中。同样重要的是要注意我正在使用(而不是我的原始设置,我使用“配置模式”)最小的FIND_PACKAGE变体(“模块模式” )。只有在使用最小变量时,CMake才会在CMake模块路径中查找Find<package-name>.cmake脚本。请参阅CMake documentation for FIND_PACKAGE


我还找到了这个指南,关于如果你是图书馆开发人员如何正确使用CMake:http://www.vtk.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file

答案 2 :(得分:0)

我现在修好了。我想我可以肯定地说整个混乱不是我的错。很抱歉回答我自己的问题。

你修好了吗? 我遇到了同样的问题,我按照你的解决方案但是没有用。 当CMake执行命令时 FIND_PACKAGE(OpenCV REQUIRED)

它会输出:

One or more OpenCV components were not found:
  calib3d
  contrib
  core
  features2d
  flann
  highgui
  imgproc
  legacy
  ml
  objdetect
  video
CMake Error at C:/Program Files/CMake 2.8/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:91 (MESSAGE):
  Could NOT find OpenCV (missing: OPENCV_CALIB3D_LIBRARY
  OPENCV_CONTRIB_LIBRARY OPENCV_CORE_LIBRARY OPENCV_FEATURES2D_LIBRARY
  OPENCV_FLANN_LIBRARY OPENCV_HIGHGUI_LIBRARY OPENCV_IMGPROC_LIBRARY
  OPENCV_LEGACY_LIBRARY OPENCV_ML_LIBRARY OPENCV_OBJDETECT_LIBRARY
  OPENCV_VIDEO_LIBRARY) (found version "2.3.1")

最后,我使用了这些命令 include_directories TARGET_LINK_LIBRARIES 包含所有必要的目录或文件,它以一种尴尬的方式运作!