Работали ли вы с CMake?

«Работали ли вы с CMake?» — вопрос из категории DevOps, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, активно использую CMake как основную систему сборки для C++ проектов. Он позволяет создавать кроссплатформенные скрипты сборки, которые генерируют Makefile, Ninja-файлы или проекты для Visual Studio и Xcode.

Пример структурированного CMakeLists.txt для проекта с библиотекой и исполняемым файлом:

cmake_minimum_required(VERSION 3.16)
project(MyCppApp VERSION 1.0.0 LANGUAGES CXX)

# Настройка стандарта C++ (например, C++17)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Создаем библиотеку из исходников
add_library(my_lib STATIC src/lib_logic.cpp include/lib_logic.h)
target_include_directories(my_lib PUBLIC include)

# Создаем исполняемый файл, который линкуется с библиотекой
add_executable(my_app src/main.cpp)
target_link_libraries(my_app PRIVATE my_lib)

# Поиск и подключение внешней зависимости (например, Boost)
find_package(Boost 1.70 REQUIRED COMPONENTS system filesystem)
if(Boost_FOUND)
    target_link_libraries(my_app PRIVATE Boost::boost Boost::system)
endif()

# Установка целей в систему
install(TARGETS my_app DESTINATION bin)
install(TARGETS my_lib DESTINATION lib)
install(DIRECTORY include/ DESTINATION include)

Часто используемые практики:

  • *`target_команды** (например,target_compile_options,target_include_directories`) для точного управления свойствами каждого компонента.
  • Генерация конфигурационных заголовочных файлов с помощью configure_file() для подстановки версий или путей.
  • Использование FetchContent или ExternalProject для управления зависимостями, которых нет в системе.