Issue
I would like to use opencv inside my project folder because my other colleagues are not all working on the same platform (Linux, Windows). So to make it easier to clone and compile the project, I would like to have only to make a clone git and launch the compilation to be able to work on the project. (without any use of environnement variable, to be totaly independent)
As with other libraries (glfw), I simply added the unzipped folder inside my dependencies folder. Then I added the add_subdirectory and target_link_libraries statements.
Then I get a small error that I can't solve.
Information about my project below
1. Project folder structure
project
│ README.md
| CMakeLists.txt (my CMakeLists project)
└───dependencies
│ └───opencv-4.1.2
│ │ CMakeLists.txt (the original opencv CMakeLists (untouched))
│ │ ...
└───src
│ main.cpp
2. my CMakeLists content
cmake_minimum_required(VERSION 3.15)
project(OpTests)
set(CMAKE_CXX_STANDARD 17)
add_subdirectory(dependencies/opencv-4.1.2)
add_executable(OpTests src/main.cpp)
target_link_libraries(OpTests opencv_core opencv_highgui opencv_imgproc opencv_videoio)
3. main.cpp content
#include <iostream>
#include <opencv2/opencv.hpp>
int main() {
std::cout << CV_VERSION << std::endl;
cv::Mat M(2,2, CV_8UC3, cv::Scalar(0,0,255));
std::cout << "M = " << std::endl << " " << M << std::endl << std::endl;
std::cout << "Hello, World!" << std::endl;
return 0;
}
4. The error
°
°
°
--
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jeremy/CLionProjects/OpTests/cmake-build-debug
[ 3%] Built target ittnotify
[ 9%] Built target ippiw
[ 18%] Built target libjasper
[ 45%] Built target libwebp
[ 69%] Built target opencv_core
[ 90%] Built target opencv_imgproc
[ 93%] Built target opencv_imgcodecs
[ 96%] Built target opencv_videoio
[100%] Built target opencv_highgui
Scanning dependencies of target OpTests
[100%] Linking CXX executable bin/OpTests
CMakeFiles/OpTests.dir/src/main.cpp.o: In function `cv::String::~String()':
/usr/include/opencv2/core/cvstd.hpp:664: undefined reference to `cv::String::deallocate()'
CMakeFiles/OpTests.dir/src/main.cpp.o: In function `cv::String::operator=(cv::String const&)':
/usr/include/opencv2/core/cvstd.hpp:672: undefined reference to `cv::String::deallocate()'
collect2: error: ld returned 1 exit status
CMakeFiles/OpTests.dir/build.make:88: recipe for target 'bin/OpTests' failed
make[3]: *** [bin/OpTests] Error 1
CMakeFiles/Makefile2:81: recipe for target 'CMakeFiles/OpTests.dir/all' failed
make[2]: *** [CMakeFiles/OpTests.dir/all] Error 2
CMakeFiles/Makefile2:88: recipe for target 'CMakeFiles/OpTests.dir/rule' failed
make[1]: *** [CMakeFiles/OpTests.dir/rule] Error 2
Makefile:186: recipe for target 'OpTests' failed
make: *** [OpTests] Error 2
So 3 questions:
What did I do wrong? And is it possible to simply fix it without a 100 lines CMakeLists?
Is this a bad practice?
Thank you in advance
Beautiful day
Solution
As far as I know the preferred way is to install OpenCV and then require it.
Therefore clone the repo of OpenCV, build and install it:
git clone [email protected]:opencv/opencv.git
cd opencv
make -j8
sudo make install
This can also be achieved by using a pre-build package from a package manager...
Then you can use the library in cmake via:
cmake_minimum_required(VERSION 3.15)
project(OpTests)
find_package(OpenCV 4.2 REQUIRED)
add_executable(OpTests src/main.cpp)
target_link_libraries(OpTests PRIVATE
${OpenCV_LIBS}
)
target_compile_features(OpTests PRIVATE cxx_std_17)
Note that the library can be required using find_package
and added as a dependency using the target_link_libraries
command.
Also note that you should set the c++ version using target_compile_features
.
To get a better understanding of cmake you can refer to the talk of Daniel Pfeifer https://www.youtube.com/watch?v=bsXLMQ6WgIk.
Answered By - Arwed Mett Answer Checked By - Clifford M. (WPSolving Volunteer)