How to properly link Visual Studio project with OpenCV (superpack) using CMake - visual-studio-2010

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:
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.
I installed (i.e. extracted to) the superpack in C:\dev\vs2010sp1_win32\opencv\2.3.1.
I have renamed C:\dev\vs2010sp1_win32\opencv\2.3.1\OpenCVConfig.cmake.in to OpenCVConfig.cmake.
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 (i.e. what am I compiling/building for): Windows 32-bit
My questions:
How do I successfully build the 'main' project? I.e. how to fix that error?
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?
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!

Related

Why OpenCV 4.5.2 doesn't have apps built

I installed OpenCV 4.5.2 using the Windows installer and when I looked in the apps folder, I couldn't find some apps (create_samples, train_cascade). So, I downloaded the code and I generated visual studio projects using CMake. After I built all those project, again, in the app folder there were no project files to build those apps.
I also run cmake . in an app directory, but this error came out:
CMake Warning (dev) in CMakeLists.txt:
No project() command is present. The top-level CMakeLists.txt file must
contain a literal, direct call to the project() command. Add a line of
code such as
project(ProjectName)
near the top of the file, but after cmake_minimum_required().
CMake is pretending there is a "project(Project)" command on the first
line.
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Error at CMakeLists.txt:4 (ocv_add_application):
Unknown CMake command "ocv_add_application".
-- Configuring incomplete, errors occurred!
See also "C:/opencv/opencv-master/apps/createsamples/CMakeFiles/CMakeOutput.log".
this is the CMakeLists.txt file that I run:
file(GLOB SRCS *.cpp)
ocv_add_application(opencv_createsamples
MODULES opencv_core opencv_imgproc opencv_objdetect opencv_imgcodecs opencv_highgui opencv_calib3d opencv_features2d opencv_videoio
SRCS ${SRCS})
In all honesty, last time that I used CMake was 10 years ago and I really would like an hand to figure this out.
Thanks
STACK:
CMake 3.20.3
OpenCV 4.5.2
Python 3.9.5
Visual Studio 16.10.0
Wndows 10
I found out why this is happening. In opencv 4.5 (I didn't check other versions), the line in the cmake file that generate the solution for traincascade and createsamples, are explicitly commented out. This because building those apps will generate more than 600 errors! Let's hope this problem will be fixed soon.
from https://github.com/opencv/opencv/issues/13231
These apps has been disabled during legacy C API removal. Rewriting them
with C++ API was not an option because it is too easy to break them
and hard to test.
Also modern approaches via DNN provides much better results - just
compare OpenCV face detector with CascadeClassifier and DNN.

Boost is using pthread but should use win32

I used Cmake gui and the FindBoost module to add Boost as a dependency in my visual studio 2010 c++ project. I set the parameter that tells FindBoost to use the win32 thread library instead of pthread (because I'm running on windows). When i build my code, all the calls to boost libraries compile fine, but boost itself is having a compile error. its failing on
boost\thread\pthread\mutex.hpp line 11
cannot open include file: 'pthread.h': No such file or directory
If I could make it use the win32 library, the mutex.hpp (and all the other files) dont call pthread.h
How do I build so that it uses boost\thread\win32 ?
here is the section of my cmakelists.txt
# include boost
set(BOOST_ROOT "E:/boost_1_58_0/boost_1_58_0")
add_definitions( -DBOOST_ALL_NO_LIB )
find_package(Boost COMPONENTS thread system)
if(Boost_FOUND)
message(STATUS "Boost was found, Success!")
# telling it to use win32 threads not pthreads
set(Boost_THREADAPI "win32")
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
endif()
CMake comes with a module called FindBoost which i used, and it correctly found the boost directory and set the following
Boost_INCLUDE_DIR
E:/boost_1_58_0/boost_1_58_0/
Boost_LIBRARY_DIR
E:/boost_1_58_0/boost_1_58_0/stage/lib
Boost_SYSTEM_LIBRARY_DEBUG
E:/boost_1_58_0/boost_1_58_0/stage/lib/boost_system-vc100-mt-gd-1_58.lib
Boost_SYSTEM_LIBRARY_RELEASE
E:/boost_1_58_0/boost_1_58_0/stage/lib/boost_system-vc100-mt-1_58.lib
Boost_THREAD_LIBRARY_DEBUG
E:/boost_1_58_0/boost_1_58_0/stage/lib/boost_system-vc100-mt-gd-1_58.lib
Boost_THREAD_LIBRARY_RELEASE
E:/boost_1_58_0/boost_1_58_0/stage/lib/boost_thread-vc100-mt-1_58.lib
visual studio project settings
C/C++ -> General -> Additional Include Directories:
...bunch of my other dependencies
E:\boost_1_58_0\boost_1_58_0
Linker -> General -> Additional Library Directories
E:/boost_1_58_0/boost_1_58_0/stage/lib;E:/boost_1_58_0/boost_1_58_0/stage/lib/$(Configuration);%(AdditionalLibraryDirectories)
Linker -> General -> Link Library Dependencies - No
Linker -> General -> Use LIbrary Dependency Inputs - No
Linker -> Input -> Additional Dependencies:
...bunch of my other .libs
boost_thread.lib
boost_system.lib
I fixed the error but I had try what I call the "dumb" way. The "smart" way didnt work. Smart way was reviewing several times the cmakelists code and the visual studio include library settings. i even did a clean and rebuild boost using b2 and manually set threading=multi and link=static because i thought maybe the library just wasnt built correct.
Finally i gave up and tried the dumb way: I cut and pasted the pthread folder and moved it somewhere else, so that it was no longer in the boost/thread folder, only the win32 folder.
I wish i tried it so long ago, because i didnt think that the compilation error would be due to my project's code, but rather an environment setting in the include and linking. But sure enough i got an error showing that in one of my project's files i was directly trying to include that mutex.hpp from the pthread folder. i didnt write this code (its open source) so i couldnt have exactly known, but still i want to slap myself
#include <boost/thread.hpp>
#include <boost/thread/pthread/mutex.hpp>
changing pthread to win32 made the error go away.

Why is Visual Studio Trying to Link 'freeglutd.lib'?

I'm trying to compile an OpenGL program using Visual Studio 2013, but I get the following error:
Error 1 error LNK1104: cannot open file
'freeglutd.lib' ...
For reference, I have FreeGLUT installed and have configured VS to search the correct directories for the include files and library files. Indeed, VS recognises the GLUT include files just fine. I've also added opengl32.lib and freeglut.lib to the Additional Dependencies.
Why is VS looking for 'freeglutd.lib'? It's definitely not listed in the Additional Dependencies. I can solve the compilation error by renaming 'libglut.lib' to 'libglutd.lib' and removing the former from the dependencies, but I'm just curious why it's behaving this way.
Speaking of Additional Dependencies, is adding opengl32.lib actually necessary? I can compile my (very basic) program without it, but more than one person has said it's required, perhaps for older versions of Visual Studio?
if you check the freeglut_std.h (freeglut V3.0):
/* Link with Win32 shared freeglut lib */
# if FREEGLUT_LIB_PRAGMAS
# ifdef NDEBUG
# pragma comment (lib, "freeglut.lib")
# else
# pragma comment (lib, "freeglutd.lib")
# endif
# endif
so if you don't define NDEBUG, the linker will link to "freeglutd.lib",
you can solve that by defining a NDEBUG in "PreprocessorDefinitions".
Good luck!
Hey man I don't know if you're still having this error but here is a solution. Pretty much the "freeglutd.lib" has to do with debugging, hence the "d" on the end, so what I did was go into the:
Properties > C/C++ > Preprocessor > Preprocessor Definitions and type NDEBUG. Then OK and Apply.
What this does is in the "freeglut_std.h" there is a ifdef for NDEBUG that if it is defined then use "freeglut.lib" otherwise it's going to use the "freeglutd.lib". So by defining it in the Preprocessor Definitions, you are now using the "freeglut.lib". Hopefully this helps you out!
Possibly already answered: freeglut error LNK1104
Also two things to check for:
Are you building in debug or release mode? The d at the end of freeglutd.lib suggests that it's a library meant for debug builds
Try creating a new project from scratch, put some basic runnable code in it that uses freeGLUT and see if VS is linking properly. This will also verify if for some reason the project file of the previous project was corrupted (as #RobertHarvey suggested) or the problem is somewhere else
I solved this problem by compiling freeglut and freeglut_static from generated CMake soluton in Debug mode - freeglutd was created in the lib/Debug directory. You can put this directory into lib path then and it will work!

Installing and Linking OpenCV 2.4.3 on 64 bit windows with CMake

I am currently attempting to transition a CMake project from Linux to Windows that is dependent on OpenCV, but I'm having trouble linking the libraries to the executable.
I've posted the approximate CMakeLists.txt file below with some private stuff left out:
project(my_project_name)
cmake_minimum_required(VERSION 2.8)
SET(CMAKE_CXX_FLAGS "-g -Wall")
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../bin)
FIND_PACKAGE(OpenCV REQUIRED)
IF(NOT OpenCV_FOUND)
MESSAGE(FATAL_ERROR "OpenCV not found")
ENDIF()
SET(PROJECT_HDRS
#headers here
)
SET(PROJECT_SRCS
#sources here
)
add_executable(${PROJECT_NAME} ${PROJECT_SRCS})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OpenCV_LIBS})
This CMakeLists.txt file works just fine on Linux, but has trouble linking on Windows. My first instinct was that it was a bad install of OpenCV? Here are the approximate steps I used while installing OpenCV
Download OpenCV 2.4.3 executable (a self-extracting archive)
Extract to some directory
Use CMake-Gui to configure and generate OpenCV.sln
Open in Visual Studio C++ 2010 Express and build the ALL_BUILD project in Debug and Release configurations
Build the INSTALL project
When I try to build my own project, I get back the errors "undefined reference to 'cv::waitKey(int)' errors, which makes me think that it's a linker issue. I've attempted pointing to the .lib files directly, such as:
target_link_libraries(${PROJECT_NAME} C:/someDirectory/opencv_core243.lib)
but I still get back the same errors.
I've also attempted the methods in described in these StackOverflow threads:
here and here.
I apologize beforehand if I'm missing something obvious, but this is more or less the first time I've developed on windows and I'm running out of ideas.
to my knowledge the problem is that visual studio2010 or vc++2010 comes with .net framework 4.5
Downgrade it to .net framework4 (i.e. uninstall .net 4.5 and install 4.0).
That would solve the problem...
I hit my head to my table solving the above problem..
or else
patch the visual c++ with new Service pack
it´s a little bit late but... let´s go
for me this tutorial was perfect
http://kevinhughes.ca/tutorials/opencv-install-on-windows-with-codeblocks-and-mingw/

