Message ID | 20200227155029.2542-1-dannym@scratchpost.org |
---|---|
State | Accepted |
Headers | show |
Series | [bug#37868,v8] system: Add kernel-module-packages to operating-system. | expand |
Context | Check | Description |
---|---|---|
cbaines/comparison | success | View comparision |
cbaines/git branch | success | View Git branch |
cbaines/applying patch | success | View Laminar job |
Hello, I'd like to push the patch to master on tuesday (with some minimal changes to the commit message). The only part I'm still unsure about is: ;; TODO: system, target. (profile-derivation (packages->manifest (cons kernel modules)) #:hooks (list linux-module-database) #:locales? #f #:allow-collisions? #f #:relative-symlinks? #t)) Will Guix do the derivation (especially the invocation of depmod) for the intended system and target? Apparently, module-init-tools are supposed to be cross-platform anyway and work when invoking depmod for files of an other architecture than the architecture depmod is invoked on (and was compiled for). So maybe we can also just ignore the entire system/target propagation in this case. To test that, I tried ./pre-inst-env guix build -s armhf-linux -m etc/system-tests.scm and that seems to hang while compiling the kernel (?). I'm confident that that has no connection to the patch because it hangs earlier (at "AR drivers/net/built-in.a"). Then I tried ./pre-inst-env guix build --target=xxx -m etc/system-tests.scm and that seems to ignore target entirely. [1] http://lists.busybox.net/pipermail/uclibc/2005-May/032671.html
Hello Danny, > Will Guix do the derivation (especially the invocation of depmod) for the > intended system and target? Yes, "profile-derivation" should use the current system or target if the #:system and #:target arguments are #f. > Apparently, module-init-tools are supposed to be cross-platform anyway and work > when invoking depmod for files of an other architecture than the architecture > depmod is invoked on (and was compiled for). So maybe we can also just ignore > the entire system/target propagation in this case. In that case, you should use #+kmod instead of #$kmod. This way, when cross-compiling, the native kmod would be used. > Then I tried > > ./pre-inst-env guix build --target=xxx -m etc/system-tests.scm > > and that seems to ignore target entirely. I'm not sure this has ever been tested. Support of cross-compilation for Guix System is still wip, even if since a few days, core-updates is in a good shape. Anyway, if you're willing to wait a few days, I can test your patch does not break system cross-compilation on core-updates. Regarding --system, producing disk-images is currently broken on all branches[1], so it will be harder to test it for now. Also, here are a few remarks about your patch. +(define (depmod! kmod version output) + "Given an (existing) OUTPUT directory, invoke KMOD's depmod on it for +kernel version VERSION." "OUTPUT" is maybe not the best naming as you read multiple "input" files from it. Maybe just "DIRECTORY"? + (let ((destination-directory (string-append output "/lib/modules/" version)) + ;; Note: "System.map" is an input file. + (maps-file (string-append output "/System.map")) + ;; Note: "Module.symvers" is an input file. + (symvers-file (string-append output "/Module.symvers"))) + (for-each (lambda (basename) + (when (and (string-prefix? "modules." basename) + ;; Note: "modules.builtin" is an input file. + (not (string=? "modules.builtin" basename)) + ;; Note: "modules.order" is an input file. + (not (string=? "modules.order" basename))) + (delete-file (string-append destination-directory "/" + basename)))) You can maybe add a comment explaining what's the point of this operation. + (scandir destination-directory)) + (invoke (string-append kmod "/bin/depmod") + "-e" ; Report symbols that aren't supplied + ;"-w" ; Warn on duplicates + "-b" output + "-F" maps-file + "-E" symvers-file The man page of depmod says that '-F' and '-E' options are mutually exclusive. + (let* ((versions (filter (lambda (name) + (not (string-prefix? "." name))) + (scandir moddir))) + (version (match versions + ((x) x)))) If versions only contains one element, then you can use find instead of filtering and matching. + ;; TODO: system, target. + (profile-derivation + (packages->manifest + (cons kernel modules)) + #:hooks (list linux-module-database) + #:locales? #f + #:allow-collisions? #f + #:relative-symlinks? #t)) + (initrd -> (operating-system-initrd-file os)) + (params (operating-system-boot-parameters-file os))) As stated above, I think you are fine removing the TODO. +(define (input-files inputs path) + "Given a list of directories INPUTS, return all entries with PATH in it." + ;; TODO: Use filter-map. + #~(begin + (use-modules (srfi srfi-1)) + (filter file-exists? + (map (lambda (x) + (string-append x #$path)) + '#$inputs)))) + This TODO can be resolved I think :) +(define (linux-module-database manifest) + "Return a derivation that unions all the kernel modules in the manifest +and creates the dependency graph for all these kernel modules." + (mlet %store-monad ((kmod (manifest-lookup-package manifest "kmod"))) + (define build + (with-imported-modules (source-module-closure '((guix build utils) (gnu build linux-modules))) + #~(begin + (use-modules (ice-9 ftw)) + (use-modules (ice-9 match)) + (use-modules (srfi srfi-1)) ; append-map + (use-modules (guix build utils)) ; mkdir-p + (use-modules (gnu build linux-modules)) ; make-linux-module-directory + (let* ((inputs '#$(manifest-inputs manifest)) + (module-directories #$(input-files (manifest-inputs manifest) "/lib/modules")) + (directory-entries + (lambda (directory-name) + (scandir directory-name (lambda (basename) + (not (string-prefix? "." basename)))))) + ;; Note: Should usually result in one entry. + (versions (delete-duplicates + (append-map directory-entries + module-directories)))) This part is over the column limit. + (match versions + ((version) + (make-linux-module-directory #$kmod inputs version #$output))) If depmod output is system agnostic, then we should use #+kmod. If that's not the case, this will be an issue as running #$kmod won't work when cross-compiling. Thanks, Mathieu
> Regarding --system, producing disk-images is currently broken on all > branches[1], so it will be harder to test it for now. And the forgotten link! [1]: https://lists.gnu.org/archive/html/guix-devel/2019-12/msg00099.html Mathieu
Hi Mathieu, On Sun, 15 Mar 2020 11:28:37 +0100 Mathieu Othacehe <m.othacehe@gmail.com> wrote: > Yes, "profile-derivation" should use the current system or target if the > #:system and #:target arguments are #f. OK! > In that case, you should use #+kmod instead of #$kmod. This way, when > cross-compiling, the native kmod would be used. > Anyway, if you're willing to wait a few days, I can test your patch does > not break system cross-compilation on core-updates. Sure. > The man page of depmod says that '-F' and '-E' options are mutually > exclusive. Linus Torvalds seems to be in favor of not supporting Module.symvers anymore, so let's use "-F"... > > + (let* ((versions (filter (lambda (name) > + (not (string-prefix? "." name))) > + (scandir moddir))) > + (version (match versions > + ((x) x)))) > > If versions only contains one element, then you can use find instead of > filtering and matching. I don't really know that it only contains one element. In normal supported operation it should--but if the user does something stupid (put kernel version A and module version B into the operating-system, where A != B), I want it to fail and not depmod half the things (neither all the things, for that matter). > As stated above, I think you are fine removing the TODO. Cool!
Hi, Danny Milosavljevic <dannym@scratchpost.org> skribis: > The only part I'm still unsure about is: > > ;; TODO: system, target. > (profile-derivation > (packages->manifest > (cons kernel modules)) > #:hooks (list linux-module-database) > #:locales? #f > #:allow-collisions? #f > #:relative-symlinks? #t)) > > Will Guix do the derivation (especially the invocation of depmod) for the > intended system and target? I would just write a test OS definition, and then run: ./pre-inst-env guix system build test.scm -nd -s armhf-linux From there, you can inspect the ‘linux-module-database’ derivation, check its system type, and check the kmod referred to in its “-builder” file (is it the file name of the armhf-linux kmod?). Likewise for cross-compilation. HTH! Ludo’.
Hello Danny, I tested you patch by cross-compiling a simple system for aarch64-gnu-linux with: --8<---------------cut here---------------start------------->8--- (kernel-loadable-modules (list acpi-call-linux-module)) --8<---------------cut here---------------end--------------->8--- However, I have the following error: --8<---------------cut here---------------start------------->8--- guix system: error: gnu/packages/linux.scm:886:2: acpi-call-linux-module@3.17: build system `linux-module' does not support cross builds --8<---------------cut here---------------end--------------->8--- This is not caused by your patch, but it prevents me from testing :( Thanks, Mathieu
Hi Mathieu, On Mon, 16 Mar 2020 10:55:57 +0100 Mathieu Othacehe <m.othacehe@gmail.com> wrote: > --8<---------------cut here---------------start------------->8--- > guix system: error: gnu/packages/linux.scm:886:2: acpi-call-linux-module@3.17: build system `linux-module' does not support cross builds > --8<---------------cut here---------------end--------------->8--- > > This is not caused by your patch, but it prevents me from testing :( That's too bad. I tried to preserve cross-compilation in guix/build-system/linux-module.scm but apparently I missed something. Sorry! It could just be the (not target) ;XXX: no cross-compilation in guix/build-system/linux-module.scm - because the other file should support it just fine.
Danny Milosavljevic <dannym@scratchpost.org> skribis: > On Mon, 16 Mar 2020 10:55:57 +0100 > Mathieu Othacehe <m.othacehe@gmail.com> wrote: > >> --8<---------------cut here---------------start------------->8--- >> guix system: error: gnu/packages/linux.scm:886:2: acpi-call-linux-module@3.17: build system `linux-module' does not support cross builds >> --8<---------------cut here---------------end--------------->8--- >> >> This is not caused by your patch, but it prevents me from testing :( > > That's too bad. > > I tried to preserve cross-compilation in guix/build-system/linux-module.scm > but apparently I missed something. Sorry! > > It could just be the > > (not target) ;XXX: no cross-compilation Yes, it means that ‘linux-module-build-system’ does not return a bag when cross-compiling. See ‘gnu-build-system’ for how to support cross-compilation. In the meantime, Mathieu, perhaps you can test system cross-compilation by using a ‘computed-file’ (instead of a package) as a fake package providing modules? Thanks, Ludo’.
Hello Danny, > It could just be the > > (not target) ;XXX: no cross-compilation > > in guix/build-system/linux-module.scm - because the other file should support > it just fine. Removing the (not target) is enough to make it build. However, when running: --8<---------------cut here---------------start------------->8--- guix build --target=aarch64-linux-gnu acpi-call-linux-module --8<---------------cut here---------------end--------------->8--- the produced module does not seem to be cross-compiled: --8<---------------cut here---------------start------------->8--- mathieu@meru:~/guix$ file /gnu/store/fkk5cd746xxh1nx4qvi7arzhznf37yxw-acpi-call-linux-module-3.17/lib/modules/5.4.25-gnu/extra/acpi_call.ko /gnu/store/fkk5cd746xxh1nx4qvi7arzhznf37yxw-acpi-call-linux-module-3.17/lib/modules/5.4.25-gnu/extra/acpi_call.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), BuildID[sha1]=a1d9e0ec7b8ef5096a4e1b5c2e7ca6a8bd524cf9, not stripped --8<---------------cut here---------------end--------------->8--- Thanks, Mathieu
Whoops. weird. guix/build/linux-module-build-system.scm sets CROSS_COMPILE up so it should have worked. Did it print the message (format #t "`CROSS_COMPILE' set to `~a'~%" (getenv "CROSS_COMPILE"))) ?
Ohhhh, try adding (target target) to the bag in guix/build-system/linux-module.scm
Hey! Mathieu Othacehe <m.othacehe@gmail.com> skribis: >> It could just be the >> >> (not target) ;XXX: no cross-compilation >> >> in guix/build-system/linux-module.scm - because the other file should support >> it just fine. > > Removing the (not target) is enough to make it build. But then it’s a native build. :-) Ludo’.
Hi Mathieu, what happen if there are no kernel-module-packages and one is cross-compiling? Then (native) depmod should still be invoked on linux-libre's modules. I think that that case is the most important to test in order to avoid regressions.
Hello Danny, > Then (native) depmod should still be invoked on linux-libre's modules. > > I think that that case is the most important to test in order to avoid > regressions. You are right and it that case, everything seems to work fine! It would be nice to fix linux-module-build-system cross-compilation, but I think that it can be done later. Mathieu
diff --git a/doc/guix.texi b/doc/guix.texi index a66bb3d646..01e2d1ab57 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -11197,6 +11197,9 @@ The package object of the operating system kernel to use@footnote{Currently only the Linux-libre kernel is supported. In the future, it will be possible to use the GNU@tie{}Hurd.}. +@item @code{kernel-loadable-modules} (default: '()) +A list of objects (usually packages) to collect loadable kernel modules from. + @item @code{kernel-arguments} (default: @code{'("quiet")}) List of strings or gexps representing additional arguments to pass on the command-line of the kernel---e.g., @code{("console=ttyS0")}. diff --git a/gnu/build/linux-modules.scm b/gnu/build/linux-modules.scm index a149eff329..0b11c52103 100644 --- a/gnu/build/linux-modules.scm +++ b/gnu/build/linux-modules.scm @@ -22,12 +22,14 @@ #:use-module (guix elf) #:use-module (guix glob) #:use-module (guix build syscalls) - #:use-module ((guix build utils) #:select (find-files)) + #:use-module ((guix build utils) #:select (find-files invoke)) + #:use-module (guix build union) #:use-module (rnrs io ports) #:use-module (rnrs bytevectors) #:use-module (srfi srfi-1) #:use-module (srfi srfi-11) #:use-module (srfi srfi-26) + #:use-module (ice-9 ftw) #:use-module (ice-9 vlist) #:use-module (ice-9 match) #:use-module (ice-9 rdelim) @@ -56,7 +58,9 @@ write-module-name-database write-module-alias-database - write-module-device-database)) + write-module-device-database + + make-linux-module-directory)) ;;; Commentary: ;;; @@ -631,4 +635,37 @@ be loaded on-demand, such as file system modules." module devname type major minor))) aliases)))) +(define (depmod! kmod version output) + "Given an (existing) OUTPUT directory, invoke KMOD's depmod on it for +kernel version VERSION." + (let ((destination-directory (string-append output "/lib/modules/" version)) + ;; Note: "System.map" is an input file. + (maps-file (string-append output "/System.map")) + ;; Note: "Module.symvers" is an input file. + (symvers-file (string-append output "/Module.symvers"))) + (for-each (lambda (basename) + (when (and (string-prefix? "modules." basename) + ;; Note: "modules.builtin" is an input file. + (not (string=? "modules.builtin" basename)) + ;; Note: "modules.order" is an input file. + (not (string=? "modules.order" basename))) + (delete-file (string-append destination-directory "/" + basename)))) + (scandir destination-directory)) + (invoke (string-append kmod "/bin/depmod") + "-e" ; Report symbols that aren't supplied + ;"-w" ; Warn on duplicates + "-b" output + "-F" maps-file + "-E" symvers-file + version))) + +(define (make-linux-module-directory kmod inputs version output) + "Create a new directory OUTPUT and ensure that the directory +OUTPUT/lib/modules/VERSION can be used as a source of Linux +kernel modules for KMOD to eventually load. Take modules to +put into OUTPUT from INPUTS." + (union-build output inputs #:create-all-directories? #t) + (depmod! kmod version output)) + ;;; linux-modules.scm ends here diff --git a/gnu/local.mk b/gnu/local.mk index 857345cfad..b25c3ceea5 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -631,6 +631,7 @@ GNU_SYSTEM_MODULES = \ %D%/tests/nfs.scm \ %D%/tests/install.scm \ %D%/tests/ldap.scm \ + %D%/tests/linux-modules.scm \ %D%/tests/mail.scm \ %D%/tests/messaging.scm \ %D%/tests/networking.scm \ diff --git a/gnu/packages/linux.scm b/gnu/packages/linux.scm index 78182555c1..32b802bab4 100644 --- a/gnu/packages/linux.scm +++ b/gnu/packages/linux.scm @@ -675,6 +675,7 @@ for ARCH and optionally VARIANT, or #f if there is no such configuration." (guix build utils) (srfi srfi-1) (srfi srfi-26) + (ice-9 ftw) (ice-9 match)) #:phases (modify-phases %standard-phases @@ -760,12 +761,26 @@ for ARCH and optionally VARIANT, or #f if there is no such configuration." ;; Install kernel modules (mkdir-p moddir) (invoke "make" - (string-append "DEPMOD=" kmod "/bin/depmod") + ;; Disable depmod because the Guix system's module directory + ;; is an union of potentially multiple packages. It is not + ;; possible to use depmod to usefully calculate a dependency + ;; graph while building only one of those packages. + "DEPMOD=true" (string-append "MODULE_DIR=" moddir) (string-append "INSTALL_PATH=" out) (string-append "INSTALL_MOD_PATH=" out) "INSTALL_MOD_STRIP=1" - "modules_install"))))) + "modules_install") + (let* ((versions (filter (lambda (name) + (not (string-prefix? "." name))) + (scandir moddir))) + (version (match versions + ((x) x)))) + (false-if-file-not-found + (delete-file (string-append moddir "/" version "/build"))) + (false-if-file-not-found + (delete-file (string-append moddir "/" version "/source")))) + #t)))) #:tests? #f)) (home-page "https://www.gnu.org/software/linux-libre/") (synopsis "100% free redistribution of a cleaned Linux kernel") diff --git a/gnu/system.scm b/gnu/system.scm index 01baa248a2..17b6e667d5 100644 --- a/gnu/system.scm +++ b/gnu/system.scm @@ -5,6 +5,7 @@ ;;; Copyright © 2016 Chris Marusich <cmmarusich@gmail.com> ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> ;;; Copyright © 2019 Meiyo Peng <meiyo.peng@gmail.com> +;;; Copyright © 2020 Danny Milosavljevic <dannym@scratchpost.org> ;;; ;;; This file is part of GNU Guix. ;;; @@ -164,6 +165,8 @@ (kernel operating-system-kernel ; package (default linux-libre)) + (kernel-loadable-modules operating-system-kernel-loadable-modules + (default '())) ; list of packages (kernel-arguments operating-system-user-kernel-arguments (default '("quiet"))) ; list of gexps/strings (bootloader operating-system-bootloader) ; <bootloader-configuration> @@ -468,9 +471,20 @@ OS." "Return the basic entries of the 'system' directory of OS for use as the value of the SYSTEM-SERVICE-TYPE service." (let ((locale (operating-system-locale-directory os))) - (mlet %store-monad ((kernel -> (operating-system-kernel os)) - (initrd -> (operating-system-initrd-file os)) - (params (operating-system-boot-parameters-file os))) + (mlet* %store-monad ((kernel -> (operating-system-kernel os)) + (modules -> + (operating-system-kernel-loadable-modules os)) + (kernel + ;; TODO: system, target. + (profile-derivation + (packages->manifest + (cons kernel modules)) + #:hooks (list linux-module-database) + #:locales? #f + #:allow-collisions? #f + #:relative-symlinks? #t)) + (initrd -> (operating-system-initrd-file os)) + (params (operating-system-boot-parameters-file os))) (return `(("kernel" ,kernel) ("parameters" ,params) ("initrd" ,initrd) diff --git a/gnu/tests/linux-modules.scm b/gnu/tests/linux-modules.scm new file mode 100644 index 0000000000..82b9627639 --- /dev/null +++ b/gnu/tests/linux-modules.scm @@ -0,0 +1,102 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.org> +;;; Copyright © 2020 Danny Milosavljevic <dannym@scratchpost.org> +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +(define-module (gnu tests linux-modules) + #:use-module (gnu packages linux) + #:use-module (gnu system) + #:use-module (gnu system vm) + #:use-module (gnu tests) + #:use-module (guix derivations) + #:use-module (guix gexp) + #:use-module (guix modules) + #:use-module (guix monads) + #:use-module (guix store) + #:export (%test-loadable-kernel-modules-0 + %test-loadable-kernel-modules-1 + %test-loadable-kernel-modules-2)) + +;;; Commentary: +;;; +;;; Test <operating-system> kernel-loadable-modules. +;;; +;;; Code: + +(define* (module-loader-program os modules) + "Return an executable store item that, upon being evaluated, will dry-run +load MODULES." + (program-file + "load-kernel-modules.scm" + (with-imported-modules (source-module-closure '((guix build utils))) + #~(begin + (use-modules (guix build utils)) + (for-each (lambda (module) + (invoke (string-append #$kmod "/bin/modprobe") "-n" "--" module)) + '#$modules))))) + +(define* (run-loadable-kernel-modules-test module-packages module-names) + "Run a test of an OS having MODULE-PACKAGES, and modprobe MODULE-NAMES." + (define os + (marionette-operating-system + (operating-system + (inherit (simple-operating-system)) + (kernel-loadable-modules module-packages)) + #:imported-modules '((guix combinators)))) + (define vm (virtual-machine os)) + (define (test script) + (with-imported-modules '((gnu build marionette)) + #~(begin + (use-modules (gnu build marionette) + (srfi srfi-64)) + (define marionette + (make-marionette (list #$vm))) + (mkdir #$output) + (chdir #$output) + (test-begin "loadable-kernel-modules") + (test-assert "script successfully evaluated" + (marionette-eval + '(primitive-load #$script) + marionette)) + (test-end) + (exit (= (test-runner-fail-count (test-runner-current)) 0))))) + (gexp->derivation "loadable-kernel-modules" (test (module-loader-program os module-names)))) + +(define %test-loadable-kernel-modules-0 + (system-test + (name "loadable-kernel-modules-0") + (description "Tests loadable kernel modules facility of <operating-system> +with no extra modules.") + (value (run-loadable-kernel-modules-test '() '())))) + +(define %test-loadable-kernel-modules-1 + (system-test + (name "loadable-kernel-modules-1") + (description "Tests loadable kernel modules facility of <operating-system> +with one extra module.") + (value (run-loadable-kernel-modules-test + (list ddcci-driver-linux) + '("ddcci"))))) + +(define %test-loadable-kernel-modules-2 + (system-test + (name "loadable-kernel-modules-2") + (description "Tests loadable kernel modules facility of <operating-system> +with two extra modules.") + (value (run-loadable-kernel-modules-test + (list acpi-call-linux-module ddcci-driver-linux) + '("acpi_call" "ddcci"))))) diff --git a/guix/profiles.scm b/guix/profiles.scm index 0d38b2513f..e39067db04 100644 --- a/guix/profiles.scm +++ b/guix/profiles.scm @@ -10,6 +10,7 @@ ;;; Copyright © 2017 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; Copyright © 2019 Kyle Meyer <kyle@kyleam.com> ;;; Copyright © 2019 Mathieu Othacehe <m.othacehe@gmail.com> +;;; Copyright © 2020 Danny Milosavljevic <dannym@scratchpost.org> ;;; ;;; This file is part of GNU Guix. ;;; @@ -139,7 +140,9 @@ %current-profile ensure-profile-directory canonicalize-profile - user-friendly-profile)) + user-friendly-profile + + linux-module-database)) ;;; Commentary: ;;; @@ -1137,6 +1140,49 @@ for both major versions of GTK+." (hook . gtk-im-modules))) (return #f))))) +(define (input-files inputs path) + "Given a list of directories INPUTS, return all entries with PATH in it." + ;; TODO: Use filter-map. + #~(begin + (use-modules (srfi srfi-1)) + (filter file-exists? + (map (lambda (x) + (string-append x #$path)) + '#$inputs)))) + +(define (linux-module-database manifest) + "Return a derivation that unions all the kernel modules in the manifest +and creates the dependency graph for all these kernel modules." + (mlet %store-monad ((kmod (manifest-lookup-package manifest "kmod"))) + (define build + (with-imported-modules (source-module-closure '((guix build utils) (gnu build linux-modules))) + #~(begin + (use-modules (ice-9 ftw)) + (use-modules (ice-9 match)) + (use-modules (srfi srfi-1)) ; append-map + (use-modules (guix build utils)) ; mkdir-p + (use-modules (gnu build linux-modules)) ; make-linux-module-directory + (let* ((inputs '#$(manifest-inputs manifest)) + (module-directories #$(input-files (manifest-inputs manifest) "/lib/modules")) + (directory-entries + (lambda (directory-name) + (scandir directory-name (lambda (basename) + (not (string-prefix? "." basename)))))) + ;; Note: Should usually result in one entry. + (versions (delete-duplicates + (append-map directory-entries + module-directories)))) + (match versions + ((version) + (make-linux-module-directory #$kmod inputs version #$output))) + (exit #t))))) + (gexp->derivation "linux-module-database" build + #:local-build? #t + #:substitutable? #f + #:properties + `((type . profile-hook) + (hook . linux-module-database))))) + (define (xdg-desktop-database manifest) "Return a derivation that builds the @file{mimeinfo.cache} database from desktop files. It's used to query what applications can handle a given