Четверг, 16.10.2025 19:00

Функции и макросы в CMake

Функции и макросы в CMake

Проекты использующие CMake по мере разработки, со временем обрастают всё большим числом настроек. К тому же код CMake, используемый в одном проекте, как правило начинает использоваться в других проектах.

В CMake как правило код разбивают на части и помещают в отдельные файлы и уже в файле CMakeLists.txt включают эти файлы в определённом порядке.

Если же один и тот же код предполагается использовать, например, для обработки разных файлов, имеет смысл объявить отдельную функцию, которая будет содержать данный код.

Сегодня мы рассмотрим использование функций и макросов в CMake.

Настройка проекта

Начнем мы с шаблона проекта Qt6 размещенного в git-репозитории.

Если папка:

c:\projects\qt6_funcs

уже существует, переместите или удалите её:

cd c:\projects
rmdir /q/s qt6_funcs

Мы будем использовать проект из git-репозитория:

cd c:\projects
rmdir /q/s qt6-project-templategit
git clone https://gitflic.ru/project/vasiliyaltunin/qt6-project-templategit.git --depth 1

Скопируем папку с проектом:

xcopy /y/e .\qt6-project-templategit\ .\qt6_funcs\

Проверим:

cd c:\projects\qt6_funcs

cmake –S . –B build

cmake —-build build

.\build\qt6tpl.exe
Hello world!
Debug: Clicked (qrc:/qt/qml/altuninvv/qmlmain/qml/Main.qml:24, expression for onClicked)

Всё работает.

Объявление функции

Добавим папку для функций:

mkdir cmake\functions

Создадим файл для функции:

type nul > cmake\functions\myfunc.cmake.in

Откроем наш проект

cd c:\projects\qt6_funcs
code .

В файл cmake\functions\myfunc.cmake.in добавим код:

# Объявление функции - myfunction
function(myfunction)
message("Helloo this is MyFunction!")
endfunction()

Откроем файл CMakeLists.txt добавим в конце:

# Добавляем функцию в проект
include(${PROJECT_SOURCE_DIR}/cmake/functions/myfunc.cmake.in)

# Вызываем функцию myfunction
myfunction()

Запустим:

cmake -S . -B build

Результат:

Helloo this is MyFunction!
-- Configuring done (1.0s)
-- Generating done (0.1s)
-- Build files have been written to: C:/Projects/qt6_funcs/build

Параметры функции

Откроем файл CMakeLists.txt изменим код после:

# Вызываем функцию myfunction

Заменим на:

set(MY_FUNCTION_PARAM "123")
myfunction(MY_FUNCTION_PARAM)

Изменим код в файле cmake\functions\myfunc.cmake:

# - Функция myfunction
# Предназначена для вычисления зависимостей от сторонних разделяемых библиотек.
#
# Использование:
#
# myfunction(
# [param1]
# )
#
# [param1] - первый параметр функции
function(myfunction param1)
message("Helloo this is MyFunction!")
message("All params: ${ARGV}")
message("Params count: ${ARGC}")
message("Params names: ${ARGN}")
message("----")
message("Param #1: ${param1}")
message("Param #1: ${ARGV0}")
endfunction()

Здесь мы сразу добавили комментарий с описанием функции.

Доступ к параметрам может осуществляться по имени параметра и использованием переменных.

Всего функция имеет три переменных, позволяющих получить доступ к параметрам:

${ARGV} – список всех параметров

${ARGС} – количество параметров

${ARGN} – имена параметров не указанных при объявлении функции

Получить параметры по порядку можно добавлением цифр к параметру ${ARGV}.

Обратите внимание! Нумерация начинается с нуля!

${ARGV0} 
${ARGV1} 
и.т.д.

Запустим:

cmake -S . -B build
Helloo this is MyFunction!
All params: MY_FUNCTION_PARAM
Params count: 1
Params names:
----
Param #1: MY_FUNCTION_PARAM
Param #1: MY_FUNCTION_PARAM

Добавим еще параметров в вызов нашей функции в файле CMakeLists.txt:

myfunction(MY_FUNCTION_PARAM ${PROJECT_SOURCE_DIR} "123456")

Запустим:

cmake -S . -B build
Helloo this is MyFunction!
All params: MY_FUNCTION_PARAM;C:/Projects/qt6_pre_package;123456
Params count: 3
Params names: C:/Projects/qt6_pre_package;123456
----
Param #1: MY_FUNCTION_PARAM
Param #1: MY_FUNCTION_PARAM

