CMake
CMake — кроссплатформенная система управления сборкой программного обеспечения, в частности, позволяющая генерировать файлы для IDE и систем сборки.
CMake де-факто стал стандартом в экосистеме C/C++ и используется во многих проектах.
Язык
CMake предоставляет скриптовый язык для описания процесса сборки: Reference.
cmake_minimum_required
cmake_minimum_required(VERSION <min>[...<max>] [FATAL_ERROR])
Устанавливает минимальную и максимальную требуемую версию CMake для проекта.
cmake_minimum_required(VERSION 3.25.0)
cmake_minimum_required(VERSION 3.20...3.25 FATAL_ERROR)
set и unset
# normal variable
set(<variable> <value>... [PARENT_SCOPE])
unset(<variable> [PARENT_SCOPE])
# cache variable
set(<variable> <value>... CACHE <type> <docstring> [FORCE])
unset(<variable> CACHE)
# environment variable
set(ENV{<variable>} [<value>])
unset(ENV{<variable>})
Устанавливает заданное значение для переменной скрипта, кеша или окружения.
Выражение<value>...
, означает, что ожидается ноль или более аргументов.
set(PROJECT_NAME "app")
set(SOURCES "main.cpp" "lib.hpp" "lib.cpp")
unset(SOURCES)
Ветвления
if(<condition>)
<commands>
elseif(<condition>) # optional block, can be repeated
<commands>
else() # optional block
<commands>
endif()
Поддерживаются:
- логические операторы (
NOT
,AND
,OR
) - проверки переменных
- проверки на существование (
COMMAND
,POLICY
,TARGET
,TEST
) - операции над путями к папкам или файлам
- сравнения (в т.ч.
MATCHES
), сравнение версий
add_subdirectory
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL] [SYSTEM])
Добавляет подкаталог в сборку; source_dir
указывает каталог, в котором
находится исходный CMakeLists.txt
и файлы кода.
Если указаны относительные пути, они будут оцениваться по отно шению к текущему каталогу (обычное использование), но это также может быть и абсолютный путь.
add_executable
add_executable(
<name> [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL]
[source1 ] [source2 ...]
)
Добавляет исполняемый файл с именем <name>
для сборки из исходных файлов,
перечисленных в вызове команды. Имя должно быть уникальным в рамках проекта.
add_executable(app
"src/main.cpp"
"src/fs/file-system.hpp"
"src/fs/file-system.cpp"
)
Модули в проекте
File Tree:
project/
├─ lib-as-module/
│ ├─ include/
│ ├─ src/
│ └─ CMakeLists.txt # Lib CMake
│
├─ app/
│ ├─ src/
│ └─ CMakeLists.txt # App CMake
│
└─ CMakeLists.txt # Root CMake
Root CMake:
cmake_minimum_required(VERSION 3.25.0)
project("project")
add_subdirectory("lib-as-module")
add_subdirectory("app")
set_property(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
PROPERTY VS_STARTUP_PROJECT "app"
)
Lib CMake:
set(LIB_NAME "lib-as-module")
# список заголовков, которые предоставляет библиотека
set(LIB_EXPORTS "includes/lib.hpp" "includes/lib-utils.hpp")
# список файлов-реализаций библиотеки
set(LIB_SOURCES "src/lib.cpp" "src/lib-utils.cpp")
add_library(${LIB_NAME} STATIC ${LIB_EXPORTS} ${LIB_SOURCES})
target_include_directories(${LIB_NAME} PUBLIC "include")
App CMake:
set(APP_NAME "app")
set(APP_SOURCES "src/main.cpp" "src/utils.hpp" "src/utils.cpp")
add_executable(${APP_NAME} ${APP_SOURCES})
target_link_libraries(${APP_NAME} "lib-as-module")
set_target_properties(
${APP_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)