Добавил:
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()
- •Виды конфигураций
- •Выражения генераторов
- •Информационные выражения
- •Логические выражения
- •Преобразующие выражения
- •Вспомогательные выражения
- •Упражнения
- •Тест рубежного контроля
- •Проектное задание
- •Интерфейс подключения библиотек
- •Подключение заголовочной библиотеки
- •Частичная подмена стандартной библиотеки
- •Интерфейс подключения библиотек
- •Локализация приложения
- •Установка приложения
- •Инструменты разработки
- •Управление версиями
- •Генерирование документации
- •Упражнения
- •Тест рубежного контроля
- •Проектное задание
- •Заключение
- •Библиография
- •Ответы на тесты

EXE_PATH bin/ex-qt-deploy${CMAKE_EXECUTABLE_SUFFIX})
include(DeployQt4)
install_qt4_executable(
"${EXE_PATH}" # исполняемый файл
"" # модули
"" # библиотеки
"${QT_LIBRARY_DIR}") # каталоги
Здесь вызываются команды install() (п. 2.10.3), ко-
3.3. Qt
торые добавляют к цели установки правила копирования исполняемого файла — результата выполнения цели
ex-qt-deploy и скомпилированных файлов локализации
(список их путей в переменной QM_FILES возвращается командой qt5_create_translation() или qt5_add_translation()).
Дальше вызывается команда install_qt4_executable(),
которая добавляет к цели установки правило копирования
разделяемых библиотек. Ей передаётся путь к исполняемому
файлу в переменной EXE_PATH относительно каталога установки. На момент выполнения правила исполняемый файл уже
должен находиться по указанному пути благодаря командам
install(). Имя файла состоит из имени цели (предполагается, что имя исполняемого файла не изменяется установкой
свойства OUTPUT_NAME для цели) и зависящего от системы
расширения, которое хранится в специальной переменной
CMAKE_EXECUTABLE_SUFFIX.
341

3. Примеры использования пакетов
Кроме относительного пути к исполняемому файлу, команде install_qt4_executable() передаётся путь
поиска библиотечных файлов. Эта передача использована исключительно для наглядности: она необязательна, так как путь записывается в переменную с именем
QT_LIBRARY_DIR, и команда install_qt4_executable() будет её также использовать для получения путей библиотек.
Путь поиска библиотек Qt получается выделением каталога (команда get_filename_component(), п. 2.9.1) из пути к библиотеке QtCore, который содержится в свойстве
IMPORTED_LOCATION_RELEASE импортируемой цели Qt5::Core.
Следует отметить, что конфигурация «Release» предоставляется
всеми сборками инструментария Qt, в отличие от конфигурации «Debug», которой, например, нет в сборках для систем
на основе Linux.
Для удобства можно создать в каталоге построения следующий сценарий (build.cmd, на примере использования системы
MinGW):
@echo off
set PATH=C:\Qt5.5.0\Tools\mingw492_32\bin;%PATH%
set GEN="MinGW Makefiles"
set QT_PATH=C:\Qt5.5.0\5.5\mingw492_32
set PREFIX_PATH=D:\install\ex-qt-deploy
set PROJECT_PATH=D:\Work\ex-qt-deploy
cmake^
342

3.4. Crypto++
-G %GEN%^
-D CMAKE_PREFIX_PATH=%QT_PATH%^
-D CMAKE_INSTALL_PREFIX=%PREFIX_PATH%^
%PROJECT_PATH%
Здесь в переменную окружения PATH добавляется путь поиска инструментов компилятора MinGW, поставляемого вместе с Qt, в переменную QT_PATH — путь к библиотекам Qt, необходимый для команды find_package() (п. 2.11.1), в переменные PREFIX_PATH и PROJECT_PATH — пути к каталогам установки и проекта. Используя этот сценарий, можно выполнить сборку и установку приложения при помощи следующих команд:
build.cmd
mingw32-make
mingw32-make translations
Дальше, если файл перевода в каталоге проекта ещё не был
заполнен, необходимо сделать это при помощи инструмента
Qt Linguist и повторно запустить последнюю команду:
mingw32-make translations
В конце необходимо выполнить цель установки:
mingw32-make install
Приведённый здесь код CMake способен создать цель установки приложения и разделяемых библиотек вне зависимости
от того, какие именно библиотеки (Qt или какие-либо другие)
используются приложением. ∗
343

