During Hackweek 20 at SUSE I created some rpm macros to create packages easily that use the glibc-hwcaps feature. There’s a post with the journal from the hackweek in case you want to read it. Here I’ll just explain how to use the new macros I created.
The package definition
First you have to add a BuildRequires
to use the macros:
BuildRequires: microarch-rpm-macros
Then before the %description
section, you have to add a line like:
%microarch_subpackage -n %{libname}
The %microarch_subpackage
macro is used to generate the subpackage sections. It’s important that the parameter passed to it is the same as the parameter passed to the %package
section that defines the library package. It’ll also generate the %files
section with the same contents as the %files
section in the library package but with the directory adapted to the microarchitecture of each subpackage.
The %build
section
Let’s consider the following code in the build section:
autoreconf -fiv
%configure \
--with-pic \
--disable-static
make %{?_smp_mflags} CFLAGS="%{optflags}"
We will replace that with:
autoreconf -fiv
%{microarch_build %$configure \
--with-pic \
--disable-static
make %{?_smp_mflags} CFLAGS="%{$optflags}"
}
The %microarch_build
macro will take care of executing 4 times the code within to build the baseline
version of the package and then the x86-64-v2
, x86-64-v3
and x86-64-v4
versions, each in a different directory and with different %optflags
values which include the respective -march
and -mtune
parameters in each case as well as different %_libdir
values so the library is installed to the right place later in %install
.
Note that %configure
was replaced with %$configure
and %{optflags}
was replaced with %{$optflags}
. This is done so that they’re not expanded before passing the arguments to %microarch_build
.
Also note that the autoreconf
execution was left out of the macro. This is so that the configure script is generated in the root source directory. Then the %microarch_build
macro can generate build.x86-64-vN
directories and put there the build files.
In my test with the bzip2 package I had a special case. If the %do_profiling boolean is set then code is built, the tests are executed and then the code is built again with the generated profiling information. The %build section used was:
%configure \
--with-pic \
--disable-static
%if 0%{?do_profiling}
make %{?_smp_mflags} CFLAGS="%{optflags} %{cflags_profile_generate}"
make %{?_smp_mflags} CFLAGS="%{optflags} %{cflags_profile_generate}" test
make %{?_smp_mflags} clean
make %{?_smp_mflags} CFLAGS="%{optflags} %{cflags_profile_feedback}"
%else
make %{?_smp_mflags} CFLAGS="%{optflags}"
%endif
And I replaced that with:
%{microarch_build %$configure \
--with-pic \
--disable-static
%if 0%{?do_profiling} && "%{$microarch_current_flavor}" == "x86-64"
make %{?_smp_mflags} CFLAGS="%{$optflags} %{cflags_profile_generate}"
make %{?_smp_mflags} CFLAGS="%{$optflags} %{cflags_profile_generate}" test
make %{?_smp_mflags} clean
make %{?_smp_mflags} CFLAGS="%{$optflags} %{cflags_profile_feedback}"
%else
make %{?_smp_mflags} CFLAGS="%{$optflags}"
%endif
}
Note that here again I used a $ within %{$microarch_current_flavor}
so it can be replaced in each flavor with the right value.
The %install
section
%install
sections usually consist on running something like %make_install
and then maybe installing some files manually. In this case, we would replace this:
%make_install pkgconfigdir=%{_libdir}/pkgconfig
install -Dpm 0755 foo %{buildroot}%{_bindir}/foo
install -m 0644 %{SOURCE2} %{buildroot}%{_mandir}/man1
with:
%microarch_install %make_install pkgconfigdir=%{_libdir}/pkgconfig
install -Dpm 0755 foo %{buildroot}%{_bindir}/foo
install -m 0644 %{SOURCE2} %{buildroot}%{_mandir}/man1
%microarch_install
will run the argument passed to it 4 times but first it’ll run the microarch flavors and the baseline flavor will be run last.
Note that after the flavors are installed and before the baseline installation is done, it’ll remove all *.so files within the glibc-hwcaps directories since we don’t want development files in there.
The %check
section
In the %check
section packages usually run the generated binaries to test they work as expected. Note that we can’t do that for all flavors since we may not have a recent enough CPU to run them. Because of this, I opted to just check the baseline flavor.
Just replace
make %{?_smp_mflags} test
or anything you have to run from the build directory in %check
with:
pushd %microarch_baseline_builddir
make %{?_smp_mflags} test
popd
And that should be enough for the simple case of bzip2 and similar packages.
Please note that this is work in progress and currently using the macros with %cmake or %meson will fail and is not supported yet. Check the conclusions on the previous post for information about what’s still missing.