Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Система построения проектов CMake. Учебник.pdf
Скачиваний:
0
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
☆
2.10. Команды добавления специальных целей
мент COMMAND указывать необязательно. При построении цели команды будут выполняться в порядке их указания в аргументах команды add_custom_target().
— После необязательного аргумента DEPENDS можно ука-
зать файлы, от которых должна зависеть цель. Здесь также можно указывать выходные файлы для команд add_custom_command() (п. 2.10.5), вызванных в текущем подпроекте. Команда add_custom_command() похожа на ко­манду add_custom_target(). Основное её отличие заклю­чается в том, что в ней явно указываются выходные файлы, создаваемые в результате построения цели.
— После необязательного аргумента WORKING_DIRECTORY
можно определить путь к рабочему каталогу для вызывае­мых инструментов. Относительный путь интерпретирует­ся по отношению к подкаталогу построения для текущего
(под)проекта.
— Некоторые из символов, встречающиеся в аргументах ко-
манд цели, могут иметь специальное значение в команд­ных оболочках различных систем. При использовании необязательного аргумента VERBATIM все аргументы ко­мандной строки будут при необходимости дополнены за­висящими от системы escape-символами так, чтобы они были переданы инструментам в неизменном виде. На­пример, строка «$n» будет интерпретирована оболочкой bash как подстановка значения переменной n. Чтобы пе­редать такую строку в качестве аргумента командной
191
2. Основы языка CMake
строки, необходимо добавить перед символом «$» escape-
символ «\».
— После необязательного аргумента SOURCES можно указать
исходные файлы для создаваемой цели. Эта настройка ни-
как не влияет на генерируемые правила и может быть
использована исключительно для удобства разработчика:
указанные исходные файлы будут отображаться интегри-
рованными средами как входящие в проект. Эти файлы мо-
гут иметь какое-либо отношение к построению цели. На-
пример, они могут обрабатываться вызываемыми инстру-
ментами.
ПРИМЕР Пусть требуется определить цель проекта, исполнение которой приводило бы к созданию в каталоге построения архива 7-zip с исходными файлами (содержимым каталога проекта).
В целях повторной используемости кода реализуем эту за­дачу в отдельном модуле CMake 7zip.cmake:
set(BINDIR32_ENV_NAME "ProgramFiles(x86)")
find_program(
7ZIP_EXECUTABLE
8
NAMES
7z 7za
PATHS
"$ENV{ProgramFiles}/7-Zip"
8
http://7-zip.org/ (дата обращения: 27.03.2015).
192
"$ENV{${BINDIR32_ENV_NAME}}/7-Zip"
"C:/Program Files/7-Zip"
"C:/Program Files (x86)/7-Zip"
)
if(7ZIP_EXECUTABLE)
add_custom_target(
create_archive
COMMAND
"${7ZIP_EXECUTABLE}"
a "${PROJECT_NAME}.7z" "${PROJECT_SOURCE_DIR}"
2.10. Команды добавления специальных целей
WORKING_DIRECTORY
"${PROJECT_BINARY_DIR}"
)
else()
message(
WARNING
"Could not find 7-zip archiver on this system. "
"You can manually assign a path to it to "
"7ZIP_EXECUTABLE variable.")
endif()
Здесь для получения пути к консольному архиватору 7-zip используется команда find_program() (п. 2.9.2), которая запи­сывает результат в переменную кэша 7ZIP_EXECUTABLE. По­сле аргумента PATHS ей передаются пути к каталогам, где эта программа может находиться в системе Windows. Сначала
193
2. Основы языка CMake
используются пути относительно каталогов «Program Files» и «Program Files (x86)». Пути к ним хранятся в переменных окружения ProgramFiles и ProgramFiles(x86). Так как послед­няя переменная содержит символы скобок, которые недопусти­мы с точки зрения CMake в именах переменных, это ограни­чение обходится присваиванием строки с именем переменной BINDIR32_ENV_NAME и разыменования последней в месте ис­пользования. На всякий случай также проверяются типичные пути к этим каталогам без ссылок на переменные окружения.
При определении цели create_archive используется вы­зов команды, передающей архиватору аргументы для до­бавления ко вновь создаваемому архиву с именем проек­та (переменная PROJECT_NAME) каталога проекта (переменная PROJECT_SOURCE_DIR) вместе с содержимым. Архив будет со­здан в каталоге построения (переменная PROJECT_BINARY_DIR), который назначается рабочим для команды.
Пример файла CMakeLists.txt, использующего модуль:
cmake_minimum_required(VERSION 2.8)
project(ex-7zip)
add_executable(ex-7zip ex-7zip.cpp)
include(7zip.cmake)
Здесь модуль подключается командой include() (п. 2.4.3).∗
194
2.10. Команды добавления специальных целей
2.10.5. add_custom_command()
add_custom_command(
OUTPUT hфайл1i ... hфайлmi
hкомандыi
f
MAIN_DEPENDENCY hзависимостьi
g
f
DEPENDSfhзависимость1i ... hзависимостьni
f
WORKING_DIRECTORY hкаталогi
f
VERBATIM
add_custom_command(
g f
APPENDg)
g
g g
TARGET hимя_целиi
PRE_BUILD
hкомандыi
PRE_LINK
f
WORKING_DIRECTORY hкаталогi
 
POST_BUILD
g
f
VERBATIMg)
hкомандыi F
hкоманда1i ... hкомандаki
hкомандаi F
COMMAND hпуть_к_командеifhаргумент1i ... hаргументpi
g
Первая форма команды add_custom_command() добавляет к проекту цель, построение которой реализуется инструмента­ми с заданными командами оболочки. В отличие от команды add_custom_target() (п. 2.10.4), создающей фальшивую цель, выходные файлы цели этой команды задаются явно. Также в от-
195
2. Основы языка CMake
личие от неё команда add_custom_command() не определяет ло­гического имени создаваемой цели. Предполагается, что цель должна запускаться на построение перед исполнением других целей, которые зависят от её выходных файлов.
— После аргумента OUTPUT перечисляются выходные файлы,
которые должны быть сгенерированы при построении це­ли. Относительные пути указываются по отношению к вы-
ходному каталогу текущего проекта.
— После каждого из нескольких необязательных аргумен-
тов COMMAND указывается команда оболочки для вызова инструмента вместе с аргументами. Вместо пути мож­но указать имя цели, созданной при помощи команды add_executable() (п. 2.5.1). В этом случае будет запущен исполняемый файл, создаваемый этой целью, и будет уста­новлена зависимость текущей цели от запускаемой.
— После необязательного аргумента MAIN_DEPENDENCY мож-
но указать основную зависимость. Основная зависимость полностью аналогична остальным зависимостям, указыва­емым после аргумента DEPENDS (см. далее), но для генерато­ра Visual Studio указывает, в какой проект необходимо доба­вить пользовательские команды.
— После необязательного аргумента DEPENDS можно указать
список файлов и целей, от которых должна зависеть текущая цель. Файлы могут быть, например, выходны­ми для других целей, созданных при помощи команды add_custom_command(). Если другая цель используется для
196
2.10. Команды добавления специальных целей
построения исполняемого файла или библиотеки, кроме
зависимости на уровне целей также добавляется зависи-
мость на уровне исходных файлов: повторное построение
другой цели приводит к запуску текущей.
— Необязательный аргумент WORKING_DIRECTORY (вместе
со следующим за ним путём), а также VERBATIM имеют та-
кое же значение, как и для команды add_custom_target()
(п. 2.10.4).
— Необязательный аргумент APPEND указывает на то, что ко-
манды вызова инструментов и зависимости должны быть
добавлены к другим командам и зависимостям, ранее опре-
делённым другой командой add_custom_command() с теми
же выходными файлами.
Таким образом, создаваемая командой цель будет запус­каться, если хотя бы один из её выходных файлов используется другой целью, которую надо построить, и будет выполнено хо­тя бы одно из следующих условий:
— хотя бы один из файлов, перечисленных после аргумента
OUTPUT, отсутствует на диске;
— время последнего изменения любого из файлов, перечис-
ленных после аргумента DEPENDS (или выходных файлов
перечисленных там же целей), если такие есть, позже вре-
мени изменения хотя бы одного из выходных файлов теку-
щей цели.
Другая форма команды add_custom_command() предназна­чена для добавления команд вызова внешних инструментов
197
2. Основы языка CMake
к уже существующим целям. Аналогичными возможностями обладает, например, интегрированная среда Visual Studio, в на­стройках проекта которой есть страницы «Событие перед сбор­кой», «Событие перед компоновкой» и «Событие после сборки». Команды будут исполняться, только если в процессе построения выходные файлы указанной цели должны быть повторно созда­ны.
— После аргумента TARGET указывается логическое имя цели,
созданной ранее при помощи команды add_executable()
(п. 2.5.1) и т. п.
— При помощи следующего аргумента указывается, в какой
момент должны быть запущены команды:
PRE_BUILD: перед построением цели. Этот аргумент под-
держивается только генераторами для Visual Studio версии 7.0 или выше. Для остальных генераторов этот аргумент эквивалентен аргументу PRE_LINK (см. да­лее).
PRE_LINK: после компиляции всех файлов, но перед запус-
ком компоновщика/инструмента создания библиоте­ки. Это событие не поддерживается для целей, создан­ных командой add_custom_target() (п. 2.10.4).
POST_BUILD: после исполнения всех инструментов для по-
строения текущей цели.
— Аргументы COMMAND, WORKING_DIRECTORY и VERBATIM име-
ют такое же значение, как и для первой формы команды
add_custom_command().
198
2.10. Команды добавления специальных целей
ПРИМЕР Рассмотрим упрощённую модель ситуации, когда часть исход­ных файлов проекта генерируются внешними инструментами. Как будет видно дальше, такая ситуация является типичной для проектов, использующих библиотеку Qt. В других проектах, на­пример LLVM, исходные файлы создаются в результате запус­ка исполняемых файлов, являющихся результатами построения других целей.
Файл CMakeLists.txt проекта:
# ...
add_custom_command(
OUTPUT out.cpp
COMMAND echo int f1() { return 14\; } > out.cpp)
add_executable(
my_prog1
my_prog1.cpp "${CMAKE_CURRENT_BINARY_DIR}/out.cpp")
Здесь командой add_custom_command() создаётся цель, ге­нерирующая текстовый файл out.cpp в текущем каталоге по­строения. Для этого цель вызывает команду оболочки echo, ко­торая записывает в файл строку:
int f1() { return 14; }
(Escape-символ «\» перед точкой с запятой необходим в ко­де CMake, чтобы она не воспринималась как разделитель эле­ментов списка.)
199
2. Основы языка CMake
Так как текущий каталог для команды не указан, по умол­чанию выбирается текущий каталог построения. Следующей ко­мандой определяется цель my_prog1 для создания исполняемо­го файла. Одним из исходных файлов в ней указан генерируе­мый предыдущей целью файл в выходном каталоге. Таким об­разом, если этот файл на диске отсутствует, при построении ав­томатически запускается создающая его цель. Так как у неё нет других зависимостей, она будет запускаться только при отсут­ствии файла out.cpp.
Файл my_prog1.cpp:
#include <iostream>
int f1();
int main()
{
std::cout << f1() << std::endl;
}
Замечание: использованный в примере вызов команды echo бу- дет корректно работать в системе Windows. Чтобы эта команда
∗
записала правильное содержимое в выходной файл в POSIX-сов­местимой командной оболочке, формат её вызова должен быть следующим:
echo "int f1() { return 14; }" > out.cpp
200
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]