On Fedora install CMake using dnf
$ sudo dnf install cmakeon Debian based distros you can isntall it using
$ sudo apt install cmakeCMake is an open-source, cross-platform family of tools designed to build, test and package software.
We have CMake installed now. Let’s build a C++ Hello World program using
CMake.
#include <iostream>
using namespace std;
int main(int argc, const char **argv){
if(argc < 2)
cout<<"Hello World\n";
else
cout<<"Hello "<< argv[1]<< "\n";
return 0;
}
Typically in order to build this program the command looks something like
$ g++ -o hello hello.cppNow let’s see how to compile this program using CMake
The CMakeLists.txt looks like.
cmake_minimum_required(VERSION 3.13)
project(hello)
set(CMAKE_CXX_STANDARD 11)
add_executable(hello hello.cpp)Let’s see what we have got in CMakeLists.txt.
cmake_minimum_required(VERSION 3.13): we are checking the minimum required version ofCMaketo build this project. IfCMake Version 3.13or greater not found on the system, the build won’t go ahed.project(hello): we are declearing the project name here.set(CMAKE_CXX_STANDARD 11): This will essentially tell the compiler that this project needs to be built usingC++ 11. So in the case ofgccit will set the-std=c++11compiler flag.add_executable(hello hello.cpp): Here the first argumenthellois the name of executable (ie filename in-o <filename>part of theg++command mentioned above),hello.cppis the source file required to buildhelloexe. In this case we are buildinghellousing only one.cppfile, although we can provide a whole list of input files toadd_executablefunction.
With that said let’s buld this program.
[04:04 PM][girish@battle-ship]:cmake-hello-world $ ls CMakeLists.txt hello.cpp [04:04 PM][girish@battle-ship]:cmake-hello-world $ mkdir build [04:04 PM][girish@battle-ship]:cmake-hello-world $ cd build [04:04 PM][girish@battle-ship]:build $ cmake .. -- The C compiler identification is GNU 10.2.1 -- The CXX compiler identification is GNU 10.2.1 -- Check for working C compiler: /usr/lib64/ccache/cc -- Check for working C compiler: /usr/lib64/ccache/cc - works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Detecting C compile features -- Detecting C compile features - done -- Check for working CXX compiler: /usr/lib64/ccache/c++ -- Check for working CXX compiler: /usr/lib64/ccache/c++ - works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Detecting CXX compile features -- Detecting CXX compile features - done -- Configuring done -- Generating done -- Build files have been written to: /home/girish/git/cmake-hello-world/build [04:04 PM][girish@battle-ship]:build $ make Scanning dependencies of target hello [ 50%] Building CXX object CMakeFiles/hello.dir/hello.cpp.o [100%] Linking CXX executable hello [100%] Built target hello [04:04 PM][girish@battle-ship]:build $ ls CMakeCache.txt CMakeFiles cmake_install.cmake hello Makefile [04:04 PM][girish@battle-ship]:build $ ./hello Hello World [04:04 PM][girish@battle-ship]:build $
At this point we have CMake installed on the system. Let’s now install
OpenCV.
To build OpenCV applications using C++ we need to install binary and
development packages for OpenCV and OpenCV Contrib.
On Fedora
$ sudo dnf install opencv opencv-contrib opencv-develSo now that we have installed both OpenCV and CMake let’s start building
OpenCV application. As always let’s build a Hello World program for video
using OpenCV. The C++ code for that looks something like following.
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char **argv){
// Create a VideoCapture object and open the input file
// If the input is the web camera, pass 0 instead of the video file name
VideoCapture cap(argv[1]);
// Check if camera opened successfully
if(!cap.isOpened()){
cout << "Error opening video stream or file" << endl;
return -1;
}
while(1){
Mat frame;
// Capture frame-by-frame
cap >> frame;
// If the frame is empty, break immediately
if (frame.empty())
break;
// Display the resulting frame
imshow( "Frame", frame );
// Press ESC on keyboard to exit
char c=(char)waitKey(25);
if(c==27)
break;
}
// When everything done, release the video capture object
cap.release();
// Closes all the frames
destroyAllWindows();
return 0;
}
The command to compile this hello world code would be
$ g++ -w hello_opencv.cpp -o hello-opencv $(pkg-config --cflags --libs opencv)In the command above, $(pkg-config --cflags --libs opencv) returns the include
path and the libraries for opencv.
Now let’s create a CMakeLists.txt file to build this exe using CMake.
cmake_minimum_required(VERSION 2.6)
# set the project name and version
project (temp)
#set (CMAKE_CXX_STANDARD 11)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS}) # not needed for opencv>=4.0
add_executable(hello-opencv hello_opencv.cpp)
target_link_libraries(hello-opencv ${OpenCV_LIBS})In this file CMakeLists.txt function find_package is responsible for
finding the OpenCV pakcage form the environment/package-config and setting
all of the required variable for using OpenCV as a dependency. Out of those
veriables we are using OpenCV_INCLUDE_DIRS and OpenCV_LIBS which holds
the include path for OpenCV and libraries provided by OpenCV.
To build the this program.
# go to the project directory
$ cd <proj-directory>
# create a new directory
$ mkdir build
$ cd build
# run cmake and pass the location of CMakeLists.txt as an argument to it.
$ cmake ..After running cmake .. you will have Makefile and a lot of other stuff
created in the build folder. Now go ahead and run
$ makeand you will have the binary executable for the OpenCV Hello World program
under build directory with the name hello_opencv. You can run it
$ hello_opencv <path to a video file>NOTE: There is a specific reason that you need to create a separate folder to generate build files. You can read more about that here.
This post covers the very basics of CMake (and may not be complete).
But it can be a good point to start from. For further reading following
links can be useful