2023-04-17 02:38:37 +08:00
|
|
|
|
Non-Standard RPM Macros
|
|
|
|
|
=======================
|
|
|
|
|
|
|
|
|
|
RPM itself defines many macros and there are several other macros that
|
|
|
|
|
are non defined by RPM but are considered ‘defacto-standard’ such as
|
|
|
|
|
some of the python macros.
|
|
|
|
|
|
|
|
|
|
When using non-standard macros that are defined outside of an RPM spec
|
2023-04-28 18:08:59 +08:00
|
|
|
|
file, the RPM spec file *must* accommodate building when and where that
|
2023-04-17 02:38:37 +08:00
|
|
|
|
macro is not defined.
|
|
|
|
|
|
|
|
|
|
The following non-standard macros are being used by YJL.
|
|
|
|
|
|
2023-04-17 02:44:29 +08:00
|
|
|
|
1. [The `%dist` macro](#the-dist-macro)
|
|
|
|
|
2. [The `%repo` macro](#the-repo-macro)
|
2023-04-17 03:13:23 +08:00
|
|
|
|
3. [The `%insinfo` macro](#the-insinfo-macro)
|
2023-04-17 05:11:00 +08:00
|
|
|
|
4. [The `%runtests` macro](#the-runtests-macro)
|
2023-04-28 18:08:59 +08:00
|
|
|
|
5. [The `%libresslAPI` macro](#the-libresslapi-macro)
|
|
|
|
|
6. [The `%cpuoptimize` macro](#the-cpuoptimize-macro)
|
|
|
|
|
7. [Perl Specific Macros](#perl-specific-macros)
|
|
|
|
|
8. [TODO --- Python Custom Macros](#todo-----python-custom-macros)
|
2023-04-17 02:44:29 +08:00
|
|
|
|
|
2023-04-17 02:38:37 +08:00
|
|
|
|
|
|
|
|
|
The `%dist` macro
|
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
|
|
Most distributions use this so it could be considered a ‘defacto-standard’
|
|
|
|
|
but it still is better to not assume it is present.
|
|
|
|
|
|
|
|
|
|
YJL (and most distributions) use it at the end of the RPM `Release:`
|
|
|
|
|
tag definition to give a string identifier of the distribution the RPM
|
|
|
|
|
package was built for.
|
|
|
|
|
|
|
|
|
|
The *only* place this macro should be used is at the end of the `Release:`
|
|
|
|
|
tag definition (with one exception) and when defined, it should be be
|
|
|
|
|
defined within the distribution specific macro definitions of the RPM
|
|
|
|
|
package. It *must* start with a `.` and *must not* end with a `.` or
|
|
|
|
|
else the package `Release` metadata will be broken.
|
|
|
|
|
|
|
|
|
|
When used in an RPM spec file it *must* be of the form `%{?dist}` so
|
|
|
|
|
that it expands to a zero-length string if not defined.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The `%repo` macro
|
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
|
|
To the best of my limited knowledge, no other distribution uses this
|
|
|
|
|
tag.
|
|
|
|
|
|
|
|
|
|
YLJ uses it to define which package repository within YJL the package
|
|
|
|
|
was built for, and also uses it for conditional features depending
|
|
|
|
|
upon which package repository it is being built for.
|
|
|
|
|
|
2023-04-28 18:08:59 +08:00
|
|
|
|
See the [Repository-Macro](03-Repository-Macro.md) for more information.
|
2023-04-17 02:38:37 +08:00
|
|
|
|
|
|
|
|
|
It is most commonly used at the beginning of a RPM `Release:` tag
|
|
|
|
|
definition and when used in RPM `Release:` tag, it *must* be used at
|
|
|
|
|
the very beginning of the `Release:` tag definition.
|
|
|
|
|
|
|
|
|
|
When defined, it *must* start with a positive integer followed by a
|
|
|
|
|
`.` followed by a string that defines the repository the package is
|
|
|
|
|
being built for. It *must* end in a `.` or else the package `Release:`
|
|
|
|
|
metadata will be broken.
|
|
|
|
|
|
|
|
|
|
When used within the RPM `Release:` tag definition it *must* be of the
|
|
|
|
|
form `%{?repo}` so that it expands to a zero-length string if not
|
|
|
|
|
defined.
|
|
|
|
|
|
|
|
|
|
### Using `%repo` for Condition Features
|
|
|
|
|
|
|
|
|
|
When the `%repo` macro is used outside of the RPM `Release:` tag, it
|
|
|
|
|
*must* also be used inside the `Release:` tag as described above.
|
|
|
|
|
|
|
|
|
|
When the `%repo` macro is used for conditional building, you *must*
|
|
|
|
|
define a spec-file specific macro for the actual condition and set it
|
|
|
|
|
to a reasonable default.
|
|
|
|
|
|
|
|
|
|
Then you can test to see if `%repo` is defined and if defined, use
|
|
|
|
|
string comparisons to change your spec file defined conditional macro.
|
|
|
|
|
|
2023-04-17 03:13:23 +08:00
|
|
|
|
An example from the [gcc.spec](SPECS/gcc.spec) file:
|
2023-04-17 02:38:37 +08:00
|
|
|
|
|
2023-04-17 02:47:15 +08:00
|
|
|
|
# buildlevel 0 is just c,c++,ada,d -- the languages
|
2023-04-17 02:38:37 +08:00
|
|
|
|
# that always should be built because they are required
|
|
|
|
|
# to build themselves.
|
|
|
|
|
# buildlevel 1 adds fortran,go,objc,obj-c++
|
|
|
|
|
%global buildlevel 1
|
|
|
|
|
%if %{?repo:1}%{!?repo:0}
|
|
|
|
|
%if "%{repo}" == "1.core."
|
|
|
|
|
%global buildlevel 0
|
|
|
|
|
%endif
|
|
|
|
|
%endif
|
|
|
|
|
|
|
|
|
|
In that example, the `%buildlevel` is the spec-file specific macro and
|
|
|
|
|
it defaults to a definition of `1`.
|
|
|
|
|
|
|
|
|
|
If the `%repo` macro is defined, then it checks to see if it is defined
|
|
|
|
|
to the string `1.core.` and if it is defined as such, the `%buildlevel`
|
|
|
|
|
macro is redefined to a value of `0`.
|
|
|
|
|
|
|
|
|
|
By doing this, the spec file remains *mostly portable* to build in a
|
|
|
|
|
different GNU/Linux distribution. A user who needs the package in a
|
|
|
|
|
distribution that does not provide it can rebuild the source RPM and
|
|
|
|
|
may not need to manually edit the spec file at all unless they need
|
|
|
|
|
conditionals other than the default.
|
2023-04-17 03:13:23 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The `%insinfo` macro
|
|
|
|
|
--------------------
|
|
|
|
|
|
|
|
|
|
Many GNU/Linux distributions have the `install-info` command installed
|
|
|
|
|
at either `/sbin/install-info` or at `/usr/sbin/install-info`. I
|
|
|
|
|
believe that is wrong because users may have a valid reason to need
|
|
|
|
|
the command outside the context of system documentation administration,
|
|
|
|
|
but it is what it is.
|
|
|
|
|
|
|
|
|
|
Unfortunately there does not seem to be a RPM standard macro that
|
|
|
|
|
defines the location of the `install-info` command, so to maintain at
|
|
|
|
|
least *partial* portability of spec files written for YJL, I created
|
|
|
|
|
the `%insinfo` macro that in YJL expands to `/usr/bin/install-info`
|
|
|
|
|
and when that macro is used, the spec file *must* have the following
|
|
|
|
|
fallback to define it if not defined:
|
|
|
|
|
|
|
|
|
|
%if %{!?insinfo:1}%{?insinfo:0}
|
|
|
|
|
%global insinfo /sbin/install-info
|
|
|
|
|
%endif
|
|
|
|
|
|
|
|
|
|
On YJL the macro is defined so the fall-back is not used, but where
|
|
|
|
|
the macro is *not* defined, the fallback then defines `%insinfo` to
|
|
|
|
|
`/sbin/install-info` which will at least be correct for *some* systems.
|
|
|
|
|
|
|
|
|
|
When a package installs `.info` files, the `%insinfo` macro *must* be
|
|
|
|
|
used in the `%post` scriptlet to add the info file to the info database
|
2023-04-28 18:08:59 +08:00
|
|
|
|
and `%insinfo --delete` *must* be used in the `%preun` scriptlet to
|
2023-04-17 03:13:23 +08:00
|
|
|
|
remove the file from the info database *when the package is deleted
|
|
|
|
|
and not just being updated*.
|
|
|
|
|
|
|
|
|
|
The code block above *must* be used to define the `%insinfo` macro on
|
|
|
|
|
systems where it is not defined by default.
|
|
|
|
|
|
|
|
|
|
|
2023-04-17 05:11:00 +08:00
|
|
|
|
The `%runtests` macro
|
|
|
|
|
---------------------
|
2023-04-17 03:13:23 +08:00
|
|
|
|
|
2023-04-17 05:11:00 +08:00
|
|
|
|
The test suite in some packages takes a *very long* time to complete.
|
|
|
|
|
For such packages, the packager may optionally use the presence of a
|
|
|
|
|
defined `%runtests` macro to determine whether or not to actually run
|
|
|
|
|
the test suite.
|
2023-04-17 03:13:23 +08:00
|
|
|
|
|
2023-04-17 05:11:00 +08:00
|
|
|
|
If the `%runtests` macro is set, regardless of what it is set to, then
|
|
|
|
|
in spec files with conditional testing any test dependency packages
|
|
|
|
|
needed to run the tests (such as DejaGnu or Valgrind) *must*
|
|
|
|
|
be triggered as `BuildRequires` and the test suite runs.
|
2023-04-17 03:13:23 +08:00
|
|
|
|
|
2023-04-17 05:11:00 +08:00
|
|
|
|
On the other hand if `%runtests` is *not* defined, then any `BuildRequires`
|
|
|
|
|
that are *only* needed for the test suite should *not* be required and
|
|
|
|
|
the test suite does not run.
|
2023-04-17 03:13:23 +08:00
|
|
|
|
|
2023-04-17 05:11:00 +08:00
|
|
|
|
With most packages, tests are fast enough that they just should always
|
|
|
|
|
be run.
|
|
|
|
|
|
|
|
|
|
|
2023-04-28 18:08:59 +08:00
|
|
|
|
The `%libresslAPI` macro
|
|
|
|
|
------------------------
|
|
|
|
|
|
|
|
|
|
Packages the require the OpenSSL API but can build against LibreSSL are
|
|
|
|
|
built against LibreSSL *however* to keep the RPM spec file portable to
|
|
|
|
|
other GNU/Linux distributions that likely do not have `libressl-devel`.
|
|
|
|
|
|
|
|
|
|
YJL defines the `%libresslAPI` macro so that during package build time,
|
|
|
|
|
the RPM spec file can use it as a Boolean (either defined or not) to
|
|
|
|
|
determine whether it should build require `libressl-devel` or `openssl-devel`.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
%if 0%{?libresslAPI:1} == 1
|
|
|
|
|
BuildRequires: libressl-devel
|
|
|
|
|
%else
|
|
|
|
|
BuildRequires: openssl-devel
|
|
|
|
|
%endif
|
|
|
|
|
|
|
|
|
|
|
2023-04-17 05:11:00 +08:00
|
|
|
|
The `%cpuoptimize` macro
|
|
|
|
|
------------------------
|
|
|
|
|
|
|
|
|
|
There are some packages that can be optimized for the specific CPU they
|
|
|
|
|
are being built for.
|
|
|
|
|
|
|
|
|
|
In such cases, the default build of the package *must* be without the
|
|
|
|
|
optimization so that the package will run regardless of the CPU specific
|
|
|
|
|
capabilities.
|
|
|
|
|
|
|
|
|
|
However the user should have the ability to rebuild the source RPM and
|
|
|
|
|
benefit from those optimizations if they so choose.
|
|
|
|
|
|
|
|
|
|
In YJL this is accomplished with the `%cpuoptimize` macro.
|
|
|
|
|
|
|
|
|
|
### The `Release:` metadata tag
|
|
|
|
|
|
|
|
|
|
When a spec file offers CPU specific optimization, the RPM `Release:`
|
|
|
|
|
metadata tag *must* have `%{?cpuoptimize}` at the *very end* of the
|
|
|
|
|
tag *directly after* the `%{?dist}` tag.
|
|
|
|
|
|
|
|
|
|
If the `%cpuoptimize` macro is not defined, then `%{?cpuoptimize}`
|
|
|
|
|
will expand to a zero-length string. When it is defined then the RPM
|
|
|
|
|
package name itself indicates it is a CPU optimized package that should
|
|
|
|
|
only be installed on that a CPU with the specific capabilities the
|
|
|
|
|
build is optimized for.
|
|
|
|
|
|
|
|
|
|
As the `%cpuoptimize` macro is used at the end of the `Release:` tag,
|
|
|
|
|
when defined it *must* begin with a `.` and *must not* end with a `.`
|
|
|
|
|
or the `Release:` metadata will be broken.
|
|
|
|
|
|
|
|
|
|
### Package Build Optimization
|
|
|
|
|
|
|
|
|
|
In cases where the RPM spec file has to take specific action to build
|
|
|
|
|
a generic package, use the following:
|
|
|
|
|
|
|
|
|
|
%if 0%{!?cpuoptimize:1} == 1
|
|
|
|
|
[do stuff]
|
|
|
|
|
%endif
|
|
|
|
|
|
|
|
|
|
An example of that scenario can be seen in the [gmp.spec](SPECS/gmp.spec]
|
|
|
|
|
file, where the action takes place during `%setup`.
|
|
|
|
|
|
|
|
|
|
In cases where the RPM spec file has to take specific action to build
|
|
|
|
|
an optimized package, use the following:
|
|
|
|
|
|
|
|
|
|
%if 0%{?cpuoptimize:1} == 1
|
|
|
|
|
[do stuff]
|
|
|
|
|
%endif
|
|
|
|
|
|
2023-04-28 18:08:59 +08:00
|
|
|
|
### Defining the `%cpuoptimize` macro
|
2023-04-17 05:11:00 +08:00
|
|
|
|
|
|
|
|
|
For packages like GMP where the build script itself determines the
|
|
|
|
|
proper optimizations to make, it does not really matter what the macro
|
|
|
|
|
is defined to be as long as it begins with a `.`, does not end with a
|
2023-04-28 18:08:59 +08:00
|
|
|
|
`.`, and otherwise only contains characters legal in an RPM `Release:`
|
2023-04-17 05:11:00 +08:00
|
|
|
|
metadata tag.
|
|
|
|
|
|
|
|
|
|
Currently in my `~/.rpmmacros` file I have the following:
|
|
|
|
|
|
2023-04-17 05:15:59 +08:00
|
|
|
|
%cpuoptimize .xeonE3
|
2023-04-17 05:11:00 +08:00
|
|
|
|
|
2023-04-17 05:17:17 +08:00
|
|
|
|
However there may be optimizations where the build scripts (e.g.
|
|
|
|
|
`configure`) has to be specifically told what optimizations to make.
|
2023-04-17 05:11:00 +08:00
|
|
|
|
|
|
|
|
|
It may be necessary to develop a standard list of valid `%cpuoptimize`
|
|
|
|
|
definitions to deal with cases where the build scripts have to be told
|
|
|
|
|
how to optimize the package.
|
|
|
|
|
|
|
|
|
|
At present, there are no plans to distribute CPU optimized packages.
|
|
|
|
|
I do however desire to make it easy for the user to just rebuild a
|
|
|
|
|
source package and get such optimization.
|
|
|
|
|
|
|
|
|
|
### CPU Optimized Kernel
|
|
|
|
|
|
|
|
|
|
Linux kernel optimization is not done within the RPM spec file itself
|
|
|
|
|
but is performed during `make config`. Kernel packages should not use
|
|
|
|
|
this macro tag.
|
|
|
|
|
|
|
|
|
|
|
2023-04-28 18:08:59 +08:00
|
|
|
|
Perl Specific Macros
|
|
|
|
|
--------------------
|
|
|
|
|
|
|
|
|
|
For Perl, see [Perl Modules](05-Perl-Modules.md)
|
|
|
|
|
|
|
|
|
|
|
2023-04-17 05:11:00 +08:00
|
|
|
|
TODO --- Python Custom Macros
|
|
|
|
|
-----------------------------
|
|
|
|
|
|
|
|
|
|
Will add when I upload the `python3.spec` and `python2.spec` RPM spec
|
|
|
|
|
files.
|