Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Система построения проектов CMake. Учебник.pdf
Скачиваний:
0
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
☆

2.5. Команды описания целей

Окончание табл. 2.4
Режим Описание Обработка Генерация
DEPRECATION Использование
зависит от настроек
устаревшей
возможности
*
При исполнении команды message(DEPRECATION ...) пове­дение системы CMake зависит от значений специальных пере­менных CMAKE_ERROR_DEPRECATED и CMAKE_WARN_DEPRECATED. Если первая из них содержит значение «истина» (см. табл. 2.1), поведение аналогично режиму FATAL_ERROR, иначе, если вто­рая содержит значение «истина», — режиму WARNING. Иначе обработка файла и генерация продолжаются, и сообщение не выводится. По умолчанию обе переменные содержат зна-
*
чение FALSE.
2.5. Команды описания целей

2.5.1. add_executable()

add_executable(
hлогическое_имя_целиi
f
WIN32
hисходный_модуль1i ... hисходный_модульni)
g f
MACOSX_BUNDLE
g f
EXCLUDE_FROM_ALL
g
81
2. Основы языка CMake
Команда добавляет к проекту цель с заданным логическим именем, построение которой из указанных исходных модулей должно привести к созданию исполняемого файла.
Имя исполняемого файла формируется из имени цели и расширения «.exe» (на платформе Windows). Изменить имя можно также при помощи установки свойства OUTPUT_NAME це­ли (см. пример на с. 214).
По умолчанию файл должен создаваться в подкаталоге построения, соответствующем текущему обрабатываемому под­каталогу проекта. Изменить этот каталог можно при помо­щи установки соответствующего свойства цели, которое изна­чально инициализируется значением специальной перемен­ной CMAKE_RUNTIME_OUTPUT_DIRECTORY. Конечные системы по­строения, которые поддерживают множественные конфигура­ции (Micsrosoft Visual Studio, XCode и т. д.), могут добавлять к это­му пути ещё один вложенный каталог, соответствующий имени используемой конфигурации (Debug, Release и т. д.).
— Передача команде необязательного аргумента WIN32
приводит к тому, что при построении для платфор-
мы Windows приложение не будет иметь создаваемой
по умолчанию консоли, даже если главной функцией
программы является функция main(), а не WinMain().
Это достигается передачей компоновщику аргумента ко-
82
мандной строки, зависящего от компилятора. Например,
для системы gcc-MinGW компоновщику передаётся ключ
-Wl,--subsystem,windows. Это бывает удобно, в част­ности, для разработки с использованием библиотек Qt.
2.5. Команды описания целей
При использовании аргумента WIN32 можно обойтись без функции WinMain(), таким образом, упростить пере­носимость кода. Для остальных платформ этот аргумент игнорируется.
— Передача необязательного аргумента MACOSX_BUNDLE сооб-
щит системе CMake, что создаваемый исполняемый файл должен быть пакетом приложения системы OS X.
— Передача необязательного аргумента EXCLUDE_FROM_ALL
приведёт к тому, что генерируемая цель будет исключена из цели «all». Таким образом, например, при работе с си­стемой make команда make или make all приведёт к по­строению данной цели, только если от неё зависимы дру­гие цели, включённые в цель «all».
Замечание: при использовании компилятора Microsoft Visual C++передачи аргумента WIN32 команде add_executable() недо-
статочно, если требуется использовать функцию main() в ка­честве точки входа. В этом случае также требуется передача компоновщику ключа «/ENTRY:mainCRTStartup» (см. пример на с. 258).
N

2.5.2. add_library()

add_library(
hлогическое_имя_целиi
f
STATIC
f
EXCLUDE_FROM_ALL
hисходный_модуль1i ... hисходный_модульni)
 
SHARED
 
MODULE
g
g
83
2. Основы языка CMake
add_library(
hлогическое_имя_целиi
hтип_библиотекиi
IMPORTED)
hтип_библиотекиi F SHARED
Первая форма команды add_library() аналогична коман-
де add_executable() (п. 2.5.1), но создаёт цель для построения библиотеки.
Имя библиотеки будет сформировано из базового име-
ни (по умолчанию соответствующего имени цели): например,
«hимяi.lib» для компилятора Microsoft Visual C++, «libhимяi.a»
для gcc и т. д.
По умолчанию библиотека будет создана в подкаталоге
построения, соответствующем текущему обрабатываемому под­каталогу проекта. Изменить расположение библиотеки можно
STATIC
 