3. Примеры использования пакетов
3.4. Crypto++
Crypto++12является объектно-ориентированной и шаблон-
ной библиотекой, реализующей популярные криптографические алгоритмы и схемы, а именно:
— схемы аутентифицированного шифрования;
— потоковые и блочные шифры, вместе с режимами их при-
менения;
— коды аутентификации сообщений;
— хеш-функции;
— криптосистемы с открытым ключом;
— схемы обмена ключами;
— алгоритмы эллиптической криптографии;
— вспомогательные алгоритмы, включая арифметику целых
чисел, многочленов и конечных полей, генерирование
псевдослучайных чисел, схему разделения секрета, функции выведения ключей и т. д.
Библиотека распространяется по лицензии Boost Software
License и широко используется в открытых, коммерческих
и научно-образовательных проектах. Библиотека совместима
с большим количеством платформ и компиляторов.
Существенным отличием библиотеки Crypto++ от рассмотренных ранее является то, что как сама библиотека не имеет
12
http://www.cryptopp.com/ (дата обращения: 21.07.2015).
344

3.4. Crypto++
поддержки CMake, так и в CMake отсутствует модуль поиска
этой библиотеки. Вместе с исходными кодами библиотеки поставляется make-файл для инструмента GNU make, который совместим с POSIX-системами и компиляторами gcc, clang, Intel C
++
Compiler и т. д., а также (после правок) — с gcc-MinGW. Кроме этого, с библиотекой поставляются файлы проектов для среды Microsoft Visual Studio. При помощи этих систем поддерживаются
следующие варианты сборки:
— В POSIX-совместимых системах возможна сборка в виде
статической библиотеки (файл libcryptopp.a) или разделяемой (файл libcryptopp.so). Результирующий файл
создаётся в каталоге исходных файлов. Цель установки
install позволяет установить файлы библиотеки, необходимые для разработчика, в требуемый каталог, со структурой, изображённой на рис. 3.15. Кроме того, эти файлы могут быть установлены из системных репозитариев в стандартные каталоги (например, /usr/include/crypto++
и /usr/lib).
— Аналогичным образом в системе Windows при помощи то-
го же самого make-файла и инструментов gcc-MinGW можно получить такие же файлы с той разницей, что вместо разделяемой библиотеки libcryptopp.so будет создана динамическая cryptopp.dll вместе с библиотекой импорта libcryptopp.dll.a (рис. 3.15).
— В системе Windows при использовании среды Microsoft Vi-
sual Studio также доступны два варианта сборки библиоте-
345

3. Примеры использования пакетов
hкаталог установкиi
bin
cryptopp.dll ........ только в Windows (MinGW)
cryptest.exe
include
cryptopp
...........................заголовочные файлы
lib
libcryptopp.a
libcryptopp.dll.a ...только в Windows (MinGW)
libcryptopp.so ........только в POSIX-системах
Рис. 3.15. Структура каталога с установленными файлами
библиотеки Crypto++
ки. В первом вся библиотека создаётся в виде одного ста-
тически подключаемого модуля (cryptlib.lib). Во втором
часть алгоритмов выносится в динамическую библиоте-
ку cryptopp.dll с соответствующей библиотекой импор-
та cryptopp.lib. Оставшиеся алгоритмы хранятся в ста-
тической библиотеке с тем же именем cryptlib.lib. Ди-
намическую библиотеку в этом случае можно использо-
вать как совместно со статической, так и отдельно. Оба ва-
рианта сборки помещаются соответственно в подкаталоги
Output и DLL_Output каталога исходных файлов библиоте-
ки (рис. 3.16). Целью такого разделения является возмож-
ность использования двоичного файла cryptopp.dll, про-
346
шедшего процедуру проверки Национальным институтом
стандартов и технологий США (NIST) на соответствие феде-
ральным стандартам обработки информации FIPS 140-2.