Обратите внимание! Необязательные параметры появились в:

Params names: C:/Projects/qt6_pre_package;123456

Разыменование параметров в функции

Изменим нашу функцию:

function(myfunction param1)
message("Helloo this is MyFunction!")
message("All params: ${ARGV}")
message("Params count: ${ARGC}")
message("Params names: ${ARGN}")
message("----")
message("Param #1: ${param1}")
message("${ARGV0}: ${${ARGV0}}")
endfunction()

Запустим:

cmake -S . -B build
Helloo this is MyFunction!
All params: MY_FUNCTION_PARAM;C:/Projects/qt6_pre_package;123456
Params count: 3
Params names: C:/Projects/qt6_pre_package;123456
----
Param #1: MY_FUNCTION_PARAM
MY_FUNCTION_PARAM: 123

Здесь мы провели двойное разыменование:

${${ARGV0}}

Для получения значения первой переменной функции.

Видимость переменных в функциях

Любые переменные устанавливаемые в функции будут удалены при выходе из функции.

Изменим нашу функцию:

function(myfunction param1)
message("Helloo this is MyFunction!")
message("All params: ${ARGV}")
message("Params count: ${ARGC}")
message("Params names: ${ARGN}")
message("----")
message("Param #1: ${param1}")
message("${ARGV0}: ${${ARGV0}}")
set(MY_FUNCTION_PARAM "456")
endfunction()

Изменим вызов нашей функции добавив еще один вызов в CMakeLists.txt:

myfunction(MY_FUNCTION_PARAM ${PROJECT_SOURCE_DIR} "123456")
myfunction(MY_FUNCTION_PARAM ${PROJECT_SOURCE_DIR} "123456")

Запустим:

cmake -S . -B build
Helloo this is MyFunction!
All params: MY_FUNCTION_PARAM;C:/Projects/qt6_pre_package;123456
Params count: 3
Params names: C:/Projects/qt6_pre_package;123456
----
Param #1: MY_FUNCTION_PARAM
MY_FUNCTION_PARAM: 123
Helloo this is MyFunction!
All params: MY_FUNCTION_PARAM;C:/Projects/qt6_pre_package;123456
Params count: 3
Params names: C:/Projects/qt6_pre_package;123456
----
Param #1: MY_FUNCTION_PARAM
MY_FUNCTION_PARAM: 123

Несмотря на то, что мы меняем значение переменной MY_FUNCTION_PARAM её значение: не сохраняется при выходе из функции.

Макросы в CMake

Макросы аналогичны функциям, за исключением того, что любые изменения глобальных параметров будут сохранены после выхода из макроса.

Изменим нашу функцию, превратив её в макрос:

macro(myfunction param1)
message("Helloo this is MyFunction!")
message("All params: ${ARGV}")
message("Params count: ${ARGC}")
message("Params names: ${ARGN}")
message("----")
message("Param #1: ${param1}")
message("${ARGV0}: ${${ARGV0}}")
set(MY_FUNCTION_PARAM "456")
endmacro()

Запустим:

cmake -S . -B build
Helloo this is MyFunction!
All params: MY_FUNCTION_PARAM;C:/Projects/qt6_pre_package;123456
Params count: 3
Params names: C:/Projects/qt6_pre_package;123456
----
Param #1: MY_FUNCTION_PARAM
MY_FUNCTION_PARAM: 123
Helloo this is MyFunction!
All params: MY_FUNCTION_PARAM;C:/Projects/qt6_pre_package;123456
Params count: 3
Params names: C:/Projects/qt6_pre_package;123456
----
Param #1: MY_FUNCTION_PARAM
MY_FUNCTION_PARAM: 456

На этот раз, при втором вызове, значение переменной MY_FUNCTION_PARAM поменялось:

Param #1: MY_FUNCTION_PARAM = 456

Обратите внимание! Всегда используйте только функции при работе с CMake, макросы используются в особых случаях, так как их использование может привести к необъяснимому поведению в процессе сборки проекта.

Заключение

Сегодня мы рассмотрели использование функций и макросов в CMake:

Рассмотрели объявление функции;

Рассмотрели объявление параметров;

Рассмотрели разыменование параметров функции;

Рассмотрели особенности применения макросов в CMake.

Категория Qt6
Теги Qt6 CMAKE

Добавить комментарий

Простой текст

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Строки и абзацы переносятся автоматически.
  • Адреса веб-страниц и email-адреса преобразовываются в ссылки автоматически.
Просмотров: 76