Finding package OpenCV with CMake - c++

I've done as follows:
I have set OpenCV_DIR variable to my build path set to $(OPENCV_ROOT)/build/x86/vc11/lib.
In my CMakeLists.txt I call find_package function:
find_package( OpenCV REQUIRED )
Some variables connected to OpenCV should be set, but they are set incorrectly. Ex. OpenCV_INCLUDE_DIRS should be set to
$(OPENCV_ROOT)/build/include
or
$(OPENCV_ROOT)/include
but instead of it it's set to
$(OPENCV_ROOT)/build/x86/vc11/lib/include;$(OPENCV_ROOT)/x86/vc11/lib/include/opencv
What to do to have the right paths?

I had built OpenCV from source to make sure that all the variables and options were set correctly.. For the purpose of explanation, let's say your CMAKE_INSTALL_PREFIX is set to C:/opencv/.. This is where your OpenCV_DIR variable should point to..
To your system environment path, add C:/opencv/bin/ (just so that all login instances from your computer have access to it and also makes it easier for VS to recognize it later on, in my experience) to the PATH variable.. Make sure you build both debug and release version of the projects and build the INSTALL project for both..
Hope this helps.
Side note: For easy path editing, I use a freeware called RapidEE

I was recently fighting with compilation of OpenCV to get minimal module necessary and then automatically including this in my project. I ended up using it the following way:
CMakeLists.txt:
find_package(OpenCV CONFIG REQUIRED PATHS <path to the install dir>)
target_link_directories(<target> PUBLIC
${OpenCV_LIB_DIRS}
)
target_link_libraries(<target>
${OpenCV_LIBS}
)
target_include_directories(<target> PUBLIC
${OpenCV_INCLUDE_DIRS}
)
Using cmake 3.16
OpenCV 4.x

Related

Correct way to build OpenCV as a third party library along with your project in CMAKE

I have a C++ project, where I use opencv, VTK. I would like to build and install these dependent libraries (opencv,vtk) automatically, which are situated in my thirdparty project folder. I know that opencv and VTK use cmake build system to build their libraries. I even saw the function ExternalProject to add them to my CMakesLists.txt but I had problem of linking the target with opencv libs.
Searching on stack overflow I could not find a proper defined method to do it to implement this for version 3.0, the proposed solutions where Version < 3.0. I would like to know how you will structure your project to build opencv automatically as a thirdparty library, exports its targets and link it with my project target.
I think that the best way is to look for what's being done on larger project on github. I would advise to look at this repo in which they use opencv version 3.2, automatically download it and compile it. I believe that this is the correct way because you just have to change the version to try the compatibility with the newer versions if you want to update your code.
What you are looking for is probably what is called a superbuild. This post might help.
I would suggest to build and install opencv in a subfolder of your repo or your build directory. Then you could set the OpenCV_DIR environment variable to the <opencv_install_prefix>/lib/cmake/opencv4 folder (or at least point to the folder where OpenCVConfig.cmake is)
Then in your CMakeLists.txt you can directly use :
find_package(OpenCV 4 REQUIRED
COMPONENTS core imgproc ximgproc)
target_link_libraries(${PROJECT_NAME} PUBLIC ${OpenCV_LIBS})
The OpenCV_DIR variable tells CMake where to find the OpenCV configuration files needed for find_package function.
For the build and installation step, you could use ExternalProject or FetchContent (I prefer the later) but since OpenCV could be very long to build, you might want to keep the build artifact outside of your project's build folder. Then you can erase your build folder to rebuild your project without rebuilding the whole OpenCV library.
On my side, I'm using a shell script that build OpenCV if needed before building the project that needs it.

How to set up OpenCV with cmake to enable dynamic and static builds?

I've built and make installed opencv on my mac with SHARED_LIBS.
I want to be able to choose for each project if I built with or without shared libs.
When I compile an additional OpenCV build with -DBUILD_SHARED_LIBS=OFF how can I reference it in my project's CMakeLists and chose the build type I want?
I have the source with shared libs in my ~/opencv and I've already compiled it in ~/opencv/build followed by make install.
When I create another dir like ~/opencv/static_build how would I have to adapt my CMakeLists in order to make a static build app? So far I've used:
find_package( OpenCV REQUIRED )
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(test ${OpenCV_LIBS})
But if I'm not mistaken, these lines all depend variables which have been added to cmake during my inital make install.
It works by configuring a different install location with the cmake flag -D CMAKE_INSTALL_PREFIX for each build and make install will then install them to their respective locations.
In order to distinguish between the specific builds and to allow cmake to find the library if it not in its path, one has to add the following line to the project's CMakeLists.txt:
set(OpenCV_DIR /path/to/build/lib/cmake)
before:
find_package( OpenCV REQUIRED )

