CMakeMiddleTechnical
Что такое CMAKE_BUILD_TYPE и какие значения он обычно принимает?
CMAKE_BUILD_TYPE управляет флагами компилятора для single-config генераторов; основные значения: Debug (-O0 -g), Release (-O3 -DNDEBUG), RelWithDebInfo (-O2 -g -DNDEBUG), MinSizeRel (-Os -DNDEBUG). Для Visual Studio/Xcode эта переменная игнорируется.
Что такое CMAKE_BUILD_TYPE
CMAKE_BUILD_TYPE — cache-переменная, которая управляет флагами компилятора и линкера для single-config генераторов (Unix Makefiles, Ninja). Она определяет, с какими оптимизациями и отладочной информацией собирается проект.
Стандартные значения
- Debug — отладочная сборка:
-O0 -g(GCC/Clang), без оптимизаций, полная отладочная информация DWARF - Release — продакшн-сборка:
-O3 -DNDEBUG, максимальная оптимизация, assert'ы отключены, без отладочных символов - RelWithDebInfo — компромисс:
-O2 -g -DNDEBUG, оптимизация + отладочные символы; используется для профилирования и анализа краш-дампов - MinSizeRel — минимальный размер:
-Os -DNDEBUG, оптимизация под размер бинаря, полезно для embedded
Как устанавливать
# При конфигурации
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
# Изменить уже существующую сборочную директорию
cmake -B build -DCMAKE_BUILD_TYPE=Debug
# Проверить, что установлено
cmake -L build/ | grep BUILD_TYPE
Установка значения по умолчанию в CMakeLists.txt
cmake_minimum_required(VERSION 3.28)
project(myapp LANGUAGES CXX)
# Установить Debug по умолчанию, если пользователь не указал иное
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING
"Build type: Debug Release RelWithDebInfo MinSizeRel" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
STRINGS Debug Release RelWithDebInfo MinSizeRel)
endif()
add_executable(myapp src/main.cpp)
target_compile_features(myapp PRIVATE cxx_std_20)
Проверка BUILD_TYPE в коде и CMake
# Условная компиляция в CMakeLists.txt
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions(myapp PRIVATE DEBUG_LOGGING=1)
endif()
# Добавить sanitizers только для Debug
if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT MSVC)
target_compile_options(myapp PRIVATE -fsanitize=address,undefined)
target_link_options(myapp PRIVATE -fsanitize=address,undefined)
endif()
Multi-config генераторы: CMAKE_BUILD_TYPE не работает
При использовании Visual Studio, Xcode или Ninja Multi-Config переменная CMAKE_BUILD_TYPE игнорируется — конфигурация выбирается при сборке:
# Конфигурация для multi-config (конфигурация не указывается)
cmake -S . -B build -G "Ninja Multi-Config"
# Сборка с выбором конфигурации
cmake --build build --config Release
cmake --build build --config Debug
# Доступные конфиги задаются через:
# set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo" CACHE STRING "")
Подводные камни
- Пустой CMAKE_BUILD_TYPE: если не установить, CMake использует пустую строку — флаги компилятора не применяются (ни оптимизация, ни отладка). Результат — «случайная» сборка.
- NDEBUG отключает assert(): в Release и RelWithDebInfo определяется
NDEBUG, что делает всеassert()no-op; если логика программы опирается на side-effects внутри assert — это тихий баг. - RelWithDebInfo != Debug по поведению: оптимизации
-O2могут инлайнить функции и переупорядочивать код, что затрудняет отладку несмотря на наличие символов. - CMAKE_BUILD_TYPE для multi-config генераторов: установка этой переменной при использовании Visual Studio молча игнорируется — распространённая ошибка в CI-скриптах.
- LTO (Link Time Optimization): для Release сборок часто добавляют
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON)— без этого LTO не включается автоматически. - Кастомные типы сборки: CMake позволяет создавать свои типы (например, Sanitize), но нужно явно задать флаги через
CMAKE_CXX_FLAGS_SANITIZEи добавить вCMAKE_CONFIGURATION_TYPES.
Common mistakes
- Объяснять CMAKE_BUILD_TYPE только по синтаксису, без жизненного цикла и стоимости.
- Игнорировать ошибки, null/empty состояния, порядок инициализации или режим сборки.
- Давать пример, который работает в демо, но ломается при изменении владельца ресурса.
- Трактовать CMake как shell-скрипт вместо описания графа таргетов.
What the interviewer is testing
- Кандидат формулирует точную модель для CMAKE_BUILD_TYPE, а не только определение.
- Пример компилируем, безопасен по lifetime и соответствует версии технологии.
- Названы trade-off, ограничения и диагностируемые симптомы ошибки.
- Разделяет configure/generate/build и использует target-based подход.