Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Система построения проектов CMake. Учебник.pdf
Скачиваний:
0
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
☆
2.9. Команды работы с файлами
hимя_переменнойi hкомандаi
g
PROGRAMfPROGRAM_ARGS hимя_переменной_аргументовi
f
CACHEg)
С помощью команды get_filename_component() в первой форме можно выделить из заданного пути файловой системы (передаётся команде вторым аргументом) нужную часть (имя, расширение и т. д.) или преобразовать путь к абсолютной фор­ме. Относительные пути интерпретируются по отношению к ка­талогу текущего подпроекта. При этом файл или каталог, к ко­торому указывается путь, не обязательно должен существовать. Возвращаемые пути содержат символы «/» в качестве раздели- телей имён каталогов и не содержат последнего символа «/».
Результат выполнения команды записывается в перемен­ную, имя которой передаётся в качестве первого аргумента. Тре­тий аргумент определяет, что именно должно быть получено в качестве результата (табл. 2.12).
Таблица 2.12
Значения третьего аргумента команды
get_filename_component(), определяющие
возвращаемый результат
Аргумент Возвращаемый результат
DIRECTORY Каталог, содержащий заданный файл
или каталог
NAME Имя с расширением без каталога
EXT Расширение (часть имени от первой точки)
151
2. Основы языка CMake
Окончание табл. 2.12
Аргумент Возвращаемый результат
NAME_WE Имя без каталога и расширения (до первой
точки)
ABSOLUTE Полный путь относительно каталога под-
проекта
REALPATH Как ABSOLUTE, но с разрешением символи-
ческих ссылок
Замечание: значение REALPATH является единственным, при ко- тором исполнение команды приводит к попытке обращения к файлу по указанному пути.
N
— При помощи необязательного аргумента CACHE можно по-
местить результирующую переменную в кэш.
Вторая форма команды ищет исполняемый файл по задан­ной командной строке с учётом системных путей поиска испол­няемых файлов (значение переменной окружения PATH и т. д.). Возвращается полный путь к файлу или пустая строка, если файл не найден.
— После необязательного аргумента PROGRAM_ARGS можно
указать имя переменной, в которую будут записаны аргу-
менты команды (начиная с первого пробела).
ПРИМЕР Пусть требуется указать в описании проекта список файлов, из которых должна собираться некоторая цель. При этом
152
2.9. Команды работы с файлами
для некоторых из этих CPP-файлов в каталоге проекта также существуют соответствующие им H-файлы, которые в списке не указаны. Их нужно найти и также включить в цель.
Эту задачу можно решить при помощи следующего файла
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
project(ex-find-h)
set(
FILES_SRC
main.cpp source1.cpp subdir/source2.cpp)
set(FILES_H)
foreach(SRC IN LISTS FILES_SRC)
get_filename_component(
SRC_EXT "${SRC}" EXT)
if(SRC_EXT STREQUAL .cpp)
get_filename_component(
SRC_FULL "${SRC}" ABSOLUTE)
get_filename_component(
SRC_DIR "${SRC_FULL}" DIRECTORY)
get_filename_component(
SRC_NAME "${SRC}" NAME_WE)
set(SRC_H "${SRC_DIR}/${SRC_NAME}.h")
if(
EXISTS "${SRC_H}" AND
153
2. Основы языка CMake
NOT IS_DIRECTORY "${SRC_H}")
message(STATUS "Found ${SRC_H}")
list(APPEND FILES_H "${SRC_H}")
endif()
endif()
endforeach()
add_executable(ex-find-h ${FILES_SRC} ${FILES_H})
Здесь список файлов в переменной FILES_SRC обходится командой foreach() (п. 2.8.3). Для каждого пути выделяется расширение файла и проверяется, что оно равно строке «.cpp». Дальше путь к файлу преобразуется к абсолютной форме, затем из него выделяются каталог и имя без расширения. Из них стро­ится имя H-файла и проверяется, что такой файл существует и является файлом, а не каталогом, при помощи команды if() (п. 2.8.1). Если это так, путь добавляется к списку в переменной FILES_H при помощи команды list(APPEND ...) (п. 2.7.3). ∗
Замечание: в make, CMake и других системах построения суще- ствуют средства для поиска файлов с заданными расширения­ми в каталоге проекта и автоматического их добавления к це­лям. Такой подход является плохой практикой, так как добавле­ние новых исходных файлов не приводит к изменению описа­ний проектов. Из-за этого механизм автоматического перестро­ения в таких случаях не срабатывает и возникают непредвиден­ные ошибки времени компоновки. Кроме того, сильно замедля­ется построение крупных проектов. При этом поиск и автомати-
154
2.9. Команды работы с файлами
ческое включение заголовочных файлов, продемонстрирован­ные в примере выше, вполне допустимы, так как заголовочные файлы не передаются системой построения на обработку ком­пилятору, а только используются интегрированными средами разработки для отображения в списке исходных файлов.
N
2.9.2. find_file(), find_library(), find_path(),
find_program()
Эти команды предназначены для поиска файла общего назначения (find_file() — как правило, заголовочных фай­лов), каталога, содержащего заданный файл (find_path()), библиотеки (find_library()) или исполняемого файла (find_program()) по заданным именам в указываемых ка­талогах, а также в некоторых стандартных каталогах.
Замечание: если программный пакет поддерживает систему CMake, для его использования вместо описанных здесь команд предпочтительнее применять более высокоуровневую команду find_package() (п. 2.11.1).
N
Все команды имеют почти одинаковый синтаксис аргумен­тов и позволяют указать множество дополнительных аргумен­тов для исключения тех или иных стандартных каталогов из по­иска. Ниже приведён сокращённый вариант синтаксиса с основ­ными настройками.
hимя_командыi(
hимя_переменнойi
hальтернативные_именаi
155
2. Основы языка CMake
f
HINTS hпуть
i ... hпуть
1,1
ifENV hимя_окружения1i
1,m
f
PATHS hпуть
i ... hпуть
2,1
ifENV hимя_окружения2i
2,p
f
PATH_SUFFIXES hсуффикс1i ... hсуффиксki
f
DOC hстрока_документацииig)
hимя_командыi F
find_file
find_library
hальтернативные_именаi F
hимяi
NAMES hимя1i ... hимяni
Команды сначала проверяют наличие переменной с задан-
 
