Essential Guide for CMake Beginners to Master Build Skills

Linux | Red Hat Certified | IT Technology | Operations Engineer

👇1000 people technical communication QQ group, note 【Official Account】 for faster approval

Essential Guide for CMake Beginners to Master Build Skills

1. CMake Installation

1. Download the CMake installation package from the official website, I downloaded v3.26

wget https://github.com/Kitware/CMake/releases/download/v3.26.0-rc4/cmake-3.26.0-rc4-linux-x86_64.sh

2. Locate the downloaded .sh file and execute the script using bash

bash cmake-3.26.0-rc4-linux-x86_64.sh

3. Then create a symbolic link for cmake/bin/cmake to the /bin directory

ln -s /root/download/cmake-3.26.0-rc4-linux-x86_64/bin/cmake /bin/cmake

4. Installation is complete, you can use the cmake command in the shell

Essential Guide for CMake Beginners to Master Build Skills

2. Using CMake to Compile Programs

1. Compiling a Program with a Single Source File

First, create two files in the current directory

hello.cpp

#include <iostream>
using namespace std;
int main() {
    cout << "Hello Today is 2023/2/26" << endl;
    return 0;
}

CMakeLists.txt (Note the casing of CMakeLists, do not write it incorrectly)

cmake_minimum_required (VERSION 2.8)
project (learn_cmake)
add_executable(hello hello.cpp)
The first line means the minimum required version of CMake is 2.8, the second line is the project name, and the third line: the first variable indicates that the executable file name is hello, and the subsequent parameters are the required dependencies.

Next, execute cmake . in the current directory.

[root@centOS learn_cmake]# cmake .
CMake Deprecation Warning at CMakeLists.txt:1 (cmake_minimum_required):  Compatibility with CMake < 2.8.12 will be removed from a future version of CMake. Update the VERSION argument <min> value or use a ...<max> suffix to tell CMake that the project does not need compatibility with older versions.
-- The C compiler identification is GNU 8.3.1
-- The CXX compiler identification is GNU 8.3.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /opt/rh/devtoolset-8/root/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /opt/rh/devtoolset-8/root/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (1.0s)
-- Generating done (0.0s)
-- Build files have been written to: /root/learn_cmake

Then you will find that additional files, such as Makefile, have been generated in the directory

Essential Guide for CMake Beginners to Master Build Skills

Then use GNU make to compile the program

Essential Guide for CMake Beginners to Master Build Skills

At this point, you will find that the executable program has been generated and can be executed normally

Essential Guide for CMake Beginners to Master Build Skills

2. Multiple Source Files in the Same Directory

At this point, add two dependencies in the current directory, and the execution of the main function requires these two files

add.cpp
add.h

Simply add the required .cpp files in CMakeLists.txt, the compilation steps are the same as above

Essential Guide for CMake Beginners to Master Build Skills

3. Many Source Files in the Same Directory

If there are countless source files in the same directory, adding them one by one can be very slow. At this point, you can use a function in CMake to store these source files

aux_source_directory(dir var)

This function stores all the source files in the dir directory into the var variable

Then, wherever the source files are needed, use the variable var instead

At this point, CMakeLists.txt can be optimized like this

Essential Guide for CMake Beginners to Master Build Skills

Note: The use of variables is different from Makefile; CMake uses curly braces, such as ${index}

4. Header Files in Different Folders

For centralized header files, CMake provides a very convenient function

include_directories( dir )

This function automatically searches for header files in the dir directory, equivalent to gcc’s gcc -I dir

At this point, CMakeLists.txt can be optimized like this

Essential Guide for CMake Beginners to Master Build Skills

5. Separating Header Files and Source Files, with Multiple Folders

Essential Guide for CMake Beginners to Master Build Skills

Assuming the current project directory is structured like this, with header files and source files separated and containing multiple folders

Based on the above sections 3 and 4, CMakeLists.txt can be optimized like this

Essential Guide for CMake Beginners to Master Build Skills

6. Generating Dynamic and Static Libraries

Assuming the current project directory is structured like this

inc directory stores header files

src directory stores source files

lib directory stores generated libraries

build directory stores files related to building the project, such as CMakeLists.txt. We will also execute cmake and make in this directory later

Essential Guide for CMake Beginners to Master Build Skills

At this point, CMakeLists.txt can be optimized like this

Essential Guide for CMake Beginners to Master Build Skills

Explanation:

PROJECT_BINARY_DIR is a CMake system variable, meaning the directory where the cmake command is executed. We plan to execute the cmake command in the build directory, so this variable is equivalent to the build directory

add_library(lib_name STATIC/SHARED src) # Function: Generate library.
# Parameter lib_name: Name of the library to be generated,
# Parameter STATIC/SHARED: Specify to generate a static or dynamic library,
# Parameter src: Specify the source files required for generating the library
set_target_properties redefines the output name of the library. If set_target_properties is not used, the library name will be the name defined in add_library. Refer to the official documentation for more details.
LIBRARY_OUTPUT_PATH is a CMake system variable, which means that all generated library files are placed in this directory. Here I specify that the library will be generated in the lib directory.

Start Compilation:

Execute cmake . in the build directory.

Execute make in the build directory.

Check if library files are generated in the lib directory,

If library files appear, the compilation is successful.

Essential Guide for CMake Beginners to Master Build Skills

7. Linking Library Files

We have generated library files in the lib directory, now we will write a main function to use the library files

Directory structure as follows:

lib directory stores static and dynamic libraries

main_src directory stores source files related to the main function

bin directory stores the generated executable files

Essential Guide for CMake Beginners to Master Build Skills

At this point, CMakeLists.txt can be written like this

Essential Guide for CMake Beginners to Master Build Skills

Explanation:

EXECUTABLE_OUTPUT_PATH is a CMake system variable, meaning the directory of the generated executable file. I changed it to the bin directory, so the generated executable file will appear in the bin directory.

find_library(var lib_name lib_path1 lib_path2) # Function: Find the library and store its absolute path and name in the first parameter
# Parameter var: Used to store the found library
# Parameter lib_name: Name of the library to search for, defaults to searching for dynamic libraries. To specify searching for dynamic or static libraries, you can add suffixes, such as funcname.so or funcname.a
# Parameter lib_path: The paths from which to search for the library, multiple paths can be specified
target_link_libraries(target lib_name) # Function: Link the library lib_name to the target executable file

Essential Guide for CMake Beginners to Master Build Skills

For course inquiries, add: HCIE666CCIE

↑ Or scan the QR code above ↑

If you have any technical points and content you want to see

You can leave a message below to let me know!

Leave a Comment