]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
docs: Make "Building rpms from source" non-dnf specific
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 13 Feb 2024 20:24:42 +0000 (21:24 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 14 Feb 2024 10:36:35 +0000 (11:36 +0100)
Let's make the doc non-dnf specific by not relying on dnf builddep
and using mkosi-install to install packages. This allows using the
same logic for opensuse images.

We also simplify things by only installing --buildrequires since
trying to cache --requires from the rpm spec isn't very useful as
most of the --requires dependencies are automatically generated and
won't be listed by rpmspec --requires in the first place.

docs/building-rpms-from-source.md
mkosi.conf.d/30-rpm/mkosi.postinst
mkosi.conf.d/30-rpm/mkosi.prepare

index ed0111b5cebd8a62aaace58ab00ef1cb46247fba..1eb4ec422111cf0a6074de48669d3214e6f65bd2 100644 (file)
@@ -11,11 +11,10 @@ If you want to build an RPM from source and install it within a mkosi
 image, you can do that with mkosi itself without using `mock`. The steps
 required are as follows:
 
-1. Install `Requires` dependencies in the image
-2. Install `BuildRequires` dependencies in the build overlay
-3. Install dynamic `BuildRequires` dependencies in the build overlay
-4. Build the RPM with `rpmbuild`
-5. Install the built rpms in the image
+1. Install `BuildRequires` dependencies in the build overlay
+1. Install dynamic `BuildRequires` dependencies in the build overlay
+1. Build the RPM with `rpmbuild`
+1. Install the built rpms in the image
 
 In the following examples, we'll use mkosi itself and its Fedora RPM
 spec as an example.
@@ -62,62 +61,77 @@ The prepare script `mkosi.prepare` then looks as follows:
 #!/bin/sh
 set -e
 
-if [ "$1" = "build" ]; then
-    DEPS="--buildrequires"
-else
-    DEPS="--requires"
+if [ "$1" = "final" ]; then
+    exit 0
 fi
 
 mkosi-chroot \
+    env --chdir=mkosi \
     rpmspec \
     --query \
-    "$DEPS" \
+    --buildrequires \
     --define "_topdir /var/tmp" \
-    --define "_sourcedir mkosi/rpm" \
-    mkosi/rpm/mkosi.spec |
-        grep -E -v mkosi |
-        xargs -d '\n' dnf install
-
-if [ "$1" = "build" ]; then
-    until mkosi-chroot \
-        env --chdir=mkosi \
-        rpmbuild \
-        -bd \
-        --build-in-place \
-        --define "_topdir /var/tmp" \
-        --define "_sourcedir rpm" \
-        --define "_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" \
-        rpm/mkosi.spec
-    do
-        EXIT_STATUS=$?
-        if [ $EXIT_STATUS -ne 11 ]; then
-            exit $EXIT_STATUS
-        fi
-
-        dnf builddep /var/tmp/SRPMS/mkosi-*.buildreqs.nosrc.rpm
-    done
-fi
+    --define "_sourcedir rpm" \
+    rpm/mkosi.spec |
+        sort --unique |
+        tee /tmp/buildrequires |
+        xargs --delimiter '\n' mkosi-install
+
+until mkosi-chroot \
+    env --chdir=mkosi \
+    rpmbuild \
+    -bd \
+    --build-in-place \
+    --define "_topdir /var/tmp" \
+    --define "_sourcedir rpm" \
+    --define "_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" \
+    rpm/mkosi.spec
+do
+    EXIT_STATUS=$?
+    if [ $EXIT_STATUS -ne 11 ]; then
+        exit $EXIT_STATUS
+    fi
+
+    mkosi-chroot \
+        rpm \
+        --query \
+        --package \
+        --requires \
+        /var/tmp/SRPMS/mkosi-*.buildreqs.nosrc.rpm |
+            grep --invert-match '^rpmlib(' |
+            sort --unique >/tmp/dynamic-buildrequires
+
+    sort /tmp/buildrequires /tmp/dynamic-buildrequires |
+        uniq --unique |
+        tee --append /tmp/buildrequires |
+        xargs --delimiter '\n' mkosi-install
+done
 ```
 
 To install non-dynamic dependencies, we use `rpmspec`. What's important
 is to set `_sourcedir` to the directory containing the RPM sources for
 the RPM spec that we want to build. We run `rpmspec` inside the image to
 make sure all the RPM macros have their expected values and then run
-`dnf` outside the image to install the required dependencies.
+`mkosi-install` outside the image to install the required dependencies.
+`mkosi-install` will invoke the package manager that's being used to
+build the image to install the given packages.
 
 We always set `_topdir` to `/var/tmp` to avoid polluting the image with
 `rpmbuild` artifacts.
 
-Subpackages from the same RPM might depend on each other. We need to
-filter out those dependencies using `grep -E -v <package-name>`.
-
-After installing non-dynamic `Requires` and `BuildRequires`
-dependencies, we have to install the dynamic `BuildRequires` by running
-`rpmbuild -bd` until it succeeds or fails with an exit code that's not
-`11`. After each run of `rpmbuild -bd` that exits with exit code `11`,
-there will be an SRPM in the `SRPMS` subdirectory of the upstream
-sources directory of which the `BuildRequires` have to be installed for
-which we use `dnf builddep`.
+After installing non-dynamic `BuildRequires` dependencies, we have to
+install the dynamic `BuildRequires` dependencies by running `rpmbuild
+-bd` until it succeeds or fails with an exit code that's not `11`. After
+each run of `rpmbuild -bd` that exits with exit code `11`, there will be
+an SRPM in the `SRPMS` subdirectory of the rpm working directory
+(`_topdir`) of which the `BuildRequires` dependencies have to be
+installed. We retrieve the list of `BuildRequires` dependencies with
+`rpm` this time (because we're operating on a package instead of a
+spec), remove all `rpmlib` style dependencies which can't be installed
+and store them in a temporary file after filtering duplicates. Because
+the `BuildRequires` dependencies from the SRPM will also contain the
+non-dynamic `BuildRequires` dependencies, we have to filter those out as
+well.
 
 Now we have an image and build overlay with all the necessary
 dependencies installed to be able to build the RPM.
index 89b6ff46564c489465d6baa5d4793ffe5491cf36..3076f26ef59369a700599eabe5908d90127837bd 100755 (executable)
@@ -2,4 +2,4 @@
 # SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
-dnf install --best mkosi
+mkosi-install mkosi
index b21336ab3bfb9b779e7de0db6c1b241654b98230..7485f0b184799e62697e081471a4260067112d5d 100755 (executable)
@@ -2,37 +2,42 @@
 # SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
-if [ "$1" = "build" ]; then
-    DEPS="--buildrequires"
-else
-    DEPS="--requires"
-fi
-
 mkosi-chroot \
     rpmspec \
     --query \
-    "$DEPS" \
+    --buildrequires \
     --define "_topdir /var/tmp" \
     --define "_sourcedir rpm" \
     rpm/mkosi.spec |
-        grep -E -v mkosi |
-        xargs -d '\n' dnf install
+        sort --unique |
+        tee /tmp/buildrequires |
+        xargs --delimiter '\n' mkosi-install
+
+until mkosi-chroot \
+    rpmbuild \
+    -bd \
+    --build-in-place \
+    --define "_topdir /var/tmp" \
+    --define "_sourcedir rpm" \
+    --define "_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" \
+    rpm/mkosi.spec
+do
+    EXIT_STATUS=$?
+    if [ $EXIT_STATUS -ne 11 ]; then
+        exit $EXIT_STATUS
+    fi
 
-if [ "$1" = "build" ]; then
-    until mkosi-chroot \
-        rpmbuild \
-        -bd \
-        --build-in-place \
-        --define "_topdir /var/tmp" \
-        --define "_sourcedir rpm" \
-        --define "_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" \
-        rpm/mkosi.spec
-    do
-        EXIT_STATUS=$?
-        if [ $EXIT_STATUS -ne 11 ]; then
-            exit $EXIT_STATUS
-        fi
+    mkosi-chroot \
+        rpm \
+        --query \
+        --package \
+        --requires \
+        /var/tmp/SRPMS/mkosi-*.buildreqs.nosrc.rpm |
+            grep --invert-match '^rpmlib(' |
+            sort --unique >/tmp/dynamic-buildrequires
 
-        dnf builddep /var/tmp/SRPMS/mkosi-*.buildreqs.nosrc.rpm
-    done
-fi
+    sort /tmp/buildrequires /tmp/dynamic-buildrequires |
+        uniq --unique |
+        tee --append /tmp/buildrequires |
+        xargs --delimiter '\n' mkosi-install
+done