find_path
g g
g g
g
 
find_program
ным именем в кэше. Только если переменной там нет или её значение равно «...-NOTFOUND» (см. также табл. 2.1), коман­ды выполняют поиск и записывают найденный путь первого встреченного файла, удовлетворяющего критериям, в перемен­ную кэша. Если файл не был найден, в переменную запишется значение «hимя_переменнойi-NOTFOUND». Таким образом, при по­следующих запусках инструмента CMake без очистки кэша ра­нее удавшийся поиск пропускается и генерирование проектов для конечной системы построения выполняется быстрее.
— После аргумента NAMES указывается одно или несколь-
ко альтернативных имён искомого файла . Команда find_program() может добавить к ним расширение ис-
156
полняемого файла, специфичное для системы, на которой выполняется инструмент CMake. Аналогично, команда find_library() может добавлять префикс в начале име-
2.9. Команды работы с файлами
ни и расширение в конце, например «libhимяi.so». Если
указывается одно имя, аргумент NAMES можно не переда-
вать.
— После необязательного аргумента HINTS можно указать до-
полнительные пути для поиска файла. Здесь рекомендует-
ся указывать пути, которые были ранее найдены в резуль-
тате исследования системы, например каталоги, где рас-
положены другие ранее найденные файлы. После необяза-
тельного аргумента ENV можно указать имя переменной
окружения, из которой будут прочитаны дополнительные
пути поиска.
— Необязательный аргумент PATHS аналогичен аргументу
HINTS, однако в отличие от него указываемые здесь пу-
ти будут проверены в последнюю очередь (о порядке про-
смотра путей см. ниже). Здесь рекомендуется указывать
при необходимости жёстко заданные пути к каталогам, та-
кие как C:\Program Files\SomeProg или /usr/local. Ес-
ли другие необязательные аргументы не указаны (вклю-
чая NAMES), аргумент PATHS также можно не передавать,
указывая в команде пути к каталогам сразу после един-
ственного имени файла.
— После необязательного аргумента PATH_SUFFIXES можно
указать дополнительные подкаталоги, которые будут ис-
пользованы для поиска в каждом из каталогов.
157
2. Основы языка CMake
— После необязательного аргумента DOC можно указать стро-
ку документации, которая будет записана в кэш для созда­ваемой переменной (см. описание команды set(), п. 2.7.1).
Поиск файла выполняется внутри каталогов в следующем
порядке:
1) Каталоги, пути к которым указаны в переменных кэша CMake:
— Команды find_file() и find_path() ищут в катало-
гах:
— hпутьi/include для всех путей из специаль-
ной переменной CMAKE_PREFIX_PATH. Также, если установлено значение специальной пе­ременной CMAKE_LIBRARY_ARCHITECTURE (ар-
хитектура библиотек), используются каталоги
hпутьi/include/hархитектураi.
— Пути из переменной CMAKE_INCLUDE_PATH.
— Пути из переменной CMAKE_FRAMEWORK_PATH.
— Команда find_library() ищет в каталогах:
— hпутьi/lib для всех путей из специальной
переменной CMAKE_PREFIX_PATH. Также, ес­ли установлено значение специальной пе­ременной CMAKE_LIBRARY_ARCHITECTURE, ис-
158
пользуются каталоги hпутьi/lib/hархитектураi. При необходимости для заданной архитек­туры также выполняется поиск в каталогах lib64 (чтобы повлиять на это, можно вручную
2.9. Команды работы с файлами
установить значение глобального свойства
FIND_LIBRARY_USE_LIB64_PATHS).
— Пути из переменной CMAKE_LIBRARY_PATH.
— Пути из переменной CMAKE_FRAMEWORK_PATH.
— Команда find_program() ищет в каталогах:
— hпутьi/bin и hпутьi/sbin для путей из перемен-
ной CMAKE_PREFIX_PATH.
— Пути из переменной CMAKE_PROGRAM_PATH.
— Пути из переменной CMAKE_APPBUNDLE_PATH.
2) Аналогично пункту 1, но вместо указанных переменных CMake используются одноимённые переменные окруже­ния.
3) Пути, переданные командам после аргумента HINTS.
4) Пути, перечисленные в переменной окружения PATH. Ко-
манды find_file() и find_path() также используют пе­ременную INCLUDE, а команда find_library() — LIB.
5) Аналогично пункту 1, но вместо переменных кэ­ша CMake с именами CMAKE_..._PATH использу­ются специальные переменные CMake с имена­ми в форме CMAKE_SYSTEM_..._PATH (например,
CMAKE_SYSTEM_PREFIX_PATH).
6) Пути, переданные командам после аргумента PATHS.
В системах, которые не используют имени диска и т. п.
в начале полного пути, возможно перенаправление поиска в ка-
159
2. Основы языка CMake
талоги, пути к которым добавляются в виде префиксов в нача­ло всех перечисленных выше путей. Это может быть удобно для выполнения кросс-компиляции, когда файлы сборки для це­левой системы располагаются в отдельных каталогах. Поиск вы­полняется в следующем порядке:
1) Префиксы путей, перечисленные в специальной перемен­ной CMake CMAKE_FIND_ROOT_PATH. При этом пути, попада­ющие в каталог, путь к которому хранится в переменной CMAKE_STAGING_PREFIX (путь установки при кросс-компи­ляции), не изменяются.
2) Префикс из специальной переменной CMAKE_SYSROOT.
3) Далее выполняется поиск в исходных каталогах без пре-
фиксов.
Пример создания цели вызова архиватора 7-zip при помо-
щи команды add_custom_target() на с. 192 также демонстри­рует использование команды find_program(). Пример подклю­чения библиотеки Crypto++ на с. 350 демонстрирует использова­ние команд find_library() и find_path().

2.10. Команды добавления специальных целей

2.10.1. configure_file()

configure_file(
hвходной_файлi hвыходной_файлi
f
COPYONLY
160
g f
ESCAPE_QUOTES
g f
g
@ONLY
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]