CMake From Beginner to Expert: A Modern C++ Build System Guide

Click the blue text to follow us

CMake From Beginner to Expert: A Modern C++ Build System Guide

CMake From Beginner to Expert: A Modern C++ Build System Guide

Hello everyone, I am an old coder! Today we will discuss the complex issue of building C++ projects. Are you still troubled by tedious compilation and linking? Still manually managing dependencies? Come on, let me introduce you to CMake, this powerful build system tool, which will surely make your project builds simple and elegant!

1

What is CMake?

CMake is like the blueprint for building a house. You can’t let the workers build the house without any plan, right? Similarly, we need to tell the compiler how to build our C++ project. CMake generates build files for various platforms (like Visual Studio project files on Windows and Makefiles on Linux) by writing a CMakeLists.txt file.

2

Your First CMake Project

Let’s start with the simplest example:

# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(HelloWorld)
add_executable(hello_world main.cpp)
// main.cpp
#include <iostream>
int main() {
    std::cout << "Hello, CMake!" << std::endl;
    return 0;
}

Tip: CMake commands are case insensitive, but I recommend developing the habit of using lowercase, as it looks cleaner.

3

Project Structure Organization

In actual projects, we usually have multiple source files and header files. CMake provides many convenient commands to organize the project structure:

# Add subdirectory
add_subdirectory(src)
# Find source files
file(GLOB SOURCES "src/*.cpp")
# Create library
add_library(mylib STATIC ${SOURCES})
# Set include directories
target_include_directories(mylib PUBLIC include)

Note: While file(GLOB ...) is convenient, it’s better to explicitly list source files in actual projects to better control the build process.

4

Dependency Management

Modern C++ projects cannot do without third-party libraries, and CMake excels in this area:

# Find package
find_package(Boost REQUIRED COMPONENTS system filesystem)
# Link library
target_link_libraries(myapp     PRIVATE         mylib        Boost::system        Boost::filesystem)

Tip: Using PRIVATE, PUBLIC, and INTERFACE keywords can control the transitivity of dependencies, avoiding unnecessary dependency spread.

5

Conditional Compilation and Configuration

CMake can also generate different code based on different platforms and configurations:

if(WIN32)    target_compile_definitions(myapp PRIVATE WIN32_LEAN_AND_MEAN)endif()
# Configuration file
configure_file(    "${PROJECT_SOURCE_DIR}/config.h.in"    "${PROJECT_BINARY_DIR}/config.h")

6

Build and Install

Once the project is written, the final steps are building and installing:

mkdir build && cd build
cmake ..
cmake --build .
# Install rules
install(TARGETS myapp    RUNTIME DESTINATION bin    LIBRARY DESTINATION lib    ARCHIVE DESTINATION lib)

7

Practical Exercise

Try to complete this small task:

  1. Create a calculator library that includes functions for addition, subtraction, multiplication, and division.
  2. Create an executable program that uses this library.
  3. Add unit test support (Tip: you can use GTest).

8

Common Pitfalls Reminder

  1. Use forward slashes / for paths, not backslashes \.
  2. Remember to set the C++ standard: set(CMAKE_CXX_STANDARD 17).
  3. When using the MSVC compiler on Windows, pay attention to character set settings.

9

Summary

Today we learned:

  • The basic concepts and uses of CMake.
  • How to create and organize CMake projects.
  • Methods of dependency management.
  • Conditional compilation and configuration.
  • The building and installation of projects.

That’s all from the old coder! Today’s C++ practice ends here. Writing is not easy, so don’t forget to like! Everyone is welcome to share their experiences using CMake in the comments. Wishing all programmer friends thick hair and plenty of job offers! See you next time!

Light up the 【like and watch】, let money and love flow to you.

Leave a Comment