Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Система построения проектов CMake. Учебник.pdf
X
- •Введение
- •Модульное программирование
- •Автоматизация построения проектов
- •Обзор инструментов построения проектов
- •qmake
- •Генераторы
- •Входные файлы
- •Пути
- •Синтаксис
- •Команды
- •Упражнения
- •Тест рубежного контроля
- •Проектное задание
- •Основные концепции
- •Строки
- •Свойства
- •Примеры простых проектов
- •Команды общего назначения
- •cmake_minimum_required()
- •project()
- •include()
- •message()
- •Команды описания целей
- •add_executable()
- •add_library()
- •add_subdirectory()
- •Команды настроек целей
- •include_directories()
- •target_include_directories()
- •add_definitions(), add_compile_options()
- •target_compile_definitions()
- •target_compile_options()
- •target_compile_features()
- •target_link_libraries()
- •add_dependencies()
- •Команды обработки данных
- •math()
- •list()
- •Команды управляющих конструкций
- •foreach(), endforeach()
- •Команды работы с файлами
- •get_filename_component()
- •Команды добавления специальных целей
- •configure_file()
- •add_test(), enable_testing()
- •install()
- •add_custom_target()
- •Прочие команды
- •find_package()
- •get_property(), set_property()
- •Виды конфигураций
- •Выражения генераторов
- •Информационные выражения
- •Логические выражения
- •Преобразующие выражения
- •Вспомогательные выражения
- •Упражнения
- •Тест рубежного контроля
- •Проектное задание
- •Интерфейс подключения библиотек
- •Подключение заголовочной библиотеки
- •Частичная подмена стандартной библиотеки
- •Интерфейс подключения библиотек
- •Локализация приложения
- •Установка приложения
- •Инструменты разработки
- •Управление версиями
- •Генерирование документации
- •Упражнения
- •Тест рубежного контроля
- •Проектное задание
- •Заключение
- •Библиография
- •Ответы на тесты

2.6. Команды настроек целей
— Для передачи компоновщику дополнительных библиотек
используется команда target_link_libraries() (п. 2.6.7).
При помощи этой же команды можно передать компонов-
щику любые аргументы.
— Для передачи компилятору аргументов, делающих доступ-
ными возможности новых стандартов языков C и C++, ис-
пользуется команда target_compile_features() (п. 2.6.6).
— Для передачи компоновщику дополнительных путей поис-
ка библиотек используется команда link_directories().
Впрочем, в реальных ситуациях эта команда почти ни-
когда не нужна, так как при добавлении библиотек
от других целей или найденных при помощи команд
find_library() (п. 2.9.2) и т. д. компоновщику будет пере-
дан полный путь к библиотеке.
2.6.4. target_compile_definitions()
target_compile_definitions(
hимя_целиi
INTERFACE
f
hопределение
PUBLIC
1,1
PRIVATE
i ... hопределение
f
INTERFACE
f
hопределение
PUBLIC
2,1
PRIVATE
i ... hопределение
1,m
i
2,n
N
g
g
i
g
...
)
101

2. Основы языка CMake
Команда target_compile_definitions() доступна в системе CMake начиная с версии 2.8.11. Эта команда аналогична
команде add_definitions() (п. 2.6.3), однако позволяет добавлять определения символов препроцессора через командную
строку вызовов компилятора не только для указанной цели,
но и автоматически для всех целей, зависимых от данной, аналогично команде target_include_directories() (п. 2.6.2).
2.6.5. target_compile_options()
target_compile_options(
g
hимя_целиifBEFORE
INTERFACE
f
hаргумент
PUBLIC
i ... hаргумент
1,1
PRIVATE
1,m
g
i
f
INTERFACE
f
hаргумент
...
PUBLIC
i ... hаргумент
2,1
PRIVATE
2,n
g
i
g
)
Команда target_compile_options() доступна в CMake
начиная с версии 2.8.12. Эта команда аналогична команде
add_compile_options() (п. 2.6.3), однако позволяет передавать
аргументы компилятору не только для указанной цели, но и автоматически для всех целей, зависимых от данной, аналогично
команде target_include_directories() (п. 2.6.2).
102

2.6. Команды настроек целей
— При помощи необязательного аргумента BEFORE можно до-
бавлять аргументы компилятора в начало их списка вместо конца (по умолчанию).
2.6.6. target_compile_features()
target_compile_features(
hимя_целиi
INTERFACE
hвозможность1i ... hвозможностьni)
Команда target_compile_features() доступна в CMake
начиная с версии 3.1.0. Эта команда предназначена для передачи специфических для используемого компилятора
аргументов, включающих заданные возможности новых
стандартов языков C и C++. Передаваемые команде возможности должны быть перечислены в специальных переменных
CMAKE_C_COMPILE_FEATURES и CMAKE_CXX_COMPILE_FEATURES.
Эти переменные содержат список возможностей, поддерживаемых выбранным компилятором, и являются подмно-
PUBLIC
PRIVATE
жествами глобальных свойств CMAKE_C_KNOWN_FEATURES
и CMAKE_CXX_KNOWN_FEATURES. См. пример на с. 214, который
демонстрирует вывод на печать значений этих свойств.
— Аргументы INTERFACE, PUBLIC и PRIVATE позволяют пере-
давать ключи компилятора не только для указанной цели,
но и автоматически для всех целей, зависимых от данной.
Их смысл аналогичен таким же аргументам для команды
target_include_directories() (п. 2.6.2).
103

2. Основы языка CMake
Если выбранный для построения компилятор не поддерживает указанную возможность, обработка описания проекта
системой CMake прерывается и генерация файлов для конечной системы построения не выполняется (аналогично команде
message(FATAL_ERROR ...), п. 2.4.4).
Замечание: хотя эта команда появилась в CMake версии 3.1.0,
имеет смысл использовать её как минимум с CMake версии 3.3.0,
так как в ней стала доступной информация о возможностях ком-
++
пиляторов gcc, Microsoft Visual C
и т. д. Для более новых ком-
пиляторов необходимо использовать более позднюю версию
CMake.
ПРИМЕР
Пусть необходимо скомпилировать следующую программу:
#include <iostream>
int main()
{
auto n = 0b0’0100’1011;
std::cout << n << std::endl;
}
N
Для этого необходимо включить соответствующие возможности компилятора C++14:
cmake_minimum_required(VERSION 3.2.0)
project(ex-cpp14)
104

2.6. Команды настроек целей
add_executable(ex-cpp14 ex-cpp14.cpp)
target_compile_features(
ex-cpp14
PRIVATE
cxx_auto_type
cxx_binary_literals
cxx_digit_separators)
∗
Замечание: на момент написания учебника приведённый вы-
ше пример работал с компиляторами Microsoft Visual C++2015
и gcc-MinGW 4.9.2.
N
2.6.7. target_link_libraries()
target_link_libraries(
g
hимя_целиifhстрока1i ... hстрокаni
f
f
debug
...
optimized
generalghстрокаi
g
)
target_link_libraries(
hимя_целиi
INTERFACE
PUBLIC
PRIVATE hстрока1i ... hстрокаmi
105

2. Основы языка CMake
f
INTERFACE
PUBLIC
PRIVATE hстрока1i ... hстрокаni
...
g
)
Команда предназначена для определения подключаемых
библиотек к заданной цели или произвольных аргументов командной строки, передаваемых компоновщику.
Замечание: имя цели должно быть определено в том же самом
каталоге проекта, внутри описания которого вызывается эта команда.
Команда определяет тип аргументов, начиная со второго,
N
по следующим правилам:
1) Если передаваемая строка начинается с символов «-l»
или «-framework», то оставшаяся часть строки интерпре-
тируется как имя библиотеки (без префикса lib и расши-
рения) или каркаса OS X соответственно.
2) Иначе, если передаваемая строка начинается с символа «-», она интерпретируется как аргумент командной
строки для компоновщика и во время построения передаётся ему без изменения.
3) Иначе, если строка совпадает с именем другой цели, ранее определённой при помощи команды add_library()
106
(п. 2.5.2), текущая цель будет строиться с использованием
библиотеки, которая является результатом построения указанной цели. Кроме этого, устанавливается зависимость

