From: Mathieu Othacehe <othacehe@gnu.org>
To: "pelzflorian \(Florian Pelz\)" <pelzflorian@pelzflorian.de>
Cc: 41120@debbugs.gnu.org
Subject: bug#41120: uvesafb service is unsupported on aarch64
Date: Wed, 13 May 2020 14:50:58 +0200 [thread overview]
Message-ID: <87blms3snh.fsf@gnu.org> (raw)
In-Reply-To: <875zd6lro0.fsf@gmail.com> (Mathieu Othacehe's message of "Fri, 08 May 2020 11:09:03 +0200")
[-- Attachment #1: Type: text/plain, Size: 1141 bytes --]
Hello,
> We could maybe do something like that:
>
> (define (operating-system-hardware-specific-services)
> #~(let-system (system target)
> (cond
> ((target-arm? system target)
> '())
> ((target-intel? system target)
> (list uvesafb-shepherd-service)))))
>
> (define (operating-system-kernel-specific-services)
> #~(let-system (system target)
> (cond
> ((target-linux? system target)
> linux-specific-services)
> ((target-hurd? system target)
> hurd-specific-services))))
>
> This way, uvesafb-shepherd-service would be built and installed only
> when producing a system targeting an Intel CPU. We could also extend
> this mechanism to have kernel specific services.
>
> That would mean, we need to dig out Ludo patch introducing
> let-system[1], but I think it was almost ready.
Here's a rebased version of Ludo's patch. I'm not sure about the merge
resolution in "lower-object", but otherwise it works fine!
Ludo, would it be of to push it?
Thanks,
Mathieu
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-gexp-Compilers-can-now-return-lowerable-objects.patch --]
[-- Type: text/x-diff, Size: 5049 bytes --]
From dde0a1ca499a4ef0592d10158a00add16386bebb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= <ludo@gnu.org>
Date: Wed, 13 May 2020 14:34:17 +0200
Subject: [PATCH 1/2] gexp: Compilers can now return lowerable objects.
* guix/gexp.scm (lower-object): Iterate if LOWERED is a struct.
(lower+expand-object): New procedure.
(gexp->sexp): Use it.
(define-gexp-compiler): Adjust docstring.
---
guix/gexp.scm | 71 ++++++++++++++++++++++++++++++++++-----------------
1 file changed, 48 insertions(+), 23 deletions(-)
diff --git a/guix/gexp.scm b/guix/gexp.scm
index 2a4b36519c..a9a4b89ab4 100644
--- a/guix/gexp.scm
+++ b/guix/gexp.scm
@@ -226,32 +226,59 @@ procedure to expand it; otherwise return #f."
corresponding to OBJ for SYSTEM, cross-compiling for TARGET if TARGET is true.
OBJ must be an object that has an associated gexp compiler, such as a
<package>."
- (match (lookup-compiler obj)
- (#f
- (raise (condition (&gexp-input-error (input obj)))))
- (lower
- ;; Cache in STORE the result of lowering OBJ.
- (mlet %store-monad ((target (if (eq? target 'current)
- (current-target-system)
- (return target)))
- (graft? (grafting?)))
- (mcached (let ((lower (lookup-compiler obj)))
- (lower obj system target))
- obj
- system target graft?)))))
+ (let loop ((obj obj))
+ (match (lookup-compiler obj)
+ (#f
+ (raise (condition (&gexp-input-error (input obj)))))
+ (lower
+ ;; Cache in STORE the result of lowering OBJ.
+ (mlet* %store-monad
+ ((target (if (eq? target 'current)
+ (current-target-system)
+ (return target)))
+ (graft? (grafting?))
+ (lowered (mcached (let ((lower (lookup-compiler obj)))
+ (lower obj system target))
+ obj
+ system target graft?)))
+ (if (and (struct? lowered) (not (eq? lowered obj)))
+ (loop lowered)
+ (return lowered)))))))
+
+(define* (lower+expand-object obj
+ #:optional (system (%current-system))
+ #:key target (output "out"))
+ "Return as a value in %STORE-MONAD the output of object OBJ expands to for
+SYSTEM and TARGET. Object such as <package>, <file-append>, or <plain-file>
+expand to file names, but it's possible to expand to a plain data type."
+ (let loop ((obj obj)
+ (expand (and (struct? obj) (lookup-expander obj))))
+ (match (lookup-compiler obj)
+ (#f
+ (raise (condition (&gexp-input-error (input obj)))))
+ (lower
+ (mlet %store-monad ((lowered (lower obj system target)))
+ ;; LOWER might return something that needs to be further lowered.
+ (if (struct? lowered)
+ ;; If we lack an expander, delegate to that of LOWERED.
+ (if (not expand)
+ (loop lowered (lookup-expander lowered))
+ (return (expand obj lowered output)))
+ (return lowered))))))) ;lists, vectors, etc.
(define-syntax define-gexp-compiler
(syntax-rules (=> compiler expander)
"Define NAME as a compiler for objects matching PREDICATE encountered in
gexps.
-In the simplest form of the macro, BODY must return a derivation for PARAM, an
-object that matches PREDICATE, for SYSTEM and TARGET (the latter of which is
-#f except when cross-compiling.)
+In the simplest form of the macro, BODY must return (1) a derivation for
+a record of the specified type, for SYSTEM and TARGET (the latter of which is
+#f except when cross-compiling), (2) another record that can itself be
+compiled down to a derivation, or (3) an object of a primitive data type.
The more elaborate form allows you to specify an expander:
- (define-gexp-compiler something something?
+ (define-gexp-compiler something-compiler <something>
compiler => (lambda (param system target) ...)
expander => (lambda (param drv output) ...))
@@ -1148,12 +1175,10 @@ and in the current monad setting (system type, etc.)"
(or n? native?)))
refs))
(($ <gexp-input> (? struct? thing) output n?)
- (let ((target (if (or n? native?) #f target))
- (expand (lookup-expander thing)))
- (mlet %store-monad ((obj (lower-object thing system
- #:target target)))
- ;; OBJ must be either a derivation or a store file name.
- (return (expand thing obj output)))))
+ (let ((target (if (or n? native?) #f target)))
+ (lower+expand-object thing system
+ #:target target
+ #:output output)))
(($ <gexp-input> (? self-quoting? x))
(return x))
(($ <gexp-input> x)
--
2.26.2
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-gexp-Add-let-system.patch --]
[-- Type: text/x-diff, Size: 6932 bytes --]
From 8fe7504a0935de7f0c8cba1236f3114d4e368093 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= <ludo@gnu.org>
Date: Wed, 13 May 2020 14:35:20 +0200
Subject: [PATCH 2/2] gexp: Add 'let-system'.
* guix/gexp.scm (<system-binding>): New record type.
(let-system): New macro.
(system-binding-compiler): New procedure.
(default-expander): Add catch-all case.
* tests/gexp.scm ("let-system", "let-system, target")
("let-system, ungexp-native, target")
("let-system, nested"): New tests.
* doc/guix.texi (G-Expressions): Document it.
---
doc/guix.texi | 26 +++++++++++++++++++++++++
guix/gexp.scm | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-
tests/gexp.scm | 50 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 126 insertions(+), 1 deletion(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index d6fbd85fde..0281a4be45 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -7811,6 +7811,32 @@ are also added to the load path of the gexp returned by
Return @code{#t} if @var{obj} is a G-expression.
@end deffn
+@deffn {Scheme Syntax} let-system @var{system}
+@deffnx {Scheme Syntax} let-system (@var{system} @var{target})
+Bind @var{system} to the currently targeted system---e.g.,
+@code{"x86_64-linux"}---within @var{body}.
+
+In the second case, additionally bind @var{target} to the current
+cross-compilation target---a GNU triplet such as
+@code{"arm-linux-gnueabihf"}---or @code{#f} if we are not
+cross-compiling.
+
+@code{let-system} is useful in the occasional case where the object
+spliced into the gexp depends on the target system, as in this example:
+
+@example
+#~(system*
+ #+(let-system system
+ (cond ((string-prefix? "armhf-" system)
+ (file-append qemu "/bin/qemu-system-arm"))
+ ((string-prefix? "x86_64-" system)
+ (file-append qemu "/bin/qemu-system-x86_64"))
+ (else
+ (error "dunno!"))))
+ "-net" "user" #$image)
+@end example
+@end deffn
+
G-expressions are meant to be written to disk, either as code building
some derivation, or as plain files in the store. The monadic procedures
below allow you to do that (@pxref{The Store Monad}, for more
diff --git a/guix/gexp.scm b/guix/gexp.scm
index a9a4b89ab4..a70b723e57 100644
--- a/guix/gexp.scm
+++ b/guix/gexp.scm
@@ -112,6 +112,7 @@
gexp-compiler?
file-like?
lower-object
+ let-system
lower-inputs
@@ -195,7 +196,9 @@ returns its output file name of OBJ's OUTPUT."
((? derivation? drv)
(derivation->output-path drv output))
((? string? file)
- file)))
+ file)
+ (obj ;lists, vectors, etc.
+ obj)))
(define (register-compiler! compiler)
"Register COMPILER as a gexp compiler."
@@ -324,6 +327,52 @@ The expander specifies how an object is converted to its sexp representation."
(derivation-file-name lowered)
lowered)))
+\f
+;;;
+;;; System dependencies.
+;;;
+
+;; Binding form for the current system and cross-compilation target.
+(define-record-type <system-binding>
+ (system-binding proc)
+ system-binding?
+ (proc system-binding-proc))
+
+(define-syntax let-system
+ (syntax-rules ()
+ "Introduce a system binding in a gexp. The simplest form is:
+
+ (let-system system
+ (cond ((string=? system \"x86_64-linux\") ...)
+ (else ...)))
+
+which binds SYSTEM to the currently targeted system. The second form is
+similar, but it also shows the cross-compilation target:
+
+ (let-system (system target)
+ ...)
+
+Here TARGET is bound to the cross-compilation triplet or #f."
+ ((_ (system target) exp0 exp ...)
+ (system-binding (lambda (system target)
+ exp0 exp ...)))
+ ((_ system exp0 exp ...)
+ (system-binding (lambda (system target)
+ exp0 exp ...)))))
+
+(define-gexp-compiler system-binding-compiler <system-binding>
+ compiler => (lambda (binding system target)
+ (match binding
+ (($ <system-binding> proc)
+ (with-monad %store-monad
+ ;; PROC is expected to return a lowerable object.
+ ;; 'lower-object' takes care of residualizing it to a
+ ;; derivation or similar.
+ (return (proc system target))))))
+
+ ;; Delegate to the expander of the object returned by PROC.
+ expander => #f)
+
\f
;;;
;;; File declarations.
diff --git a/tests/gexp.scm b/tests/gexp.scm
index 6a42d3eb57..c1d65b2c4e 100644
--- a/tests/gexp.scm
+++ b/tests/gexp.scm
@@ -322,6 +322,56 @@
(string-append (derivation->output-path drv)
"/bin/touch"))))))
+(test-equal "let-system"
+ (list `(begin ,(%current-system) #t) '(system-binding) '())
+ (let ((exp #~(begin
+ #$(let-system system system)
+ #t)))
+ (list (gexp->sexp* exp)
+ (match (gexp-inputs exp)
+ (((($ (@@ (guix gexp) <system-binding>)) "out"))
+ '(system-binding))
+ (x x))
+ (gexp-native-inputs exp))))
+
+(test-equal "let-system, target"
+ (list `(list ,(%current-system) #f)
+ `(list ,(%current-system) "aarch64-linux-gnu"))
+ (let ((exp #~(list #$@(let-system (system target)
+ (list system target)))))
+ (list (gexp->sexp* exp)
+ (gexp->sexp* exp "aarch64-linux-gnu"))))
+
+(test-equal "let-system, ungexp-native, target"
+ `(here it is: ,(%current-system) #f)
+ (let ((exp #~(here it is: #+@(let-system (system target)
+ (list system target)))))
+ (gexp->sexp* exp "aarch64-linux-gnu")))
+
+(test-equal "let-system, nested"
+ (list `(system* ,(string-append "qemu-system-" (%current-system))
+ "-m" "256")
+ '()
+ '(system-binding))
+ (let ((exp #~(system*
+ #+(let-system (system target)
+ (file-append (@@ (gnu packages virtualization)
+ qemu)
+ "/bin/qemu-system-"
+ system))
+ "-m" "256")))
+ (list (match (gexp->sexp* exp)
+ (('system* command rest ...)
+ `(system* ,(and (string-prefix? (%store-prefix) command)
+ (basename command))
+ ,@rest))
+ (x x))
+ (gexp-inputs exp)
+ (match (gexp-native-inputs exp)
+ (((($ (@@ (guix gexp) <system-binding>)) "out"))
+ '(system-binding))
+ (x x)))))
+
(test-assert "ungexp + ungexp-native"
(let* ((exp (gexp (list (ungexp-native %bootstrap-guile)
(ungexp coreutils)
--
2.26.2
next prev parent reply other threads:[~2020-05-13 12:51 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-07 5:40 bug#41120: uvesafb service is unsupported on aarch64 Efraim Flashner
2020-05-07 7:06 ` Mathieu Othacehe
2020-05-07 8:05 ` Efraim Flashner
2020-05-07 8:12 ` Efraim Flashner
2020-05-07 14:55 ` pelzflorian (Florian Pelz)
2020-05-07 14:58 ` pelzflorian (Florian Pelz)
2020-05-08 9:09 ` Mathieu Othacehe
2020-05-13 12:50 ` Mathieu Othacehe [this message]
2020-05-14 8:16 ` Ludovic Courtès
2020-05-15 22:43 ` Ludovic Courtès
2021-12-29 2:30 ` Leo Famulari
2021-12-29 8:20 ` Efraim Flashner
2021-12-29 22:03 ` Tobias Geerinckx-Rice via Bug reports for GNU Guix
2022-08-04 23:03 ` Pavel Shlyak
2022-08-05 12:59 ` pelzflorian (Florian Pelz)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://guix.gnu.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87blms3snh.fsf@gnu.org \
--to=othacehe@gnu.org \
--cc=41120@debbugs.gnu.org \
--cc=pelzflorian@pelzflorian.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/guix.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).