How to know variable such as 'OpenCV' in CMake

I am using OpenCV with gcc and cmake. And I found a tutorial https://docs.opencv.org/3.4.0/db/df5/tutorial_linux_gcc_cmake.html .In the file CMakeLists.txt, there are some variables such as OpenCV and OpenCV_INCLUDE_DIRS.
cmake_minimum_required(VERSION 3.9)
project(VideoRecord)
set(CMAKE_CXX_STANDARD 11)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(VideoRecord main.cpp)
target_link_libraries(VideoRecord ${OpenCV_LIBS})
I want to know where to find these variables definition.
EDIT
Thanks #qbranchmaster's answer. I tried to search FindOpenCV.cmake but failed.
First try.
➜ ~ cmake --help-module-list | grep "FindOpen"
FindOpenACC
FindOpenAL
FindOpenCL
FindOpenGL
FindOpenMP
FindOpenSSL
FindOpenSceneGraph
FindOpenThreads
Another try.
➜ / find . "FindOpenCV.cmake"
In addition, my os is osx and I install cmake with brew. I comiple and install OpenCV manually.
These variables are part of the package config script shipping with OpenCV.
Note that find_package is a two-headed beast. The classic mode of operation is finding libraries through find-scripts. This is still the approach being used today for third-party libraries that are not aware of CMake. However, if your dependency is itself being built with CMake, it can provide a package config file instead, which allows for a more powerful mode of operation.
The idea here is that instead of you telling CMake how to find a dependency, the dependency itself tells CMake how clients can find it. This is the approach that is taken by libraries like OpenCV and Qt.
To answer your question, those variables are being set by the package config file in your local OpenCV installation, the template of which can be found in the OpenCV source code under cmake/templates/OpenCVConfig.cmake.in.
They are defined in CMake OpenCV module. CMake has numerous modules that aid in finding various libraries like OpenCV (FindOpenCV.cmake module).
Using this command you can get a list of modules that your CMake supports:
cmake --help-module-list
Some libraries come with their own *.cmake modules which should be installed in some system path. If you are using Ubuntu, your cmake modules should be localised in:
/usr/share/cmake/Modules/
If not, just search system for file FindOpenCV.cmake. In that file you will find these variables.
In general, you get variable names from the documentation or source code of the package you want to find.
Often you can derive the name to put into find_package from the provided FindFoo.cmake module file name, because "Foo" would be the name. The find module is either part of CMake or comes with the third-party library.
If there is no find module, some modules provide FooConfig.cmake files, where "Foo" is again the string to put into find_package.
If you have neither a find nor a config file, you need to find the library by other means, e.g., FindPkgConfig or find_library / find_file.

Setup CMake with SFML in VS2017

Just like in CLion I want to use SFML with Visual Studio 2017, but I'm still learning cmake and I don't know the commands or the logic of how cmake works at all. I've just seen some posts and got this litle script.
Note: I downloaded the latest version of sfml in the link provided, I just taked the extrated directory and put alongside CMakeLists.txt in my folder
#sets up the minimum version of cmake
cmake_minimum_required(VERSION 3.9)
#how the project will be called
project (space_impact)
#set c++11 standard
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" -std=c++11)
#set source files
set (SOURCE_FILES main.cpp)
#we add the executable of the program
add_executable (space_impact ${SOURCE_FILES})
#taked from a mac-clion tutorial, doesn't work
set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/SFML/cmake-modules/")
find_package (SFML REQUIRED system window graphics network audio)
if (SFML_FOUND)
include_directories(${SFML_INCLUDE_DIR})
target_link_libraries(space_impact ${SFML_LIBRARIES})
endif()
that thing gave me errors:
Error CMake Error at SFML/cmake-modules/FindSFML.cmake:355 (message):
Could NOT find SFML (missing: SFML_SYSTEM_LIBRARY SFML_WINDOW_LIBRARY
SFML_GRAPHICS_LIBRARY SFML_NETWORK_LIBRARY SFML_AUDIO_LIBRARY) SFML/cmake-modules/FindSFML.cmake
I want everything to be dynamic, but I don't know how can I do that..
So my question is what should I do for setting up correctly SFML with Cmake in Visual Studio.
I don't want the old-fashioned method from the official website
UPDATE
Here's my location....
The thing is.. the FindSFML.cmake script it's not working...
What files should I move for make it working?
Your script is perfectly fine, except three things I'd change:
Move the whole module detection before defining targets. I'm pretty sure you also have to define your include directories before.
Your if(SFML_FOUND) bracket is pretty pointless right now, because you've set SFML to be required, which means it will never get past find_package() unless it's found.
-std=c++11 is a GCC only flag (MSVC will always use the latest standard, unless specified). As such you'll have to check the compiler here or use CMAKE_CXX_STANDARD.
So the "cleaned" CMakeLists.txt could look like this:
#sets up the minimum version of cmake
cmake_minimum_required(VERSION 3.9) # personally I'd set this version as low as required; you don't have to require the cutting edge version
#how the project will be called
project (space_impact)
#set the C++ standard to be used
set (CMAKE_CXX_STANDARD 11)
#set source files
set (SOURCE_FILES main.cpp)
#look for SFML and add it
set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/SFML/cmake-modules/")
find_package (SFML REQUIRED system window graphics network audio)
include_directories(${SFML_INCLUDE_DIR})
#we add the executable of the program
add_executable (space_impact ${SOURCE_FILES})
target_link_libraries(space_impact ${SFML_LIBRARIES} ${SFML_DEPENDENCIES})
Note that adding SFML_DEPENDENCIES to the library list is optional, unless you're using a static version of SFML.
But what about your SFML issue? Since you don't have the SFML files installed in any directory looked into by default, you'll have to tell CMake where it's found using the CMake variable SFML_ROOT or the environment variable of the same name.
So the first time you're invoking CMake, it could look like this:
cmake -G "Visual Studio 15 2017" -DSFML_ROOT=path/to/sfml path/to/source
This is all you need to compile sfml in your cmake project.
find_package(SFML 2.5.1 COMPONENTS system graphics audio network REQUIRED)
add_executable (AwesomeProject "AwesomeProject.cpp" "AwesomeProject.h")
target_link_libraries(AwesomeProject PRIVATE sfml-audio sfml-graphics sfml-network sfml-system)
Also set SFML_DIR var to your sfml folder.

How to link QtMain in CMake with Qt5?

I upgraded my project code from Qt4 to Qt5. It uses CMake.
The conversion got well except for one line of Cmake commands related to Qt.
I can’t find in current documentation, like
http://qt-project.org/doc/qt-5.0/qtdoc/cmake-manual.html
http://qt-project.org/doc/qt-5.0/qtdoc/qtmain.html
How to link with QtMain from CMake (with Qt5)?
It is the only missing bit to convert my project.
Can someone point me to a doc explaining this or explain how to do it with Qt5? My Qt4 code worked correctly but I can't find the Cmake macro for Qt5.
EDIT> Here is the CMake file I have at the moment: https://bitbucket.org/klaim/aos_qt5/src/593c195c4c6889f6968d68fca018ef425783a063/tools/aosdesigner/CMakeLists.txt?at=wip_qt5
All qt5 necessary CMake macros have been set correctly I belive, the only thing that don't work is the linking to QtMain that do nothing, as expected since there should be a Qt5 specific way of doing it that I don't find in the Qt5 documentation.
You can browse the file history to see how it was working with Qt4.
From the Qt docs you linked to, it seems you can find Qt5Core instead of Qt5Widgets. That will create an imported target named Qt5::WinMain. From the Qt docs:
Imported targets are created for each Qt module. That means that the Qt5<Module>_LIBRARIES contains a name of an imported target, rather than a path to a library.
...
Each module in Qt 5 has a library target with the naming convention Qt5::<Module>
find_package( Qt5Widgets REQUIRED )
find_package( Qt5Core REQUIRED )
...
add_executable( aosdesigner WIN32 ${AOSDESIGNER_ALL_FILES} )
target_link_libraries( aosdesigner
${Boost_LIBRARIES}
utilcpp
aoslcpp
Qt5::WinMain # <-- New target available via find_package ( Qt5Core )
)
qt5_use_modules( aosdesigner Widgets )
I'd also recommend that you remove your two link_libraries calls since it's a deprecated command and I'd specify CMake version 2.8.9 rather than just 2.8 as the minimum required at the top of your CMakeLists.txt, since that's required for qt5_use_modules.
As of CMake 2.8.11 and Qt 5.1, linking to Qt5::WinMain is automatic/implicit if you specify WIN32 in your add_executable call, or otherwise set the WIN32_EXECUTABLE target property.
The presentation at
https://devdays.kdab.com/wp-content/uploads/2012/cmake.pdf
with video at
http://www.youtube.com/watch?feature=player_detailpage&v=GJ0kMsLbk6Q#t=751
describes the features which made it into CMake 2.8.11.
For more about CMake with Qt see
http://www.kdab.com/modern-cmake-with-qt-and-boost/
EDIT : Thanks to Archi comment (see below), simply add
target_link_libraries(<your_app> Qt5::WinMain)
or
target_link_libraries(<your_app> ${Qt5Core_QTMAIN_LIBRARIES})
in your application's CMakeLists.txt. Both syntaxes worked for me.