cmake & gcc compiles every file every time

I'm a learning c++ developer writing a game initially on the Mac platform using XCode, but now moving to cross platform by leveraging CMake. So far I can get it compiled on my ickle linux netbook and I'm putting together a dev environment on this machine for on the go coding. However I'm finding that gcc recompiles every file whenever I make a change. Clearly I need some additional configuration to the CMakeLists.txt . My current one is very simple. Like so;
cmake_minimum_required (VERSION 2.8)
set (source
Creature.cpp
DisplayManager.cpp
Engine.cpp
EngineState.cpp
Entity.cpp
GameWorld.cpp
GfxSFML.cpp
Item.cpp
Map.cpp
Position.cpp
Projectile.cpp
ScreenTile.cpp
SquadAI.cpp
Terrain.cpp
UIButton.cpp
UICharPanel.cpp
UIView.cpp
Utility.cpp
Weapon.cpp
fov.cpp
main.cpp
)
find_package (OpenAL)
find_package (OpenGL)
find_package (SFML)
set(CMAKE_CXX_FLAGS "-g -Wall -pg")
add_executable (tractionedge ${source})
target_link_libraries(tractionedge ${SFML_LIBRARY} ${OPENGL_LIBRARY} ${OPENAL_LIBRARY})
I've concentrated so far on C++ as a language rather than build systems by sticking with XCode for everything. My knowledge of Autotools (make?) and Gcc is very limited. How do I have gcc only recompile the changed source?
Are you rerunning cmake every time? If you just modify one source file, you should be able to simply rerun make, and it should rebuild just the one object file before linking. If you rerun cmake, it might mark all of the source files dirty and rebuild everything.
Only rerun cmake if you change the actual list of source files being used, or other major changes like that.
Rebuilding only the modified sources SHOULD be the default behavior. Of course if you change a central header included by nearly all dependent cpp files it'll trigger a nearly complete rebuild. Look at what happens if you only modify one cpp file (adding a comment or alike), if more than that compilation unit is compiling then I propose you to invest more time investigating it eventually giving you my EMail to have a deeper look at the configuration.
Another possibility is that you are compiling under windows and using a 2.8 cmake that has a bug regarding this. Look at a 2.9 version to see if that defect is away then: http://www.mail-archive.com/cmake#cmake.org/msg24876.html
I would rewrite your CMakeLists.txt using glob (maybe move the files in a "src" directory if you have other *.cpp files around) and give your project a name (this sets some important variables):
cmake_minimum_required (VERSION 2.8)
project(TRACTION)
file (GLOB TRACTION_SOURCES *.cpp)
find_package (OpenAL)
find_package (OpenGL)
find_package (SFML)
set(CMAKE_CXX_FLAGS "-g -Wall -pg")
add_executable (tractionedge ${TRACTION_SOURCES})
target_link_libraries(tractionedge ${SFML_LIBRARY} ${OPENGL_LIBRARY} ${OPENAL_LIBRARY})
I also experienced unnecessary rebuilds using cmake and visual studio. The problem is related to an inappropriate x64 configuration parameter: Visual Studio 2008 Unnecessary Project Building
A simple solution in many of these cases is to completely wipe the build tree and regenerate it (and I mean something along the lines of rm -rf build && mkdir build && cd build && cmake -G "Unix Makefiles" ../src, not just make clean)

Resources