MODULE
 
UNKNOWN
при помощи установки соответствующих свойств цели, кото­рые инициализируются значениями специальных переменных (табл. 2.5). Как и в случае с командой add_executable(), конеч­ные системы построения могут добавлять к этим путям каталог с именем используемой конфигурации.
84
2.5. Команды описания целей
Таблица 2.5
Специальные переменные, определяющие выходные
каталоги для библиотек
Переменная Виды библиотек
CMAKE_ARCHIVE_OUTPUT_DIRECTORY статические (+импорта)
CMAKE_RUNTIME_OUTPUT_DIRECTORY DLL
CMAKE_LIBRARY_OUTPUT_DIRECTORY модули, разделяемые
— Тип библиотеки можно задать при помощи необязательно-
го аргумента:
STATIC: статическая;
SHARED: динамическая (разделяемая);
MODULE: разделяемая, предназначенная исключитель-
но для загрузки при помощи функций API (POSIX dlopen() и т. п.). Такой тип библиотеки использу­ется для реализации загружаемых модулей (plugins). См. пример определения и использования такой библиотеки на с. 230.
По умолчанию создаются правила для построения разделя­емой библиотеки, если переменная BUILD_SHARED_LIBS со­держит истинное значение, и статической, если иначе.
Таблица 2.5 нуждается в пояснении. При построении все статические библиотеки помещаются в каталог, определяе­мый переменной CMAKE_ARCHIVE_OUTPUT_DIRECTORY. Аналогич­но, все загружаемые модули попадают в каталог, путь к кото-
85
2. Основы языка CMake
рому задаётся переменной CMAKE_LIBRARY_OUTPUT_DIRECTORY. Сложнее обстоит дело с разделяемыми библиотеками. Дело в том, что в POSIX-совместимых системах разделяемые библио­теки принято помещать в специальные каталоги — туда же, где находятся и статические библиотеки. При создании про­цесса динамический загрузчик исполняемого файла будет ис­кать все требуемые для него библиотеки в этих каталогах. Неко­торые из этих путей могут быть заданы системой (перемен­ная окружения LD_LIBRARY_PATH и т. д.). Другие из этих пу­тей могут храниться в относительном виде в самом исполняе­мом файле («rpath»). Если библиотеки будут расположены в дру­гом месте, загрузчик не сможет их найти. Как правило, испол­няемые файлы помещаются в каталог с именем bin, а разде­ляемые библиотеки — в находящийся рядом каталог lib. Та­ким образом, разделяемые библиотеки помещаются при по­строении в каталог, путь к которому задаётся переменной
CMAKE_LIBRARY_OUTPUT_DIRECTORY.
В системах, совместимых с Windows, динамические биб­лиотеки ищутся загрузчиком прежде всего в тех же каталогах, что и исполняемые файлы. Например, динамическая библио­тека может находиться в том же каталоге, что и использую­щая её программа. По этой причине динамические библиоте­ки создаются при построении проекта в таких системах в том же каталоге, что и исполняемые модули, т. е. путь к которо­му находится в переменной CMAKE_RUNTIME_OUTPUT_DIRECTORY. При этом для облегчения процесса подключения динамической библиотеки к использующему её приложению при её постро-
86
2.5. Команды описания целей
ении также создаётся небольшая статическая библиотека, со­держащая информацию об экспортируемых символах динами­ческой (так называемая библиотека импорта — import library). Как и другие статические библиотеки, библиотеки импорта по­мещаются в каталог, путь к которому определяется переменной
CMAKE_ARCHIVE_OUTPUT_DIRECTORY.
ПРИМЕР Пусть проект включает исполняемый файл и две библиотеки, которые он использует. Пусть структура каталога проекта соот­ветствует рис. 2.4.
my_project .................................... каталог проекта
my_library_1 .....................подкаталог библиотеки 1
...
CMakeLists.txt .........описание проекта библиотеки 1
my_library_2 .....................подкаталог библиотеки 2
...
CMakeLists.txt .........описание проекта библиотеки 2
my_program ............... подкаталог проекта программы
...
CMakeLists.txt .......... описание проекта приложения
CMakeLists.txt ..........описание проекта верхнего уровня
Рис. 2.4. Структура каталога проекта с исполняемым файлом
и двумя библиотеками
В этом случае для формирования при построении систе­мы выходных каталогов, совместимой с рекомендациями GNU, можно использовать следующее описание для системы CMake:
project(my_project)
87
2. Основы языка CMake
set(BINARY_DIR "${CMAKE_BINARY_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${BINARY_DIR}/bin")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BINARY_DIR}/lib")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${BINARY_DIR}/lib")
add_subdirectory(my_library_1)
add_subdirectory(my_library_2)
add_subdirectory(my_program)
Здесь специальная переменная CMAKE_BINARY_DIR хранит полный путь к каталогу построения проекта верхнего уровня. Вместо неё в этом примере можно использовать переменную CMAKE_CURRENT_BINARY_DIR, в которой хранится путь к катало­гу построения текущего (под)проекта.
В результате обработки этого примера инструментом CMake и сборки проекта в системе Windows каталог построения будет иметь структуру, изображённую на рис. 2.5, а в POSIX-сов­местимой системе — как на рис. 2.6. Как можно видеть, в систе­ме Windows все выходные файлы будут помещены в один ката­лог, так что при отладке приложения загрузчик сможет найти все требуемые ему библиотеки. То же самое будет справедли­вым и для систем, совместимых с POSIX. ∗
Вторая форма команды add_library() предназначена для добавления к проекту внешней заранее собранной библиоте­ки (как правило, сторонней). Как и для предыдущей формы команды, создаётся цель с заданным логическим именем, ко­торая по умолчанию имеет область видимости текущего ката-
88
2.5. Команды описания целей
build_my_project ..........................каталог построения
bin
my_library_1.dll
my_library_2.dll
my_program.exe
lib
my_library_1.lib ..................библиотеки импорта
my_library_2.lib
my_library_1
...................................промежуточные файлы
my_library_2
...................................промежуточные файлы
my_program
...................................промежуточные файлы
...
Рис. 2.5. Структура каталога построения в системе Windows
лога построения и ниже и которую можно использовать, как и остальные цели библиотек, для связывания с другими целя­ми проекта при помощи команды target_link_libraries() (п. 2.6.7). Однако в этом случае не создаётся никаких правил построения библиотеки. Чтобы указать местоположение фай­ла библиотеки для создаваемой цели, необходимо записать его в свойство цели IMPORTED_LOCATION, а также в свойства IMPORTED_LOCATION_DEBUG и т. д. для каждой используемой кон­фигурации (подробнее о конфигурациях см. п. 2.12.1) при по­мощи команды set_property() (п. 2.11.2). Для получения пути к исполняемому файлу библиотеки можно использовать коман­ду find_library() (п. 2.9.2).
Вообще говоря, использовать дополнительную команду
add_library(... IMPORTED) для того, чтобы подключить
89
2. Основы языка CMake
build_my_project ..........................каталог построения
bin
my_program ............................исполняемый файл
lib
libmy_library_1.so ............разделяемые библиотеки
libmy_library_2.so
my_library_1
...................................промежуточные файлы
my_library_2
...................................промежуточные файлы
my_program
...................................промежуточные файлы
...
Рис. 2.6. Структура каталога построения
в POSIX-совместимой системе
внешнюю библиотеку, необязательно, так как команда target_link_libraries() может получать на вход непо­средственно пути к файлам библиотек вместо логических имён их целей. Однако команда позволяет существенно упростить повторное использование библиотеки, поскольку для опре­деляемой ею цели можно настроить свойства, используемые при построении зависимых целей (например, каталоги поиска заголовочных файлов). Таким образом, эти свойства не нужно устанавливать заново для каждой цели, к которой подклю­чается библиотека. К сожалению, цель библиотеки, которая определяется этой командой, нельзя передавать первым па­раметром командам target_include_directories() (п. 2.6.2) и т. п. Однако можно устанавливать соответствующие свойства цели командой set_property() (п. 2.11.2), что менее удобно, но всё равно не влияет на удобство описания зависимых целей.
90
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]