Макросы: стандартные, системные, свои
Переменные и макросы RPM, условные конструкции, определение собственных макросов.
На этой странице
Макросы — это переменные и функции, которые делают SPEC-файлы гибкими, переносимыми и читаемыми.
Синтаксис макросов
Простые макросы
%{name} # Значение тега Name
%{version} # Значение тега Version
%{_bindir} # Путь /usr/bin
Условные макросы
%{?dist} # Значение dist, если определён, иначе пусто
%{!?dist:default} # "default", если dist не определён
%{?with_tests:1} # "1", если with_tests определён
Раскрытие макросов
# Посмотреть значение
rpm --eval '%{_libdir}'
# /usr/lib64
rpm --eval '%{name}'
# %{name} (не определён вне контекста SPEC)
# Раскрыть сложное выражение
rpm --eval '%{?fedora:Fedora}%{?rhel:RHEL}%{?rosa:ROSA}'
Стандартные макросы
Теги пакета
%{name} # Имя пакета
%{version} # Версия
%{release} # Релиз
%{epoch} # Epoch (или пусто)
%{summary} # Summary
%{license} # Лицензия
%{url} # URL
Пути установки
%{_prefix} # /usr
%{_exec_prefix} # /usr
%{_bindir} # /usr/bin
%{_sbindir} # /usr/sbin
%{_libdir} # /usr/lib64 (на x86_64)
%{_libexecdir} # /usr/libexec
%{_includedir} # /usr/include
%{_datadir} # /usr/share
%{_mandir} # /usr/share/man
%{_infodir} # /usr/share/info
%{_docdir} # /usr/share/doc
%{_sysconfdir} # /etc
%{_localstatedir} # /var
%{_rundir} # /run
%{_tmppath} # /var/tmp
Сборочные пути
%{buildroot} # Временный корень установки
%{_builddir} # ~/rpmbuild/BUILD
%{_sourcedir} # ~/rpmbuild/SOURCES
%{_specdir} # ~/rpmbuild/SPECS
%{_srcrpmdir} # ~/rpmbuild/SRPMS
%{_rpmdir} # ~/rpmbuild/RPMS
Системная информация
%{_arch} # Архитектура (x86_64, aarch64, ...)
%{_host} # Хост сборки
%{_host_cpu} # CPU хоста
%{_target} # Целевая платформа
%{dist} # Суффикс дистрибутива (.rosa13.1)
Флаги компиляции
%{optflags} # Флаги оптимизации (-O2 -g ...)
%{build_cflags} # CFLAGS
%{build_cxxflags} # CXXFLAGS
%{build_ldflags} # LDFLAGS
%{_smp_mflags} # Флаги параллельной сборки (-j8)
Макросы секций
%configure
%configure --enable-feature
Раскрывается в:
./configure \
--build=x86_64-redhat-linux-gnu \
--host=x86_64-redhat-linux-gnu \
--prefix=/usr \
--exec-prefix=/usr \
--bindir=/usr/bin \
--sbindir=/usr/sbin \
--sysconfdir=/etc \
--datadir=/usr/share \
--includedir=/usr/include \
--libdir=/usr/lib64 \
--libexecdir=/usr/libexec \
--localstatedir=/var \
--sharedstatedir=/var/lib \
--mandir=/usr/share/man \
--infodir=/usr/share/info \
--enable-feature
%make_build, %make_install
%make_build # make -O -j8
%make_install # make install DESTDIR=%{buildroot}
%cmake, %cmake_build, %cmake_install
%cmake -DFEATURE=ON
%cmake_build
%cmake_install
%meson, %meson_build, %meson_install
%meson -Dfeature=true
%meson_build
%meson_install
%autosetup
%autosetup -p1 # Распаковка + патчи
%autosetup -n dir # Указать имя каталога
%autosetup -N # Без автоматического применения патчей
Определение своих макросов
Глобальные макросы
%global project_name MyProject
%global commit abc123def456
%global shortcommit %(c=%{commit}; echo ${c:0:7})
%global — макрос доступен везде в SPEC.
Локальные макросы
%define localvar value
%define — макрос раскрывается лениво (при использовании).
Разница %global и %define
%define lazy %{version}
%global eager %{version}
# Если version изменится, lazy вернёт новое значение
# eager сохранит значение на момент определения
Рекомендация: Используйте %global для констант, %define — редко.
Макросы с параметрами
%global make_verbose %{__make} VERBOSE=1 %{?_smp_mflags}
%build
%{make_verbose}
Shell-команды в макросах
%global shortcommit %(c=%{commit}; echo ${c:0:7})
%global git_date %(date +%Y%m%d)
%(...) выполняет shell-команду и подставляет результат.
Условные конструкции
%if / %endif
%if 0%{?fedora} >= 38
BuildRequires: new-package
%else
BuildRequires: old-package
%endif
%ifarch / %ifnarch
%ifarch x86_64 aarch64
# Только для этих архитектур
BuildRequires: special-lib
%endif
%ifnarch i686
# Для всех, кроме i686
%global with_feature 1
%endif
%if с макросами
%if 0%{?with_tests}
%check
make test
%endif
0%{?macro} — защита от пустого значения (пустота + число = число).
Опции сборки (bcond)
# Определение опций
%bcond_without tests # По умолчанию tests включены
%bcond_with debug # По умолчанию debug выключен
# Использование
%if %{with tests}
BuildRequires: test-framework
%endif
%build
%configure %{?with_debug:--enable-debug}
%if %{with tests}
%check
make test
%endif
Использование при сборке:
rpmbuild --with debug --without tests -ba package.spec
Специальные макросы
%
Release: 1%{?dist}
# На ROSA: 1.rosa13.1
# На Fedora: 1.fc39
%
make %{?_smp_mflags}
# Раскрывается в -j8 (или сколько ядер)
%{SOURCE0}, %
# Полный путь к Source0
install -m 644 %{SOURCE1} %{buildroot}%{_unitdir}/
# Полный путь к Patch0
cat %{PATCH0}
%find_lang
%install
%make_install
%find_lang %{name}
%files -f %{name}.lang
Встроенные Lua-макросы
%{lua: print(rpm.expand("%{version}"))}
%{lua:
local v = rpm.expand("%{version}")
print(v:gsub("%.", "_"))
}
Файл ~/.rpmmacros
Персональные настройки:
%_topdir %(echo $HOME)/rpmbuild
%packager Your Name <your@email.com>
%vendor ROSA Linux
%dist .rosa13.1
# Отключить debuginfo
%debug_package %{nil}
# Параллельная сборка
%_smp_mflags -j8
Системные макросы
Макросы дистрибутива в /usr/lib/rpm/macros.d/:
ls /usr/lib/rpm/macros.d/
# macros.python3
# macros.cmake
# macros.meson
# ...
Отладка макросов
# Раскрыть все макросы в SPEC
rpmspec --parse package.spec
# Раскрыть конкретный макрос
rpm --eval '%{_libdir}'
# Показать все определённые макросы
rpm --showrc | grep -i macro
# Показать макрос с определением
rpm -E '%{dump}' 2>&1 | grep _bindir
Типичные ошибки
Пустой макрос ломает синтаксис
# Опасно — если dist пуст, будет синтаксическая ошибка
%if %{dist} == ".fc39"
# Безопасно
%if "%{?dist}" == ".fc39"
%if 0%{?fedora}
Неправильный порядок %global
# Неправильно — version ещё не определён
%global archive %{name}-%{version}.tar.gz
Name: myapp
Version: 1.0
# Правильно — определять после тегов или использовать буквальные значения
Лишние пробелы в %define
# Неправильно — пробел станет частью значения
%global myvar value
# Правильно
%global myvar value
Проверьте понимание
- Чем отличается
%{?macro}от%{macro}? - Какая разница между
%globalи%define? - Как выполнить shell-команду в макросе?
- Что делает
0%{?fedora}? - Как определить опцию сборки, включённую по умолчанию?
Далее: Ведение %changelog