CMake has the ability to search our dependencies and external libraries, giving us the ability to build complex projects, depending on the external components in our projects, and add some requirements.
In this book, the most important dependency is, of course, OpenCV, and we will add it to all of our projects:
cmake_minimum_required (VERSION 3.0)
PROJECT(Chapter2)
# Requires OpenCV
FIND_PACKAGE( OpenCV 4.0.0 REQUIRED )
# Show a message with the opencv version detected
MESSAGE("OpenCV version : ${OpenCV_VERSION}") # Add the paths to the include directories/to the header files
include_directories(${OpenCV_INCLUDE_DIRS}) # Add the paths to the compiled libraries/objects
link_directories(${OpenCV_LIB_DIR})
# Create a variable called SRC
SET(SRC main.cpp)
# Create our executable
ADD_EXECUTABLE(${PROJECT_NAME} ${SRC})
# Link our library
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OpenCV_LIBS})
Now, let's understand the working of the script from the following:
The first line defines the minimum CMake version, and the second line tells CMake to use the new behavior of CMake to facilitate recognition of the correct numbers and Boolean constants without dereferencing variables with such names; this policy was introduced in CMake 2.8.0, and CMake warns when the policy is not set from version 3.0.2. Finally, the last line defines the project title. After defining the project name, we have to define the requirements, libraries, and dependencies:
# Requires OpenCV
FIND_PACKAGE( OpenCV 4.0.0 REQUIRED )
# Show a message with the opencv version detected
MESSAGE("OpenCV version : ${OpenCV_VERSION}")
include_directories(${OpenCV_INCLUDE_DIRS})
link_directories(${OpenCV_LIB_DIR})
Here is where we search for our OpenCV dependency. FIND_PACKAGE is the function that allows us to find our dependencies, the minimum version required, and whether this dependency is required or optional. In this sample script, we look for OpenCV in version 4.0.0 or greater and state that it is a required package.
The FIND_PACKAGE command includes all OpenCV submodules, but you can specify the submodules that you want to include in the project by executing your application smaller and faster. For example, if we are only going to work with the basic OpenCV types and core functionality, we can use the following command: FIND_PACKAGE(OpenCV 4.0.0 REQUIRED core).
If CMake does not find it, it returns an error and does not prevent us from compiling our application. The MESSAGE function shows a message in the terminal or CMake GUI. In our case, we are showing the OpenCV version as follows:
OpenCV version : 4.0.0
The ${OpenCV_VERSION} is a variable where CMake stores the OpenCV package version. include_directories() and link_directories() add to our environment the headers and the directory of the specified library. OpenCV CMake's module saves this data in the ${OpenCV_INCLUDE_DIRS} and ${OpenCV_LIB_DIR} variables. These lines are not required in all platforms, such as Linux, because these paths normally are in the environment, but it's recommended to have more than one OpenCV version to choose the correct link and include directories. Now is the time to include our developed sources:
# Create a variable called SRC
SET(SRC main.cpp)
# Create our executable
ADD_EXECUTABLE(${PROJECT_NAME} ${SRC})
# Link our library
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OpenCV_LIBS})
This last line creates the executable and links the executable with the OpenCV library, as we saw in the previous section, Creating a library. There is a new function in this piece of code, SET; this function creates a new variable and adds to it any value that we need. In our case, we incorporate the main.cpp value in the SRC variable. We can add more and more values to the same variable, as can be seen in the following script: