Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Система построения проектов CMake. Учебник.pdf
Скачиваний:
0
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
☆
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
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]