
Making the script more complex
In this section, we will show you a more complex script that includes subfolders, libraries, and executables, all in only two files and a few lines, as shown in this script.
It's not mandatory to create multiple CMakeLists.txt
files because we can specify everything in the main CMakeLists.txt
file. It is more common to use different CMakeLists.txt
files for each project subfolder, making it more flexible and portable.
This example has a code structure folder that contains one folder for the utils
library and the other for the root
folder, which contains the main executable:
CMakeLists.txt main.cpp utils/ CMakeLists.txt computeTime.cpp computeTime.h logger.cpp logger.h plotting.cpp plotting.h
Then, we need to define two CMakeLists.txt
files: one in the root
folder and the other in the utils
folder. The CMakeLists.txt
root folder file has the following contents:
cmake_minimum_required (VERSION 2.6) project (Chapter2) # Opencv Package required FIND_PACKAGE( OpenCV 3.0.0 REQUIRED ) #Add opencv header files to project include_directories( ${OpenCV_INCLUDE_DIR} ) link_directories(${OpenCV_LIB_DIR}) add_subdirectory(utils) # Add optional log with a precompiler definition option(WITH_LOG "Build with output logs and images in tmp" OFF) if(WITH_LOG) add_definitions(-DLOG) endif(WITH_LOG) # generate our new executable add_executable( ${PROJECT_NAME} main.cpp ) # link the project with his dependencies target_link_libraries( ${PROJECT_NAME} ${OpenCV_LIBS} Utils)
Almost all the lines are described in the previous sections except for some functions that we will explain in later sections.
The add_subdirectory()
tells CMake to analyze the CMakeLists.txt
of a desired subfolder.
Before we continue with an explanation of the main CMakeLists.txt
file, we will explain the utils CMakeLists.txt
file.
In the CMakeLists.txt
file in the utils
folder, we will write a new library to include it in our main project folder:
# Add new variable for src utils lib SET(UTILS_LIB_SRC computeTime.cpp logger.cpp plotting.cpp ) # create our new utils lib add_library(Utils ${UTILS_LIB_SRC} ) # make sure the compiler can find include files for our library target_include_directories(Utils PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
This CMake script file defines an UTILS_LIB_SRC
variable where we add all the source files included in our library, generate the library with the add_library
function, and use the target_include_directories
function to allow our main project to detect all header files.
Leaving out the utils
subfolder and continuing with the root cmake
script, the Option function creates a new variable—in our case, WITH_LOG
, with a small description attached. This variable can be changed via the ccmake
command line or CMake GUI interface, where the description and a checkbox appears that allow users to enable or disable this option.
This function is very useful and allows the user to decide about compile-time features such as enabling or disabling logs, compiling with Java or Python support as with OpenCV, and so on.
In our case, we use this option to enable a logger in our application. To enable the logger, we use a precompiler definition in our code:
#ifdef LOG logi("Number of iteration %d", i); #endif
To tell our compiler that we require the LOG
compile time definition, we use the add_definitions(-DLOG)
function in our CMakeLists.txt
. To allow the user to decide whether they want to enable it or not, we only have to verify whether the WITH_LOG
CMake variable is checked or not with a simple condition:
if(WITH_LOG) add_definitions(-DLOG) endif(WITH_LOG)
Now, we are ready to create our CMake script files to be compiled in any operating system our Computer Vision projects. Then, we will continue with the OpenCV basics before we start with a sample project.