Managing dependencies

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:

cmake_minimum_required (VERSION 3.0) 
cmake_policy(SET CMP0012 NEW) 
PROJECT(Chapter2) 

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 libraryThere 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:

SET(SRC main.cpp 
        utils.cpp 
        color.cpp
)