简体   繁体   中英

How to properly link Visual Studio project with OpenCV (superpack) using CMake

I am currently digitizing old VHS cassettes. For post-processing, I would like to implement a custom algorithm with C++ & OpenCV. I have already implemented a promising prototype in Matlab, but it can only process single images (reading / writing video files is not possible in my version (R2010a); also, Matlab is far too slow).

Sadly, I am - over and over again - stuck with CMake. Though I wonder... this can't be so difficult. I have often had problems with CMake, so I will go into a lot of detail here. I hope that you can not only point out to me what I am doing wrong here, but give general advices towards my usage of CMake as well. Maybe I am doing it all wrong, I don't know.

Here is what I've done so far:

  1. I have downloaded the OpenCV 2.3.1 superpack from sourceforge. The superpack contains OpenCV source code, includes and - most importantly - the.lib and.dll files for all major platforms. For this reason, I need not build OpenCV myself. It is already done. I need only use/link it.
  2. I installed (ie extracted to) the superpack in C:\dev\vs2010sp1_win32\opencv\2.3.1 .
  3. I have renamed C:\dev\vs2010sp1_win32\opencv\2.3.1\OpenCVConfig.cmake.in to OpenCVConfig.cmake .
  4. I have created a folder for my project C:\dev\VhsDejitterizer with the following structure:

VhsDejitterizer/
    CMakeLists.txt (A)
    src/
        CMakeLists.txt (B)
        libvhsdejitter/
            CMakeLists.txt (C)
            vhsdejitter/
                util.h
                util.cpp
        main/
            CMakeLists.txt (D)
            main.cpp

Here are the contents of the individual CMakeLists.txt files.

/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)

Configuring and generating the Visual Studio.sln (...) files works well. In fact, I am not getting a single warning or error:

Configuring done
Generating done

However, my attempt to build the 'main' project in Visual Studio fails:

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 ==========

Further details:

  • Operating system: Windows 7 Pro 64-bit
  • IDE: Visual Studio 2010 SP1
  • CMake version: 2.8.4
  • Target platform (ie what am I compiling/building for): Windows 32-bit

My questions:

  1. How do I successfully build the 'main' project? Ie how to fix that error?
  2. What are these @VARIABLE_OR_SOMETHING@ ? I have tried to find out where they come from, and they seem to be set up in OpenCVConfig.cmake . But how are they supposed to work? Are they supposed to be evaluated by Visual Studio at "build-time"? If so, how are they evaluated?
  3. You have probably noticed that I have set up quite a sophisticated folder structure. Do you have any advice on this? How do you organize your libraries and projects? Are there best-practices? Where are they documented?

Thank you and best regards, Robert

These variables are probably related to CMake's configure_file command, which allows you to specify a parameterised template document (typically with the extension ending in .in ) and you can substitute CMake variables into the file to create it. They are evaluated at the time of the configure_file call, which happens when running CMake. I think what's happening is that there will be a parent CMake script to the one that you've taken which will configure that file with the contents of those variables and then use it in an add_subdirectory call. I would suggest checking for any readme that describes the top level run process (or any file which defines those variables then substitute them manually).

I have fixed it now. I think I can safely say that the whole mess was not my fault. Sorry for answering my own question.


Here is what I tried first (of course, this did not work for me, but it might work for others):

As Martin Foot pointed out in his answer, the *.in files are templates which are supposed to be filled out with proper values during a CMake configuration. However, I am using the OpenCV superpack, which includes all the binaries. For this reason I have, at no point, performed such a configuration step, because I assumed this would only be necessary if you wanted to compile something.

However, it seems that - even if you're using the superpack with prebuilt binaries - you have to configure the project in order to get your OpenCVConfig.cmake generated. Vadim Pisarevsky has stated that in the OpenCV bug tracker .

For some reason, this didn't work for me. I started up the Cmake GUI as usual, pointed it to the OpenCV directory and hit "Configure". I even hit "Generate" out of desperation. Yet, no OpenCVConfig.cmake appeared.

So I had to go on further...


This is what actually helped:

In a recently filed bugreport related to OpenCVConfig.cmake, Sergiu Dotenco pointed out "that the currently provided OpenCVConfig.cmake is pretty fragile" etc. etc. Fortunately, Sergio has also provided a custom FindOpenCV.cmake script . By using his script I have finally been able to generate a working Visual Studio solution.

By the way, this is my current top-level 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")

I have installed Sergio's FindOpenCV.cmake script in a new cmake-modules/ subfolder of the project. It is also important to note that I am using (as opposed to my original setup, where I used the "config mode" ) the minimal FIND_PACKAGE variant ( "module mode" ). Only if the minimal variant is used, CMake is looking for Find<package-name>.cmake scripts in the CMake module path. See the CMake documentation for FIND_PACKAGE .


I have also found this guide, which is about how to properly use CMake if you're a library developer: http://www.vtk.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file

I have fixed it now. I think I can safely say that the whole mess was not my fault. Sorry for answering my own question.

You fixed it? I am having the same problem, and I followed your solution but it did not work. When CMake executed the command FIND_PACKAGE( OpenCV REQUIRED )

It would output:

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")

Finally, I used the commands include_directories TARGET_LINK_LIBRARIES to include all necessary directories or files, and it works, in a awkward way!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM