Евлахов, Анатолий Сергеевич
- 1 year ago
- 0
- 0
CMake ( МФА [ ˈ s i ː m e ɪ k ]; от англ. cross-platform make — кроссплатформенный make ) — кроссплатформенное программное средство автоматизации сборки программного обеспечения из исходного кода . Не занимается непосредственно сборкой, а лишь генерирует файлы сборки из предварительно написанного файла сценария CMakeLists.txt и предоставляет простой единый интерфейс управления. Помимо этого, способно автоматизировать процесс установки и сборки пакетов .
Считается альтернативой распространённой в сообществе GNU системе Autotools , разработанной на базе Perl и M4 , основными недостатками которой считаются необходимость нетривиальных навыков для практического использования и несовместимость версий в ряде случаев.
В сравнении с другой альтернативой Autotools — системой SCons , основанной на Python , является более быстродействующей, поскольку написана на Си и использует крайне простой макроязык , но при этом SCons обладает большими возможностями по расширению.
Разработка CMake началась в 1999 году в ответ на потребность в кроссплатформенной системе сборки для , финансируемой национальной библиотекой медицины США части . Задача по разработке была возложена на небольшую компанию . На него повлияла более ранняя система pcmaker, созданная Кеном Мартином ( Ken Martin ) и другими разработчиками для поддержки инструментария визуализации ( VTK ).
В то время обычным считалось использование и make-файлов для сборки программных проектов на Unix-платформах и файлов проектов Visual Studio в среде Windows . Такой подход к разработке вызывал огромное неудобство, например, добавление одного файла исходного кода в проект приводило к большим трудностям, так как для каждой платформы это приходилось делать по отдельности и совершенно разными методами. Очевидно, что разработчики нуждались в единой унифицированной системе сборки, не отнимающей лишнее время .
Ключевой особенностью является возможность размещать выходные данные компилятора (например, объектные файлы) вне дерева исходного кода. Это позволяет выполнять несколько вариаций сборок из одного и того же исходного кода, а также кросскомпиляцию . Такой подход разделения файлов исходного кода и файлов сборки даёт гарантию, что удаление каталога сборки не приведёт к удалению исходного кода. Однако сами пользователи не защищены от случайного удаления каталога с исходными файлами .
CMake может находить общесистемные и пользовательские каталоги исполняемых файлов, файлов конфигураций и библиотек. Эти местоположения хранятся в кэше , который можно конфигурировать перед созданием целевых файлов сборки. CMake-кэш можно редактировать с помощью графического редактора, который поставляется вместе с CMake, либо в командной строке с помощью команд CMake.
Сложные иерархии каталогов проектов, рассчитанные на разные конфигурации, сборка с разными библиотеками и инструментами также хорошо поддерживаются CMake. По сути CMake предоставляет возможность создавать подпроекты, собираемые перед сборкой основного проекта, что позволяет создавать цепочки зависимостей, собираемые в необходимой разработчику последовательности.
CMake может создавать файлы проектов для нескольких популярных интегрированных средств разработки , в том числе Microsoft Visual Studio , Xcode и Eclipse CDT .
Может создавать сценарии сборки для MSBuild и в Windows, make на Unix-подобных системах, Ninja . Для упрощения внедрения поддержки CMake в новые среды разработки используются файлы преднастройки CMakePresets.json . Среди сред, изначально поддерживающих CMake — CLion , KDevelop , Qt Creator , Visual Studio .
CMake позволяет определять свойства, которые компилятор должен поддерживать, чтобы скомпилировать целевую программу или библиотеку .
CMake поддерживает обширный список компиляторов, в который входят в том числе Clang (включая Clang из Xcode ), GNU GCC , MSVC , SunPro , Intel C++ .
Сборка программы или библиотеки с помощью CMake представляет собой двухэтапный процесс. На первом этапе стандартные файлы сборки генерируются из файлов конфигурации ( CMakeLists.txt ), которые написаны на языке CMake. Затем задействуются системные инструменты сборки, такие как make, Ninja, используемые для непосредственной компиляции программ .
Файлы сборки конфигурируются в зависимости от используемого генератора (например, генератор «Unix Makefiles» — для make-фaйлов). Продвинутые пользователи могут создавать и включать свои собственные генераторы файлов Make для поддержки новых компиляторов и операционных систем. Сгенерированные файлы обычно помещаются (с помощью флага CMake) во внешний каталог, за пределами исходных файлов, например в каталог build .
После сборки каждый проект в подкаталогах содержит CMakeCache.txt и каталог make-файлов, что помогает избежать или ускорить этап «перегенерации» в случае повторного запуска сборки .
В зависимости от конфигурации CMakeLists.txt и выбранной цели файлы сборки могут создавать:
CMake может создавать объектные файлы, которые могут быть связаны с исполняемыми программами или библиотеками, избегая динамического (во время выполнения) связывания, вместо этого используя статическое связывание. Это обеспечивает гибкость в настройке различных оптимизаций (зависимости сборки могут определяться автоматически).
Начиная с версии CMake 3.6 можно создавать предварительно скомпилированные заголовочные файлы .
CMake имеет относительно простой интерпретируемый императивный язык сценариев , поддерживающий переменные , методы обработки строк , массивы , объявления функций и макросов , включение модулей (импортирование). Команды языка CMake (или директивы) считываются CMake из файла CMakeLists.txt . В этом файле указываются исходные файлы и параметры сборки, которые CMake размещает в спецификации сборки проекта (например, в make-файле). Кроме того, файлы с приставкой .cmake могут содержать сценарии, используемые CMake.
Аргументы команд разделены пробелами и могут содержать ключевые слова для разделения групп аргументов. Например, в команде:
# Команда установки
install(TARGETS ... # цели
CONFIGURATIONS ... # конфигурации (Debug, Release…)
RUNTIME DESTINATION ...) # (исполняемый файл, MACOSX_BUNDLE, DLL) место_назначения
ключевые слова —
TARGETS
,
CONFIGURATIONS
и
RUNTIME DESTINATION
. В данном случае
TARGETS
и
CONFIGURATIONS
служат разделителями между «целями» и «конфигурациями»
.
Примеры команд CMake, которые определяют цели и их зависимости :
add_executable
(
...
)
— определяет цель (исполняемый файл, например
.exe
, зависит от целевой платформы);
add_library
(
...
)
— определяет цель (библиотеку, например
.so
или
.dll
);
target_link_libraries
(
...
)
— определяет зависимости указанной цели.
CMake поддерживает извлечение значений данных в переменные из строк JSON (начиная с версии 3.19) .
CMake поставляется с большим количеством модулей и инструментов .cmake . Они облегчают такую работу, как поиск зависимостей (как встроенных, так и внешних, например, модули FindXYZ ), инструменты для тестирования исполняемых файлов, упаковка (модуль CPack и команда cpack ) и управление зависимостями от внешних проектов (модуль ExternalProject ) :
Начиная с версии 2.4.2 в состав CMake включены система автоматизированной сборки пакетов программного обеспечения и модуль CMake для взаимодействия с ней. Система позволяет создавать пакеты программного обеспечения для популярных пакетных менеджеров ( DEB , RPM , DMG ), средства установки программного обеспечения ( NSIS для Microsoft Windows , Qt Installer Framework для систем, работающих с Qt ), а также архивы со сборкой ( TGZ , TBZ2 , ZIP , самораспаковывающийся TGZ ) .
Среди проектов с открытым исходным кодом, использующих CMake — Boost , Blender , ReactOS , MySQL , KDE , FreeCAD , WebKit . Среди закрытых проектов, собираемых с использованием CMake — программное обеспечение эксперимента ATLAS , медицинский проект , внутренние системы Netflix и Second Life .
Проект « Hello, World! » на языке CMake:
# Файл — «CMakeLists.txt»
cmake_minimum_required(VERSION 3.16) # Выбираем минимальную необходимую версию cmake
project(my_project) # Присваиваем имя проекту
add_executable( # Создаём цель (исполняемый файл)
${PROJECT_NAME} # Имя файла
main.cpp # Список файлов исходного кода
) # Добавлять заголовочные файлы нет необходимости
install( # Указываем цель и путь установки
TARGETS ${PROJECT_NAME} # Путь прибавляется к префиксу
RUNTIME DESTINATION bin # bin - binary (путь к исполняемым файлам)
) # Стандартный префикс для UNIX систем
# "/usr/local" + "/bin"
// файл — «main.cpp»
# include <iostream>
int main()
{
std::cout << "Hello, World!" << std::endl;
return 0;
}
Сборка осуществляется посредством следующих команд в каталоге с файлами:
cmake . # Вызываем генерацию файлов сборки
cmake --build . # Собираем цель, на выходе получаем исполняемый файл
cmake --install . # По необходимости устанавливаем
При этом есть возможность получить справочную информацию об отдельном элементе языка CMake и его команд.
cmake --help
cmake --help-command-list
cmake --help-command install