2.6. Команды настроек целей
при построении текущей цели от указанной, аналогично
команде add_dependencies() (п. 2.6.8).
4) Иначе строка должна представлять путь к файлу библиотеки, которая будет использована при построении цели.
Несколько команд target_link_libraries(), последова-
тельно исполняемых для одной и той же цели, добавляют новые
настройки к процессу её компоновки.
Использование команды также транзитивно переносит
на зависимую цель требования, определённые для целей связываемых библиотек при помощи интерфейсных аргументов команд target_include_directories() (п. 2.6.2) и других, имеющих префикс «target_».
Замечание: по умолчанию (см. ниже) устанавливаемые от-
ношения зависимости между целями при помощи команды
target_link_libraries() являются транзитивными, т. е. распространяются на зависимые цели. Это может оказаться нужным при построении приложения, использующего функции
из библиотеки, которая, в свою очередь, использует другие библиотеки. Даже если библиотеки являются статическими, следовательно, одни библиотеки физически никак не участвуют
в компоновке других библиотек, они все вместе будут использоваться при компоновке приложения.
ПРИМЕР
# ...
N
107

2. Основы языка CMake
add_library(lib_aa STATIC ...)
add_library(lib_ab STATIC ...)
add_library(lib_a STATIC ...)
target_link_libraries(lib_a lib_aa lib_ab)
add_executable(prog ...)
target_link_libraries(prog lib_a)
Здесь при компоновке исполняемого файла prog будут использоваться статические библиотеки, получаемые в результате построения целей lib_aa и т. д. Граф зависимостей между
проектами изображён на рис. 2.8. ∗
lib_aa
prog
lib_a
lib_ab
Рис. 2.8. Граф зависимостей между целями исполняемого
файла и библиотек
— При помощи необязательных аргументов debug,
optimized или general можно ограничить действие
108
следующего аргумента на различные конфигурации:
debug: следующий аргумент будет применяться в конфи-
гурации Debug и всех конфигурациях, перечисленных
в глобальном свойстве DEBUG_CONFIGURATIONS.

2.6. Команды настроек целей
optimized: следующий аргумент будет применяться
во всех остальных конфигурациях.
general: следующий аргумент будет применяться во всех
конфигурациях, как и в случае, когда перед настройкой не указан никакой из этих трёх аргументов.
— Во второй форме команды, появившейся в CMake вер-
сии 2.8.12, перед аргументами, определяющими подключаемые библиотеки, можно указывать аргументы
INTERFACE, PUBLIC и PRIVATE. Они позволяют переопределять стандартное поведение, когда настройки компоновщика транзитивно передаются зависимым целям. Их
смысл аналогичен таким же аргументам для команды
target_include_directories() (п. 2.6.2).
ПРИМЕР
Пусть требуется связать приложение с библиотекой Qt Core. Эта
библиотека, как и остальные из набора Qt, поставляется в двух
вариантах построения: отладочная (с окончанием «d») и предназначенная для конечного пользователя. Правильный вариант
в соответствии с конфигурацией построения самого приложения можно выбрать при помощи следующей команды:
target_link_libraries(
myprog debug -lQt5Cored optimized -lQt5Core)
∗
109

2. Основы языка CMake
Замечания:
— Приведённый выше пример предназначен исключи-
тельно для демонстрации использования команды
target_link_libraries() совместно с аргументами
debug и optimized. Более предпочтительный способ
подключения библиотек Qt описан в п. 3.3.1.
— Не имеет смысла устанавливать зависимость при компо-
новке от целей библиотек, собираемых при помощи ко-
манд add_library(hимяi MODULE ...) (п. 2.5.2), поскольку
такой тип библиотек предназначен только для динамиче-
ского связывания.
ПРИМЕР
Пусть требуется создать проект динамической (разделяемой)
библиотеки. При использовании компилятора Microsoft Visual
C++в таблицу экспорта динамических библиотек попадают только те функции, которые в объявлении имеют атрибут описания
__declspec (dllexport). Можно создать заголовочный файл
my_dll.h вида:
int __declspec (dllexport) my_dll_f();
// ...
N
Этот файл нужно будет подключить перед определением функции my_dll_f() и всех других, которые необходимо экспортировать. С другой стороны, в коде клиента библиотеки эти же функции требуется объявить без атрибута
__declspec (dllexport). Более того, чтобы компилятор смог
110
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