hкаталог исходных файловi
hназвание архитектурыi ........................Win32 или x64
DLL_Output
hназвание конфигурацииi ...........Debug или Release
cryptopp.dll
cryptest.exe
dlltest.exe
cryptlib.lib
cryptopp.lib
...
Output
hназвание конфигурацииi ...........Debug или Release
cryptest.exe
cryptlib.lib
...
3.4. Crypto++
...
...
Рис. 3.16. Структура каталога с собранными файлами
библиотеки Crypto++ при помощи среды Microsoft Visual
Studio
В случае использования динамического варианта библиотеки, собранного при помощи Visual C++, необходимо также
учитывать ещё одну связанную с этим проблему. Дело в том,
что проект библиотеки для этой среды содержит настройки
для её построения с ключами компилятора /MTd и /MT в режимах Debug и Release соответственно (подробнее об этих ключах см. в описании примера использования библиотеки OpenCV
на с. 258). Из этого следует, что библиотека Crypto++ будет связана со статическими версиями функций диспетчера динамической памяти стандартной библиотеки поддержки выполнения программ. Это означает, что библиотека и вызывающее
347

3. Примеры использования пакетов
её приложение будут использовать разные области динамической памяти. А это представляет собой серьёзную проблему, так
как часто возникает потребность выделения области памяти
в приложении с последующим её освобождением в библиотеке13(см. пример далее). Библиотека Crypto++ предлагает три возможных варианта решения проблемы, выполняя попытки их
использования при отображении в адресное пространство работающего процесса в следующей последовательности:
1) В каждом загруженном в адресное пространство процесса исполняемом модуле ищется экспортируемая функция с именем GetNewAndDeleteForCryptoPP(). Если она
там есть, она вызывается, возвращая адреса функций
operator new () и operator delete () этого модуля
для дальнейшего использования библиотекой. В итоге приложение и библиотека будут использовать одну и ту же область динамической памяти. Этот вариант больше подходит для случая, когда приложение использует нестандартный диспетчер памяти. Однако он неработоспособен, если
приложение связано со статической версией стандартной
библиотеки поддержки выполнения программ (в этом случае динамическая память инициализируется позже инициализации библиотеки).
2) Если функция из пункта 1 не экспортируется модулем, но при этом им экспортируется функция с именем SetNewAndDeleteFromCryptoPP(), то она вызывается,
13
http://stackoverflow.com/questions/1634773/
freeing-memory-allocated-in-a-different-dll (дата обращения: 27.07.2015).
348

3.4. Crypto++
при этом ей передаются адреса функций operator new ()
и operator delete () библиотеки Crypto++. Предполагается, что приложение сохранит эти адреса для дальнейшего использования.
3) Если функции из пунктов 1 и 2 отсутствуют во всех загруженных в процесс модулях, библиотека Crypto++ пытается
найти функции operator new () и operator delete (),
экспортируемые динамической версией стандартной библиотеки поддержки исполнения программ. Для работоспособности данного варианта требуется обеспечить загрузку
этой библиотеки до библиотеки Crypto++.
Анализ приведённых возможностей решения проблемы
показывает, что наиболее универсальным и простым в реализации из них является вариант 2.
Поскольку, как уже было отмечено, в системе CMake от-
сутствует модуль поиска библиотеки Crypto++, как и в самой
библиотеке отсутствует конфигурационный файл для системы
CMake, логику подключения этой библиотеки необходимо реализовывать самостоятельно. Сформулируем требования для нашей реализации:
— Поддержка должна быть реализована в виде, удобном для
повторного использования.
— Для связывания цели с библиотекой должно быть доста-
точно подключения реализуемого модуля CMake и вызова команды target_link_libraries(), аналогично набору библиотек Qt.
349

3. Примеры использования пакетов
— Реализация должна быть кроссплатформенной.
— Реализация должна иметь возможность подключать биб-
лиотеку, как собранную при помощи make-файла, так
и при помощи среды Visual Studio.
— Реализация должна уметь находить файлы библиоте-
ки, как расположенные непосредственно в каталоге
исходных файлов после построения, так и установленные целью install или из стандартных репозитариев
системы. Каталоги поиска файлов должны зависеть от значений специальных переменных CMAKE_PREFIX_PATH,
CMAKE_LIBRARY_PATH и других, влияющих на поведение
команд find_library() и т. д. (п. 2.9.2).
— Реализация должна выбирать статический или дина-
мический/разделяемый вариант сборки библиотеки
в зависимости от значения специальной переменной
BUILD_SHARED_LIBS.
— При использовании динамической версии библиотеки, со-
бранной в среде Visual Studio, к проекту должен автоматически подключаться исходный модуль для поддержки совместного использования приложением и библиотекой общей области динамической памяти, реализованный в варианте 2.
— Реализация должна выбирать правильную версию библио-
теки для разных конфигураций построения проекта.
350
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
