宏定义保护

类似 %if 0%{?suse_version} 这样的语法,前面的 0 的用法其实与 shell 中的 if [ x$i = x ]; then ... fi 类似,就是为了避免变量 i 没定义时报错。

预定义宏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
$ rpm -ql rpm | grep macros
/usr/lib/rpm/macros
/usr/lib/rpm/macros.d
/usr/lib/rpm/platform/aarch64-linux/macros
...
/usr/lib/rpm/platform/x86_64-linux/macros
/usr/share/doc/rpm-4.11.3/macros

$ ll /etc/rpm/
total 132
-rw-r--r--. 1 root root 170 Mar 9 2019 macros.blender
-rw-r--r--. 1 root root 1470 Nov 5 2016 macros.cmake
-rw-r--r--. 1 root root 53 Apr 11 2018 macros.cups
-rw-r--r--. 1 root root 66 Oct 8 2018 macros.dist
-rw-r--r--. 1 root root 1806 Apr 13 2018 macros.dwz
-rw-r--r--. 1 root root 324 Sep 20 2017 macros.emacs
-rw-r--r--. 1 root root 13543 Nov 21 2015 macros.fjava
-rw-r--r--. 1 root root 2673 Jan 25 2014 macros.gconf2
-rw-r--r--. 1 root root 215 Apr 13 2018 macros.ghc-srpm
-rw-r--r--. 1 root root 227 Apr 13 2018 macros.gnat-srpm
-rw-r--r--. 1 root root 4700 Nov 21 2015 macros.jpackage
-rw-r--r--. 1 root root 105 Apr 13 2018 macros.mono-srpm
-rw-r--r--. 1 root root 228 Apr 13 2018 macros.nodejs-srpm
-rw-r--r--. 1 root root 115 Apr 13 2018 macros.ocaml-srpm
-rw-r--r--. 1 root root 5134 Mar 2 2017 macros.perl
-rw-r--r--. 1 root root 794 Jun 10 2014 macros.perl-srpm
-rw-r--r--. 1 root root 2336 Nov 6 2016 macros.pesign
-rw-r--r--. 1 root root 297 Nov 6 2016 macros.prelink
-rw-r--r--. 1 root root 886 Oct 14 00:03 macros.pybytecompile
-rw-r--r--. 1 root root 3348 Oct 14 00:03 macros.python
-rw-r--r--. 1 root root 1495 Oct 14 00:03 macros.python2
-rw-r--r--. 1 root root 1839 Oct 14 00:03 macros.python3
...

$ cat /usr/lib/rpm/macros | grep ___build_pre
%___build_pre \
%{___build_pre}\
%__spec_prep_pre %{___build_pre}
%__spec_build_pre %{___build_pre}
%__spec_install_pre %{___build_pre}
%__spec_check_pre %{___build_pre}
#%__spec_autodep_pre %{___build_pre}
%__spec_clean_pre %{___build_pre}
%__spec_rmbuild_pre %{___build_pre}

without

为 rpmbuild 增加 --without tcmalloc 选项:

1
%bcond_without tcmalloc

如果在 rpmbuild 时不指定,则默认增加 tcmalloc 支持。

with

为 rpmbuild 增加 --with tcmalloc 选项:

1
%bcond_with tcmalloc

如果在 rpmbuild 时不指定,则默认移除 tcmalloc 支持。

if/else/endif

在 spec 正文中可以以如下的方式使用条件构建:

1
2
3
4
5
%if %{with selinux}
...
%else
...
%endif

查询 BuildRequires

1
2
3
$ rpmspec -q --buildrequires ceph.spec
$ rpmspec -q --srpm --requires ceph.spec
$ rpmspec --parse ceph.spec 2>/dev/null | grep BuildRequires

比如为了安装 ceph 的构建依赖,可以使用如下的命令:

1
2
3
$ sed -e 's/@//g' < ceph.spec.in > ceph.spec
$ sed -i -e 's/%bcond_with make_check/%bcond_without make_check/g' ceph.spec
$ sudo yum install -y --skip-broken $(rpmspec --parse ceph.spec 2>/dev/null | grep BuildRequires | awk '{ print $2 }' | xargs)

禁止修改源代码属性

1
2
3
4
5
6
7
8
9
10
// rpm/build/parsePrep.c

doSetupMacro
/* Fix the permissions of the setup build tree */
{ char *fix = rpmExpand("%{_fixperms} .", NULL);
if (fix && *fix != '%') {
appendLineStringBuf(spec->prep, fix);
}
free(fix);
}
1
2
$ rpm --eval %{_fixperms}
/usr/bin/chmod -Rf a+rX,u+w,g-w,o-w
1
$ rpmbuild -ba --define "_topdir ${BUILDAREA}" --define "dist ${DIST}" --define "_fixperms %{nil}"

参考资料

Scriptlets

https://docs.fedoraproject.org/en-US/packaging-guidelines/Scriptlets/

Some tips on RPM conditional macros

https://backreference.org/2011/09/17/some-tips-on-rpm-conditional-macros/

Automatic Dependencies

http://ftp.rpm.org/max-rpm/s1-rpm-depend-auto-depend.html

Manual Dependencies

http://ftp.rpm.org/max-rpm/s1-rpm-depend-manual-dependencies.html

Upgrade paths — renaming or splitting packages

https://fedoraproject.org/wiki/Upgrade_paths_%E2%80%94_renaming_or_splitting_packages

RPM Packaging Guide

https://rpm-packaging-guide.github.io/

rpm documentation

https://rpm.org/documentation.html

Maximum RPM

http://ftp.rpm.org/max-rpm/index.html

RPM to parse BuildRequires from .spec

https://bugzilla.redhat.com/show_bug.cgi?id=540807

EXTRACING RPM BUILD DEPENDENCIES FROM RPM SPEC FILES

https://www.terriblecode.com/blog/extracing-rpm-build-dependencies-from-rpm-spec-files/

how to override rpm macro

https://serverfault.com/questions/217640/how-to-override-rpm-macro

RPM packager’s cheat sheet

https://ro-che.info/articles/2018-01-25-rpm-packager-cheat-sheet

What is a Dependency, Anyway

https://weldr.io/RPM-Dependencies/

Dependencies

https://rpm.org/user_doc/dependencies.html

Dnf ignore weak dependencies

https://bgstack15.wordpress.com/2017/05/13/dnf-ignore-weak-dependencies/

rpm: use Recommends on fedora also

https://github.com/ceph/ceph/pull/26819