2014-04-28 23:00:57 +02:00
|
|
|
|
;;; GNU Guix --- Functional package management for GNU
|
2015-01-12 23:26:52 +01:00
|
|
|
|
;;; Copyright © 2014, 2015 Ludovic Courtès <ludo@gnu.org>
|
2014-04-28 23:00:57 +02:00
|
|
|
|
;;;
|
|
|
|
|
;;; 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 (guix gexp)
|
monads: Move '%store-monad' and related procedures where they belong.
This turns (guix monads) into a generic module for monads, and moves the
store monad and related monadic procedures in their corresponding
module.
* guix/monads.scm (store-return, store-bind, %store-monad, store-lift,
text-file, interned-file, package-file, package->derivation,
package->cross-derivation, origin->derivation, imported-modules,
compiled, modules, built-derivations, run-with-store): Move to...
* guix/store.scm (store-return, store-bind, %store-monad, store-lift,
text-file, interned-file): ... here.
(%guile-for-build): New variable.
(run-with-store): Moved from monads.scm. Remove default value for
#:guile-for-build.
* guix/packages.scm (default-guile): Export.
(set-guile-for-build): New procedure.
(package-file, package->derivation, package->cross-derivation,
origin->derivation): Moved from monads.scm.
* guix/derivations.scm (%guile-for-build): Remove.
(imported-modules): Rename to...
(%imported-modules): ... this.
(compiled-modules): Rename to...
(%compiled-modules): ... this.
(built-derivations, imported-modules, compiled-modules): New
procedures.
* gnu/services/avahi.scm, gnu/services/base.scm, gnu/services/dbus.scm,
gnu/services/dmd.scm, gnu/services/networking.scm,
gnu/services/ssh.scm, gnu/services/xorg.scm, gnu/system/install.scm,
gnu/system/linux-initrd.scm, gnu/system/shadow.scm, guix/download.scm,
guix/gexp.scm, guix/git-download.scm, guix/profiles.scm,
guix/svn-download.scm, tests/monads.scm: Adjust imports accordingly.
* guix/monad-repl.scm (default-guile-derivation): New procedure.
(store-monad-language, run-in-store): Use it.
* build-aux/hydra/gnu-system.scm (qemu-jobs): Add explicit
'set-guile-for-build' call.
* guix/scripts/archive.scm (derivation-from-expression): Likewise.
* guix/scripts/build.scm (options/resolve-packages): Likewise.
* guix/scripts/environment.scm (guix-environment): Likewise.
* guix/scripts/system.scm (guix-system): Likewise.
* doc/guix.texi (The Store Monad): Adjust module names accordingly.
2015-01-14 13:34:52 +01:00
|
|
|
|
#:use-module (guix store)
|
2014-04-28 23:00:57 +02:00
|
|
|
|
#:use-module (guix monads)
|
monads: Move '%store-monad' and related procedures where they belong.
This turns (guix monads) into a generic module for monads, and moves the
store monad and related monadic procedures in their corresponding
module.
* guix/monads.scm (store-return, store-bind, %store-monad, store-lift,
text-file, interned-file, package-file, package->derivation,
package->cross-derivation, origin->derivation, imported-modules,
compiled, modules, built-derivations, run-with-store): Move to...
* guix/store.scm (store-return, store-bind, %store-monad, store-lift,
text-file, interned-file): ... here.
(%guile-for-build): New variable.
(run-with-store): Moved from monads.scm. Remove default value for
#:guile-for-build.
* guix/packages.scm (default-guile): Export.
(set-guile-for-build): New procedure.
(package-file, package->derivation, package->cross-derivation,
origin->derivation): Moved from monads.scm.
* guix/derivations.scm (%guile-for-build): Remove.
(imported-modules): Rename to...
(%imported-modules): ... this.
(compiled-modules): Rename to...
(%compiled-modules): ... this.
(built-derivations, imported-modules, compiled-modules): New
procedures.
* gnu/services/avahi.scm, gnu/services/base.scm, gnu/services/dbus.scm,
gnu/services/dmd.scm, gnu/services/networking.scm,
gnu/services/ssh.scm, gnu/services/xorg.scm, gnu/system/install.scm,
gnu/system/linux-initrd.scm, gnu/system/shadow.scm, guix/download.scm,
guix/gexp.scm, guix/git-download.scm, guix/profiles.scm,
guix/svn-download.scm, tests/monads.scm: Adjust imports accordingly.
* guix/monad-repl.scm (default-guile-derivation): New procedure.
(store-monad-language, run-in-store): Use it.
* build-aux/hydra/gnu-system.scm (qemu-jobs): Add explicit
'set-guile-for-build' call.
* guix/scripts/archive.scm (derivation-from-expression): Likewise.
* guix/scripts/build.scm (options/resolve-packages): Likewise.
* guix/scripts/environment.scm (guix-environment): Likewise.
* guix/scripts/system.scm (guix-system): Likewise.
* doc/guix.texi (The Store Monad): Adjust module names accordingly.
2015-01-14 13:34:52 +01:00
|
|
|
|
#:use-module (guix derivations)
|
2015-02-13 17:23:17 +01:00
|
|
|
|
#:use-module (guix utils)
|
2014-04-28 23:00:57 +02:00
|
|
|
|
#:use-module (srfi srfi-1)
|
|
|
|
|
#:use-module (srfi srfi-9)
|
2014-04-30 23:16:03 +02:00
|
|
|
|
#:use-module (srfi srfi-9 gnu)
|
2014-04-28 23:00:57 +02:00
|
|
|
|
#:use-module (srfi srfi-26)
|
|
|
|
|
#:use-module (ice-9 match)
|
|
|
|
|
#:export (gexp
|
|
|
|
|
gexp?
|
2015-03-15 21:45:37 +01:00
|
|
|
|
|
|
|
|
|
gexp-input
|
|
|
|
|
gexp-input?
|
2015-06-03 11:45:27 +02:00
|
|
|
|
|
2015-03-28 21:26:33 +01:00
|
|
|
|
local-file
|
|
|
|
|
local-file?
|
2015-06-03 11:21:15 +02:00
|
|
|
|
local-file-file
|
|
|
|
|
local-file-name
|
|
|
|
|
local-file-recursive?
|
2015-03-15 21:45:37 +01:00
|
|
|
|
|
2015-06-03 11:45:27 +02:00
|
|
|
|
plain-file
|
|
|
|
|
plain-file?
|
|
|
|
|
plain-file-name
|
|
|
|
|
plain-file-content
|
|
|
|
|
|
2014-04-28 23:00:57 +02:00
|
|
|
|
gexp->derivation
|
|
|
|
|
gexp->file
|
2015-01-12 23:26:52 +01:00
|
|
|
|
gexp->script
|
2015-02-13 17:23:17 +01:00
|
|
|
|
text-file*
|
|
|
|
|
imported-files
|
|
|
|
|
imported-modules
|
2015-03-17 22:09:32 +01:00
|
|
|
|
compiled-modules
|
|
|
|
|
|
|
|
|
|
define-gexp-compiler
|
|
|
|
|
gexp-compiler?))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
;;;
|
|
|
|
|
;;; This module implements "G-expressions", or "gexps". Gexps are like
|
|
|
|
|
;;; S-expressions (sexps), with two differences:
|
|
|
|
|
;;;
|
|
|
|
|
;;; 1. References (un-quotations) to derivations or packages in a gexp are
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
;;; replaced by the corresponding output file name; in addition, the
|
|
|
|
|
;;; 'ungexp-native' unquote-like form allows code to explicitly refer to
|
|
|
|
|
;;; the native code of a given package, in case of cross-compilation;
|
2014-04-28 23:00:57 +02:00
|
|
|
|
;;;
|
|
|
|
|
;;; 2. Gexps embed information about the derivations they refer to.
|
|
|
|
|
;;;
|
|
|
|
|
;;; Gexps make it easy to write to files Scheme code that refers to store
|
|
|
|
|
;;; items, or to write Scheme code to build derivations.
|
|
|
|
|
;;;
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
|
|
|
|
;; "G expressions".
|
|
|
|
|
(define-record-type <gexp>
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(make-gexp references natives proc)
|
2014-04-28 23:00:57 +02:00
|
|
|
|
gexp?
|
|
|
|
|
(references gexp-references) ; ((DRV-OR-PKG OUTPUT) ...)
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(natives gexp-native-references) ; ((DRV-OR-PKG OUTPUT) ...)
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(proc gexp-proc)) ; procedure
|
|
|
|
|
|
2014-04-30 23:16:03 +02:00
|
|
|
|
(define (write-gexp gexp port)
|
|
|
|
|
"Write GEXP on PORT."
|
|
|
|
|
(display "#<gexp " port)
|
2014-07-17 15:40:06 +02:00
|
|
|
|
|
|
|
|
|
;; Try to write the underlying sexp. Now, this trick doesn't work when
|
|
|
|
|
;; doing things like (ungexp-splicing (gexp ())) because GEXP's procedure
|
|
|
|
|
;; tries to use 'append' on that, which fails with wrong-type-arg.
|
|
|
|
|
(false-if-exception
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(write (apply (gexp-proc gexp)
|
|
|
|
|
(append (gexp-references gexp)
|
|
|
|
|
(gexp-native-references gexp)))
|
|
|
|
|
port))
|
2014-04-30 23:16:03 +02:00
|
|
|
|
(format port " ~a>"
|
|
|
|
|
(number->string (object-address gexp) 16)))
|
|
|
|
|
|
|
|
|
|
(set-record-type-printer! <gexp> write-gexp)
|
|
|
|
|
|
2015-03-15 23:27:34 +01:00
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
;;; Methods.
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
;; Compiler for a type of objects that may be introduced in a gexp.
|
|
|
|
|
(define-record-type <gexp-compiler>
|
|
|
|
|
(gexp-compiler predicate lower)
|
|
|
|
|
gexp-compiler?
|
|
|
|
|
(predicate gexp-compiler-predicate)
|
|
|
|
|
(lower gexp-compiler-lower))
|
|
|
|
|
|
|
|
|
|
(define %gexp-compilers
|
|
|
|
|
;; List of <gexp-compiler>.
|
|
|
|
|
'())
|
|
|
|
|
|
|
|
|
|
(define (register-compiler! compiler)
|
|
|
|
|
"Register COMPILER as a gexp compiler."
|
|
|
|
|
(set! %gexp-compilers (cons compiler %gexp-compilers)))
|
|
|
|
|
|
|
|
|
|
(define (lookup-compiler object)
|
|
|
|
|
"Search a compiler for OBJECT. Upon success, return the three argument
|
|
|
|
|
procedure to lower it; otherwise return #f."
|
|
|
|
|
(any (match-lambda
|
|
|
|
|
(($ <gexp-compiler> predicate lower)
|
|
|
|
|
(and (predicate object) lower)))
|
|
|
|
|
%gexp-compilers))
|
|
|
|
|
|
|
|
|
|
(define-syntax-rule (define-gexp-compiler (name (param predicate)
|
|
|
|
|
system target)
|
|
|
|
|
body ...)
|
|
|
|
|
"Define NAME as a compiler for objects matching PREDICATE encountered in
|
|
|
|
|
gexps. 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.)"
|
|
|
|
|
(begin
|
|
|
|
|
(define name
|
|
|
|
|
(gexp-compiler predicate
|
|
|
|
|
(lambda (param system target)
|
|
|
|
|
body ...)))
|
|
|
|
|
(register-compiler! name)))
|
|
|
|
|
|
2015-03-21 23:13:02 +01:00
|
|
|
|
(define-gexp-compiler (derivation-compiler (drv derivation?) system target)
|
|
|
|
|
;; Derivations are the lowest-level representation, so this is the identity
|
|
|
|
|
;; compiler.
|
|
|
|
|
(with-monad %store-monad
|
|
|
|
|
(return drv)))
|
|
|
|
|
|
2015-03-28 21:26:33 +01:00
|
|
|
|
|
|
|
|
|
;;;
|
2015-06-03 11:45:27 +02:00
|
|
|
|
;;; File declarations.
|
2015-03-28 21:26:33 +01:00
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
(define-record-type <local-file>
|
|
|
|
|
(%local-file file name recursive?)
|
|
|
|
|
local-file?
|
|
|
|
|
(file local-file-file) ;string
|
|
|
|
|
(name local-file-name) ;string
|
|
|
|
|
(recursive? local-file-recursive?)) ;Boolean
|
|
|
|
|
|
|
|
|
|
(define* (local-file file #:optional (name (basename file))
|
2015-06-18 23:25:49 +02:00
|
|
|
|
#:key recursive?)
|
2015-03-28 21:26:33 +01:00
|
|
|
|
"Return an object representing local file FILE to add to the store; this
|
|
|
|
|
object can be used in a gexp. FILE will be added to the store under NAME--by
|
|
|
|
|
default the base name of FILE.
|
|
|
|
|
|
|
|
|
|
When RECURSIVE? is true, the contents of FILE are added recursively; if FILE
|
|
|
|
|
designates a flat file and RECURSIVE? is true, its contents are added, and its
|
|
|
|
|
permission bits are kept.
|
|
|
|
|
|
|
|
|
|
This is the declarative counterpart of the 'interned-file' monadic procedure."
|
2015-06-19 10:18:44 +02:00
|
|
|
|
;; Canonicalize FILE so that if it's a symlink, it is resolved. Failing to
|
|
|
|
|
;; do that, when RECURSIVE? is #t, we could end up creating a dangling
|
|
|
|
|
;; symlink in the store, and when RECURSIVE? is #f 'add-to-store' would just
|
|
|
|
|
;; throw an error, both of which are inconvenient.
|
|
|
|
|
(%local-file (canonicalize-path file) name recursive?))
|
2015-03-28 21:26:33 +01:00
|
|
|
|
|
|
|
|
|
(define-gexp-compiler (local-file-compiler (file local-file?) system target)
|
|
|
|
|
;; "Compile" FILE by adding it to the store.
|
|
|
|
|
(match file
|
|
|
|
|
(($ <local-file> file name recursive?)
|
|
|
|
|
(interned-file file name #:recursive? recursive?))))
|
|
|
|
|
|
2015-06-03 11:45:27 +02:00
|
|
|
|
(define-record-type <plain-file>
|
|
|
|
|
(%plain-file name content references)
|
|
|
|
|
plain-file?
|
|
|
|
|
(name plain-file-name) ;string
|
|
|
|
|
(content plain-file-content) ;string
|
|
|
|
|
(references plain-file-references)) ;list (currently unused)
|
|
|
|
|
|
|
|
|
|
(define (plain-file name content)
|
|
|
|
|
"Return an object representing a text file called NAME with the given
|
|
|
|
|
CONTENT (a string) to be added to the store.
|
|
|
|
|
|
|
|
|
|
This is the declarative counterpart of 'text-file'."
|
|
|
|
|
;; XXX: For now just ignore 'references' because it's not clear how to use
|
|
|
|
|
;; them in a declarative context.
|
|
|
|
|
(%plain-file name content '()))
|
|
|
|
|
|
|
|
|
|
(define-gexp-compiler (plain-file-compiler (file plain-file?) system target)
|
|
|
|
|
;; "Compile" FILE by adding it to the store.
|
|
|
|
|
(match file
|
|
|
|
|
(($ <plain-file> name content references)
|
|
|
|
|
(text-file name content references))))
|
|
|
|
|
|
2015-03-15 23:27:34 +01:00
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
;;; Inputs & outputs.
|
|
|
|
|
;;;
|
|
|
|
|
|
2015-03-11 23:20:50 +01:00
|
|
|
|
;; The input of a gexp.
|
|
|
|
|
(define-record-type <gexp-input>
|
2015-03-15 21:45:37 +01:00
|
|
|
|
(%gexp-input thing output native?)
|
2015-03-11 23:20:50 +01:00
|
|
|
|
gexp-input?
|
|
|
|
|
(thing gexp-input-thing) ;<package> | <origin> | <derivation> | ...
|
|
|
|
|
(output gexp-input-output) ;string
|
|
|
|
|
(native? gexp-input-native?)) ;Boolean
|
|
|
|
|
|
2015-03-30 22:59:24 +02:00
|
|
|
|
(define (write-gexp-input input port)
|
|
|
|
|
(match input
|
|
|
|
|
(($ <gexp-input> thing output #f)
|
|
|
|
|
(format port "#<gexp-input ~s:~a>" thing output))
|
|
|
|
|
(($ <gexp-input> thing output #t)
|
|
|
|
|
(format port "#<gexp-input native ~s:~a>" thing output))))
|
|
|
|
|
|
|
|
|
|
(set-record-type-printer! <gexp-input> write-gexp-input)
|
|
|
|
|
|
2015-03-15 21:45:37 +01:00
|
|
|
|
(define* (gexp-input thing ;convenience procedure
|
|
|
|
|
#:optional (output "out")
|
|
|
|
|
#:key native?)
|
|
|
|
|
"Return a new <gexp-input> for the OUTPUT of THING; NATIVE? determines
|
|
|
|
|
whether this should be considered a \"native\" input or not."
|
|
|
|
|
(%gexp-input thing output native?))
|
|
|
|
|
|
2014-04-28 23:00:57 +02:00
|
|
|
|
;; Reference to one of the derivation's outputs, for gexps used in
|
|
|
|
|
;; derivations.
|
2015-03-16 22:31:14 +01:00
|
|
|
|
(define-record-type <gexp-output>
|
|
|
|
|
(gexp-output name)
|
|
|
|
|
gexp-output?
|
|
|
|
|
(name gexp-output-name))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
|
2015-03-30 22:59:24 +02:00
|
|
|
|
(define (write-gexp-output output port)
|
|
|
|
|
(match output
|
|
|
|
|
(($ <gexp-output> name)
|
|
|
|
|
(format port "#<gexp-output ~a>" name))))
|
|
|
|
|
|
|
|
|
|
(set-record-type-printer! <gexp-output> write-gexp-output)
|
|
|
|
|
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(define raw-derivation
|
|
|
|
|
(store-lift derivation))
|
|
|
|
|
|
2014-08-17 21:20:11 +02:00
|
|
|
|
(define* (lower-inputs inputs
|
|
|
|
|
#:key system target)
|
|
|
|
|
"Turn any package from INPUTS into a derivation for SYSTEM; return the
|
|
|
|
|
corresponding input list as a monadic value. When TARGET is true, use it as
|
|
|
|
|
the cross-compilation target triplet."
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(with-monad %store-monad
|
|
|
|
|
(sequence %store-monad
|
|
|
|
|
(map (match-lambda
|
2015-03-28 18:24:03 +01:00
|
|
|
|
(((? struct? thing) sub-drv ...)
|
|
|
|
|
(mlet* %store-monad ((lower -> (lookup-compiler thing))
|
|
|
|
|
(drv (lower thing system target)))
|
|
|
|
|
(return `(,drv ,@sub-drv))))
|
|
|
|
|
(input
|
|
|
|
|
(return input)))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
inputs))))
|
|
|
|
|
|
2014-09-06 15:45:32 +02:00
|
|
|
|
(define* (lower-reference-graphs graphs #:key system target)
|
|
|
|
|
"Given GRAPHS, a list of (FILE-NAME INPUT ...) lists for use as a
|
|
|
|
|
#:reference-graphs argument, lower it such that each INPUT is replaced by the
|
|
|
|
|
corresponding derivation."
|
|
|
|
|
(match graphs
|
|
|
|
|
(((file-names . inputs) ...)
|
|
|
|
|
(mlet %store-monad ((inputs (lower-inputs inputs
|
|
|
|
|
#:system system
|
|
|
|
|
#:target target)))
|
|
|
|
|
(return (map cons file-names inputs))))))
|
|
|
|
|
|
2015-02-11 22:10:14 +01:00
|
|
|
|
(define* (lower-references lst #:key system target)
|
|
|
|
|
"Based on LST, a list of output names and packages, return a list of output
|
|
|
|
|
names and file names suitable for the #:allowed-references argument to
|
|
|
|
|
'derivation'."
|
|
|
|
|
;; XXX: Currently outputs other than "out" are not supported, and things
|
|
|
|
|
;; other than packages aren't either.
|
|
|
|
|
(with-monad %store-monad
|
|
|
|
|
(define lower
|
|
|
|
|
(match-lambda
|
|
|
|
|
((? string? output)
|
|
|
|
|
(return output))
|
2015-03-21 23:21:53 +01:00
|
|
|
|
(($ <gexp-input> thing output native?)
|
|
|
|
|
(mlet* %store-monad ((lower -> (lookup-compiler thing))
|
|
|
|
|
(drv (lower thing system
|
|
|
|
|
(if native? #f target))))
|
|
|
|
|
(return (derivation->output-path drv output))))
|
2015-03-15 23:27:34 +01:00
|
|
|
|
(thing
|
|
|
|
|
(mlet* %store-monad ((lower -> (lookup-compiler thing))
|
|
|
|
|
(drv (lower thing system target)))
|
2015-02-11 22:10:14 +01:00
|
|
|
|
(return (derivation->output-path drv))))))
|
|
|
|
|
|
|
|
|
|
(sequence %store-monad (map lower lst))))
|
|
|
|
|
|
2015-03-17 22:09:32 +01:00
|
|
|
|
(define default-guile-derivation
|
|
|
|
|
;; Here we break the abstraction by talking to the higher-level layer.
|
|
|
|
|
;; Thus, do the resolution lazily to hide the circular dependency.
|
|
|
|
|
(let ((proc (delay
|
|
|
|
|
(let ((iface (resolve-interface '(guix packages))))
|
|
|
|
|
(module-ref iface 'default-guile-derivation)))))
|
|
|
|
|
(lambda (system)
|
|
|
|
|
((force proc) system))))
|
|
|
|
|
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(define* (gexp->derivation name exp
|
|
|
|
|
#:key
|
2014-08-17 21:20:11 +02:00
|
|
|
|
system (target 'current)
|
2014-04-28 23:00:57 +02:00
|
|
|
|
hash hash-algo recursive?
|
|
|
|
|
(env-vars '())
|
|
|
|
|
(modules '())
|
2014-11-09 22:19:17 +01:00
|
|
|
|
(module-path %load-path)
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(guile-for-build (%guile-for-build))
|
2015-02-13 23:14:05 +01:00
|
|
|
|
(graft? (%graft?))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
references-graphs
|
2015-02-11 22:10:14 +01:00
|
|
|
|
allowed-references
|
2015-04-30 23:51:44 +02:00
|
|
|
|
leaked-env-vars
|
2014-04-28 23:00:57 +02:00
|
|
|
|
local-build?)
|
|
|
|
|
"Return a derivation NAME that runs EXP (a gexp) with GUILE-FOR-BUILD (a
|
2014-08-17 21:20:11 +02:00
|
|
|
|
derivation) on SYSTEM. When TARGET is true, it is used as the
|
|
|
|
|
cross-compilation target triplet for packages referred to by EXP.
|
2014-04-28 23:00:57 +02:00
|
|
|
|
|
|
|
|
|
Make MODULES available in the evaluation context of EXP; MODULES is a list of
|
2014-11-09 22:19:17 +01:00
|
|
|
|
names of Guile modules searched in MODULE-PATH to be copied in the store,
|
2014-04-28 23:00:57 +02:00
|
|
|
|
compiled, and made available in the load path during the execution of
|
|
|
|
|
EXP---e.g., '((guix build utils) (guix build gnu-build-system)).
|
|
|
|
|
|
2015-02-13 23:14:05 +01:00
|
|
|
|
GRAFT? determines whether packages referred to by EXP should be grafted when
|
|
|
|
|
applicable.
|
|
|
|
|
|
2014-09-06 15:45:32 +02:00
|
|
|
|
When REFERENCES-GRAPHS is true, it must be a list of tuples of one of the
|
|
|
|
|
following forms:
|
|
|
|
|
|
|
|
|
|
(FILE-NAME PACKAGE)
|
|
|
|
|
(FILE-NAME PACKAGE OUTPUT)
|
|
|
|
|
(FILE-NAME DERIVATION)
|
|
|
|
|
(FILE-NAME DERIVATION OUTPUT)
|
|
|
|
|
(FILE-NAME STORE-ITEM)
|
|
|
|
|
|
|
|
|
|
The right-hand-side of each element of REFERENCES-GRAPHS is automatically made
|
|
|
|
|
an input of the build process of EXP. In the build environment, each
|
|
|
|
|
FILE-NAME contains the reference graph of the corresponding item, in a simple
|
|
|
|
|
text format.
|
|
|
|
|
|
2015-02-11 22:10:14 +01:00
|
|
|
|
ALLOWED-REFERENCES must be either #f or a list of output names and packages.
|
|
|
|
|
In the latter case, the list denotes store items that the result is allowed to
|
|
|
|
|
refer to. Any reference to another store item will lead to a build error.
|
2014-09-06 15:45:32 +02:00
|
|
|
|
|
2014-04-28 23:00:57 +02:00
|
|
|
|
The other arguments are as for 'derivation'."
|
|
|
|
|
(define %modules modules)
|
|
|
|
|
(define outputs (gexp-outputs exp))
|
|
|
|
|
|
2014-09-06 15:45:32 +02:00
|
|
|
|
(define (graphs-file-names graphs)
|
|
|
|
|
;; Return a list of (FILE-NAME . STORE-PATH) pairs made from GRAPHS.
|
|
|
|
|
(map (match-lambda
|
2015-03-21 23:13:02 +01:00
|
|
|
|
;; TODO: Remove 'derivation?' special cases.
|
2014-09-06 15:45:32 +02:00
|
|
|
|
((file-name (? derivation? drv))
|
|
|
|
|
(cons file-name (derivation->output-path drv)))
|
|
|
|
|
((file-name (? derivation? drv) sub-drv)
|
|
|
|
|
(cons file-name (derivation->output-path drv sub-drv)))
|
|
|
|
|
((file-name thing)
|
|
|
|
|
(cons file-name thing)))
|
|
|
|
|
graphs))
|
|
|
|
|
|
2015-02-13 23:14:05 +01:00
|
|
|
|
(mlet* %store-monad (;; The following binding forces '%current-system' and
|
|
|
|
|
;; '%current-target-system' to be looked up at >>=
|
|
|
|
|
;; time.
|
|
|
|
|
(graft? (set-grafting graft?))
|
2014-08-17 21:20:11 +02:00
|
|
|
|
|
2014-07-12 22:11:12 +02:00
|
|
|
|
(system -> (or system (%current-system)))
|
2014-08-17 21:20:11 +02:00
|
|
|
|
(target -> (if (eq? target 'current)
|
|
|
|
|
(%current-target-system)
|
|
|
|
|
target))
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(normals (lower-inputs (gexp-inputs exp)
|
2014-08-17 21:20:11 +02:00
|
|
|
|
#:system system
|
|
|
|
|
#:target target))
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(natives (lower-inputs (gexp-native-inputs exp)
|
|
|
|
|
#:system system
|
|
|
|
|
#:target #f))
|
|
|
|
|
(inputs -> (append normals natives))
|
2014-08-17 21:20:11 +02:00
|
|
|
|
(sexp (gexp->sexp exp
|
|
|
|
|
#:system system
|
|
|
|
|
#:target target))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(builder (text-file (string-append name "-builder")
|
|
|
|
|
(object->string sexp)))
|
|
|
|
|
(modules (if (pair? %modules)
|
|
|
|
|
(imported-modules %modules
|
|
|
|
|
#:system system
|
2014-11-09 22:19:17 +01:00
|
|
|
|
#:module-path module-path
|
2014-04-28 23:00:57 +02:00
|
|
|
|
#:guile guile-for-build)
|
|
|
|
|
(return #f)))
|
|
|
|
|
(compiled (if (pair? %modules)
|
|
|
|
|
(compiled-modules %modules
|
|
|
|
|
#:system system
|
2014-11-09 22:19:17 +01:00
|
|
|
|
#:module-path module-path
|
2014-04-28 23:00:57 +02:00
|
|
|
|
#:guile guile-for-build)
|
|
|
|
|
(return #f)))
|
2014-09-06 15:45:32 +02:00
|
|
|
|
(graphs (if references-graphs
|
|
|
|
|
(lower-reference-graphs references-graphs
|
|
|
|
|
#:system system
|
|
|
|
|
#:target target)
|
|
|
|
|
(return #f)))
|
2015-02-11 22:10:14 +01:00
|
|
|
|
(allowed (if allowed-references
|
|
|
|
|
(lower-references allowed-references
|
|
|
|
|
#:system system
|
|
|
|
|
#:target target)
|
|
|
|
|
(return #f)))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(guile (if guile-for-build
|
|
|
|
|
(return guile-for-build)
|
2015-03-17 22:09:32 +01:00
|
|
|
|
(default-guile-derivation system))))
|
2015-02-13 23:14:05 +01:00
|
|
|
|
(mbegin %store-monad
|
|
|
|
|
(set-grafting graft?) ;restore the initial setting
|
|
|
|
|
(raw-derivation name
|
|
|
|
|
(string-append (derivation->output-path guile)
|
|
|
|
|
"/bin/guile")
|
|
|
|
|
`("--no-auto-compile"
|
|
|
|
|
,@(if (pair? %modules)
|
|
|
|
|
`("-L" ,(derivation->output-path modules)
|
|
|
|
|
"-C" ,(derivation->output-path compiled))
|
|
|
|
|
'())
|
|
|
|
|
,builder)
|
|
|
|
|
#:outputs outputs
|
|
|
|
|
#:env-vars env-vars
|
|
|
|
|
#:system system
|
|
|
|
|
#:inputs `((,guile)
|
|
|
|
|
(,builder)
|
|
|
|
|
,@(if modules
|
|
|
|
|
`((,modules) (,compiled) ,@inputs)
|
|
|
|
|
inputs)
|
|
|
|
|
,@(match graphs
|
|
|
|
|
(((_ . inputs) ...) inputs)
|
|
|
|
|
(_ '())))
|
|
|
|
|
#:hash hash #:hash-algo hash-algo #:recursive? recursive?
|
|
|
|
|
#:references-graphs (and=> graphs graphs-file-names)
|
|
|
|
|
#:allowed-references allowed
|
2015-04-30 23:51:44 +02:00
|
|
|
|
#:leaked-env-vars leaked-env-vars
|
2015-02-13 23:14:05 +01:00
|
|
|
|
#:local-build? local-build?))))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
|
2015-03-22 23:17:37 +01:00
|
|
|
|
(define* (gexp-inputs exp #:key native?)
|
|
|
|
|
"Return the input list for EXP. When NATIVE? is true, return only native
|
|
|
|
|
references; otherwise, return only non-native references."
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(define (add-reference-inputs ref result)
|
|
|
|
|
(match ref
|
2015-03-22 23:17:37 +01:00
|
|
|
|
(($ <gexp-input> (? gexp? exp) _ #t)
|
|
|
|
|
(if native?
|
|
|
|
|
(append (gexp-inputs exp)
|
|
|
|
|
(gexp-inputs exp #:native? #t)
|
|
|
|
|
result)
|
|
|
|
|
result))
|
|
|
|
|
(($ <gexp-input> (? gexp? exp) _ #f)
|
|
|
|
|
(if native?
|
|
|
|
|
(append (gexp-inputs exp #:native? #t)
|
|
|
|
|
result)
|
|
|
|
|
(append (gexp-inputs exp)
|
|
|
|
|
result)))
|
2015-03-11 23:20:50 +01:00
|
|
|
|
(($ <gexp-input> (? string? str))
|
|
|
|
|
(if (direct-store-path? str)
|
|
|
|
|
(cons `(,str) result)
|
2014-04-28 23:00:57 +02:00
|
|
|
|
result))
|
2015-03-15 23:27:34 +01:00
|
|
|
|
(($ <gexp-input> (? struct? thing) output)
|
|
|
|
|
(if (lookup-compiler thing)
|
|
|
|
|
;; THING is a derivation, or a package, or an origin, etc.
|
|
|
|
|
(cons `(,thing ,output) result)
|
|
|
|
|
result))
|
2015-03-22 23:17:37 +01:00
|
|
|
|
(($ <gexp-input> (lst ...) output n?)
|
2015-03-11 23:20:50 +01:00
|
|
|
|
(fold-right add-reference-inputs result
|
|
|
|
|
;; XXX: For now, automatically convert LST to a list of
|
|
|
|
|
;; gexp-inputs.
|
2015-03-15 21:45:37 +01:00
|
|
|
|
(map (match-lambda
|
|
|
|
|
((? gexp-input? x) x)
|
2015-03-22 23:17:37 +01:00
|
|
|
|
(x (%gexp-input x "out" (or n? native?))))
|
2015-03-15 21:45:37 +01:00
|
|
|
|
lst)))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(_
|
|
|
|
|
;; Ignore references to other kinds of objects.
|
|
|
|
|
result)))
|
|
|
|
|
|
|
|
|
|
(fold-right add-reference-inputs
|
|
|
|
|
'()
|
2015-03-22 23:17:37 +01:00
|
|
|
|
(if native?
|
|
|
|
|
(gexp-native-references exp)
|
|
|
|
|
(gexp-references exp))))
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
|
|
|
|
|
(define gexp-native-inputs
|
2015-03-22 23:17:37 +01:00
|
|
|
|
(cut gexp-inputs <> #:native? #t))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
|
|
|
|
|
(define (gexp-outputs exp)
|
|
|
|
|
"Return the outputs referred to by EXP as a list of strings."
|
|
|
|
|
(define (add-reference-output ref result)
|
|
|
|
|
(match ref
|
2015-03-16 22:31:14 +01:00
|
|
|
|
(($ <gexp-output> name)
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(cons name result))
|
2015-03-11 23:20:50 +01:00
|
|
|
|
(($ <gexp-input> (? gexp? exp))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(append (gexp-outputs exp) result))
|
2015-03-11 23:20:50 +01:00
|
|
|
|
(($ <gexp-input> (lst ...) output native?)
|
|
|
|
|
;; XXX: Automatically convert LST.
|
2015-03-15 21:45:37 +01:00
|
|
|
|
(add-reference-output (map (match-lambda
|
|
|
|
|
((? gexp-input? x) x)
|
|
|
|
|
(x (%gexp-input x "out" native?)))
|
|
|
|
|
lst)
|
2015-03-11 23:20:50 +01:00
|
|
|
|
result))
|
2015-02-27 22:05:40 +01:00
|
|
|
|
((lst ...)
|
|
|
|
|
(fold-right add-reference-output result lst))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(_
|
|
|
|
|
result)))
|
|
|
|
|
|
2015-03-02 16:26:13 +01:00
|
|
|
|
(delete-duplicates
|
|
|
|
|
(add-reference-output (gexp-references exp) '())))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
|
2014-08-17 21:20:11 +02:00
|
|
|
|
(define* (gexp->sexp exp #:key
|
|
|
|
|
(system (%current-system))
|
|
|
|
|
(target (%current-target-system)))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
"Return (monadically) the sexp corresponding to EXP for the given OUTPUT,
|
|
|
|
|
and in the current monad setting (system type, etc.)"
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(define* (reference->sexp ref #:optional native?)
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(with-monad %store-monad
|
|
|
|
|
(match ref
|
2015-03-16 22:31:14 +01:00
|
|
|
|
(($ <gexp-output> output)
|
2014-04-29 17:58:34 +02:00
|
|
|
|
;; Output file names are not known in advance but the daemon defines
|
|
|
|
|
;; an environment variable for each of them at build time, so use
|
|
|
|
|
;; that trick.
|
|
|
|
|
(return `((@ (guile) getenv) ,output)))
|
2015-03-11 23:20:50 +01:00
|
|
|
|
(($ <gexp-input> (? gexp? exp) output n?)
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(gexp->sexp exp
|
|
|
|
|
#:system system
|
2015-03-11 23:20:50 +01:00
|
|
|
|
#:target (if (or n? native?) #f target)))
|
|
|
|
|
(($ <gexp-input> (refs ...) output n?)
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(sequence %store-monad
|
2015-03-11 23:20:50 +01:00
|
|
|
|
(map (lambda (ref)
|
|
|
|
|
;; XXX: Automatically convert REF to an gexp-input.
|
2015-03-15 21:45:37 +01:00
|
|
|
|
(reference->sexp
|
|
|
|
|
(if (gexp-input? ref)
|
|
|
|
|
ref
|
|
|
|
|
(%gexp-input ref "out" n?))
|
|
|
|
|
native?))
|
2015-03-11 23:20:50 +01:00
|
|
|
|
refs)))
|
2015-03-15 23:27:34 +01:00
|
|
|
|
(($ <gexp-input> (? struct? thing) output n?)
|
|
|
|
|
(let ((lower (lookup-compiler thing))
|
|
|
|
|
(target (if (or n? native?) #f target)))
|
2015-03-28 21:26:33 +01:00
|
|
|
|
(mlet %store-monad ((obj (lower thing system target)))
|
|
|
|
|
;; OBJ must be either a derivation or a store file name.
|
|
|
|
|
(return (match obj
|
|
|
|
|
((? derivation? drv)
|
|
|
|
|
(derivation->output-path drv output))
|
|
|
|
|
((? string? file)
|
|
|
|
|
file))))))
|
2015-03-11 23:20:50 +01:00
|
|
|
|
(($ <gexp-input> x)
|
|
|
|
|
(return x))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(x
|
|
|
|
|
(return x)))))
|
|
|
|
|
|
|
|
|
|
(mlet %store-monad
|
|
|
|
|
((args (sequence %store-monad
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(append (map reference->sexp (gexp-references exp))
|
|
|
|
|
(map (cut reference->sexp <> #t)
|
|
|
|
|
(gexp-native-references exp))))))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(return (apply (gexp-proc exp) args))))
|
|
|
|
|
|
|
|
|
|
(define (syntax-location-string s)
|
|
|
|
|
"Return a string representing the source code location of S."
|
|
|
|
|
(let ((props (syntax-source s)))
|
|
|
|
|
(if props
|
|
|
|
|
(let ((file (assoc-ref props 'filename))
|
|
|
|
|
(line (and=> (assoc-ref props 'line) 1+))
|
|
|
|
|
(column (assoc-ref props 'column)))
|
|
|
|
|
(if file
|
|
|
|
|
(simple-format #f "~a:~a:~a"
|
|
|
|
|
file line column)
|
|
|
|
|
(simple-format #f "~a:~a" line column)))
|
|
|
|
|
"<unknown location>")))
|
|
|
|
|
|
|
|
|
|
(define-syntax gexp
|
|
|
|
|
(lambda (s)
|
|
|
|
|
(define (collect-escapes exp)
|
|
|
|
|
;; Return all the 'ungexp' present in EXP.
|
|
|
|
|
(let loop ((exp exp)
|
|
|
|
|
(result '()))
|
2015-03-22 23:09:43 +01:00
|
|
|
|
(syntax-case exp (ungexp
|
|
|
|
|
ungexp-splicing
|
|
|
|
|
ungexp-native
|
|
|
|
|
ungexp-native-splicing)
|
2014-04-28 23:00:57 +02:00
|
|
|
|
((ungexp _)
|
|
|
|
|
(cons exp result))
|
|
|
|
|
((ungexp _ _)
|
|
|
|
|
(cons exp result))
|
|
|
|
|
((ungexp-splicing _ ...)
|
|
|
|
|
(cons exp result))
|
2015-03-22 23:09:43 +01:00
|
|
|
|
((ungexp-native _ ...)
|
|
|
|
|
result)
|
|
|
|
|
((ungexp-native-splicing _ ...)
|
|
|
|
|
result)
|
2014-04-28 23:00:57 +02:00
|
|
|
|
((exp0 exp ...)
|
|
|
|
|
(let ((result (loop #'exp0 result)))
|
|
|
|
|
(fold loop result #'(exp ...))))
|
|
|
|
|
(_
|
|
|
|
|
result))))
|
|
|
|
|
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(define (collect-native-escapes exp)
|
|
|
|
|
;; Return all the 'ungexp-native' forms present in EXP.
|
|
|
|
|
(let loop ((exp exp)
|
|
|
|
|
(result '()))
|
2015-03-22 23:09:43 +01:00
|
|
|
|
(syntax-case exp (ungexp
|
|
|
|
|
ungexp-splicing
|
|
|
|
|
ungexp-native
|
|
|
|
|
ungexp-native-splicing)
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
((ungexp-native _)
|
|
|
|
|
(cons exp result))
|
|
|
|
|
((ungexp-native _ _)
|
|
|
|
|
(cons exp result))
|
|
|
|
|
((ungexp-native-splicing _ ...)
|
|
|
|
|
(cons exp result))
|
2015-03-22 23:09:43 +01:00
|
|
|
|
((ungexp _ ...)
|
|
|
|
|
result)
|
|
|
|
|
((ungexp-splicing _ ...)
|
|
|
|
|
result)
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
((exp0 exp ...)
|
|
|
|
|
(let ((result (loop #'exp0 result)))
|
|
|
|
|
(fold loop result #'(exp ...))))
|
|
|
|
|
(_
|
|
|
|
|
result))))
|
|
|
|
|
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(define (escape->ref exp)
|
|
|
|
|
;; Turn 'ungexp' form EXP into a "reference".
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(syntax-case exp (ungexp ungexp-splicing
|
|
|
|
|
ungexp-native ungexp-native-splicing
|
|
|
|
|
output)
|
2014-04-28 23:00:57 +02:00
|
|
|
|
((ungexp output)
|
2015-03-16 22:31:14 +01:00
|
|
|
|
#'(gexp-output "out"))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
((ungexp output name)
|
2015-03-16 22:31:14 +01:00
|
|
|
|
#'(gexp-output name))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
((ungexp thing)
|
2015-03-15 21:45:37 +01:00
|
|
|
|
#'(%gexp-input thing "out" #f))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
((ungexp drv-or-pkg out)
|
2015-03-15 21:45:37 +01:00
|
|
|
|
#'(%gexp-input drv-or-pkg out #f))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
((ungexp-splicing lst)
|
2015-03-15 21:45:37 +01:00
|
|
|
|
#'(%gexp-input lst "out" #f))
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
((ungexp-native thing)
|
2015-03-15 21:45:37 +01:00
|
|
|
|
#'(%gexp-input thing "out" #t))
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
((ungexp-native drv-or-pkg out)
|
2015-03-15 21:45:37 +01:00
|
|
|
|
#'(%gexp-input drv-or-pkg out #t))
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
((ungexp-native-splicing lst)
|
2015-03-15 21:45:37 +01:00
|
|
|
|
#'(%gexp-input lst "out" #t))))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(define (substitute-ungexp exp substs)
|
|
|
|
|
;; Given EXP, an 'ungexp' or 'ungexp-native' form, substitute it with
|
|
|
|
|
;; the corresponding form in SUBSTS.
|
|
|
|
|
(match (assoc exp substs)
|
|
|
|
|
((_ id)
|
|
|
|
|
id)
|
|
|
|
|
(_
|
|
|
|
|
#'(syntax-error "error: no 'ungexp' substitution"
|
|
|
|
|
#'ref))))
|
|
|
|
|
|
|
|
|
|
(define (substitute-ungexp-splicing exp substs)
|
|
|
|
|
(syntax-case exp ()
|
|
|
|
|
((exp rest ...)
|
|
|
|
|
(match (assoc #'exp substs)
|
|
|
|
|
((_ id)
|
|
|
|
|
(with-syntax ((id id))
|
|
|
|
|
#`(append id
|
|
|
|
|
#,(substitute-references #'(rest ...) substs))))
|
|
|
|
|
(_
|
|
|
|
|
#'(syntax-error "error: no 'ungexp-splicing' substitution"
|
|
|
|
|
#'ref))))))
|
|
|
|
|
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(define (substitute-references exp substs)
|
|
|
|
|
;; Return a variant of EXP where all the cars of SUBSTS have been
|
|
|
|
|
;; replaced by the corresponding cdr.
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(syntax-case exp (ungexp ungexp-native
|
|
|
|
|
ungexp-splicing ungexp-native-splicing)
|
2014-04-28 23:00:57 +02:00
|
|
|
|
((ungexp _ ...)
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(substitute-ungexp exp substs))
|
|
|
|
|
((ungexp-native _ ...)
|
|
|
|
|
(substitute-ungexp exp substs))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(((ungexp-splicing _ ...) rest ...)
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(substitute-ungexp-splicing exp substs))
|
|
|
|
|
(((ungexp-native-splicing _ ...) rest ...)
|
|
|
|
|
(substitute-ungexp-splicing exp substs))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
((exp0 exp ...)
|
|
|
|
|
#`(cons #,(substitute-references #'exp0 substs)
|
|
|
|
|
#,(substitute-references #'(exp ...) substs)))
|
|
|
|
|
(x #''x)))
|
|
|
|
|
|
|
|
|
|
(syntax-case s (ungexp output)
|
|
|
|
|
((_ exp)
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(let* ((normals (delete-duplicates (collect-escapes #'exp)))
|
|
|
|
|
(natives (delete-duplicates (collect-native-escapes #'exp)))
|
|
|
|
|
(escapes (append normals natives))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(formals (generate-temporaries escapes))
|
|
|
|
|
(sexp (substitute-references #'exp (zip escapes formals)))
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(refs (map escape->ref normals))
|
|
|
|
|
(nrefs (map escape->ref natives)))
|
2015-03-11 23:20:50 +01:00
|
|
|
|
#`(make-gexp (list #,@refs) (list #,@nrefs)
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(lambda #,formals
|
|
|
|
|
#,sexp)))))))
|
|
|
|
|
|
2015-02-13 17:23:17 +01:00
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
;;; Module handling.
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
(define %mkdir-p-definition
|
|
|
|
|
;; The code for 'mkdir-p' is copied from (guix build utils). We use it in
|
|
|
|
|
;; derivations that cannot use the #:modules argument of 'gexp->derivation'
|
|
|
|
|
;; precisely because they implement that functionality.
|
|
|
|
|
(gexp
|
|
|
|
|
(define (mkdir-p dir)
|
|
|
|
|
(define absolute?
|
|
|
|
|
(string-prefix? "/" dir))
|
|
|
|
|
|
|
|
|
|
(define not-slash
|
|
|
|
|
(char-set-complement (char-set #\/)))
|
|
|
|
|
|
|
|
|
|
(let loop ((components (string-tokenize dir not-slash))
|
|
|
|
|
(root (if absolute? "" ".")))
|
|
|
|
|
(match components
|
|
|
|
|
((head tail ...)
|
|
|
|
|
(let ((path (string-append root "/" head)))
|
|
|
|
|
(catch 'system-error
|
|
|
|
|
(lambda ()
|
|
|
|
|
(mkdir path)
|
|
|
|
|
(loop tail path))
|
|
|
|
|
(lambda args
|
|
|
|
|
(if (= EEXIST (system-error-errno args))
|
|
|
|
|
(loop tail path)
|
|
|
|
|
(apply throw args))))))
|
|
|
|
|
(() #t))))))
|
|
|
|
|
|
|
|
|
|
(define* (imported-files files
|
|
|
|
|
#:key (name "file-import")
|
|
|
|
|
(system (%current-system))
|
|
|
|
|
(guile (%guile-for-build)))
|
|
|
|
|
"Return a derivation that imports FILES into STORE. FILES must be a list
|
|
|
|
|
of (FINAL-PATH . FILE-NAME) pairs; each FILE-NAME is read from the file
|
|
|
|
|
system, imported, and appears under FINAL-PATH in the resulting store path."
|
|
|
|
|
(define file-pair
|
|
|
|
|
(match-lambda
|
|
|
|
|
((final-path . file-name)
|
|
|
|
|
(mlet %store-monad ((file (interned-file file-name
|
|
|
|
|
(basename final-path))))
|
|
|
|
|
(return (list final-path file))))))
|
|
|
|
|
|
|
|
|
|
(mlet %store-monad ((files (sequence %store-monad
|
|
|
|
|
(map file-pair files))))
|
|
|
|
|
(define build
|
|
|
|
|
(gexp
|
|
|
|
|
(begin
|
|
|
|
|
(use-modules (ice-9 match))
|
|
|
|
|
|
|
|
|
|
(ungexp %mkdir-p-definition)
|
|
|
|
|
|
|
|
|
|
(mkdir (ungexp output)) (chdir (ungexp output))
|
|
|
|
|
(for-each (match-lambda
|
|
|
|
|
((final-path store-path)
|
|
|
|
|
(mkdir-p (dirname final-path))
|
|
|
|
|
(symlink store-path final-path)))
|
|
|
|
|
'(ungexp files)))))
|
|
|
|
|
|
|
|
|
|
;; TODO: Pass FILES as an environment variable so that BUILD remains
|
|
|
|
|
;; exactly the same regardless of FILES: less disk space, and fewer
|
|
|
|
|
;; 'add-to-store' RPCs.
|
|
|
|
|
(gexp->derivation name build
|
|
|
|
|
#:system system
|
|
|
|
|
#:guile-for-build guile
|
|
|
|
|
#:local-build? #t)))
|
|
|
|
|
|
|
|
|
|
(define search-path*
|
|
|
|
|
;; A memoizing version of 'search-path' so 'imported-modules' does not end
|
|
|
|
|
;; up looking for the same files over and over again.
|
|
|
|
|
(memoize search-path))
|
|
|
|
|
|
|
|
|
|
(define* (imported-modules modules
|
|
|
|
|
#:key (name "module-import")
|
|
|
|
|
(system (%current-system))
|
|
|
|
|
(guile (%guile-for-build))
|
|
|
|
|
(module-path %load-path))
|
|
|
|
|
"Return a derivation that contains the source files of MODULES, a list of
|
|
|
|
|
module names such as `(ice-9 q)'. All of MODULES must be in the MODULE-PATH
|
|
|
|
|
search path."
|
|
|
|
|
;; TODO: Determine the closure of MODULES, build the `.go' files,
|
|
|
|
|
;; canonicalize the source files through read/write, etc.
|
|
|
|
|
(let ((files (map (lambda (m)
|
|
|
|
|
(let ((f (string-append
|
|
|
|
|
(string-join (map symbol->string m) "/")
|
|
|
|
|
".scm")))
|
|
|
|
|
(cons f (search-path* module-path f))))
|
|
|
|
|
modules)))
|
|
|
|
|
(imported-files files #:name name #:system system
|
|
|
|
|
#:guile guile)))
|
|
|
|
|
|
|
|
|
|
(define* (compiled-modules modules
|
|
|
|
|
#:key (name "module-import-compiled")
|
|
|
|
|
(system (%current-system))
|
|
|
|
|
(guile (%guile-for-build))
|
|
|
|
|
(module-path %load-path))
|
|
|
|
|
"Return a derivation that builds a tree containing the `.go' files
|
|
|
|
|
corresponding to MODULES. All the MODULES are built in a context where
|
|
|
|
|
they can refer to each other."
|
|
|
|
|
(mlet %store-monad ((modules (imported-modules modules
|
|
|
|
|
#:system system
|
|
|
|
|
#:guile guile
|
|
|
|
|
#:module-path
|
|
|
|
|
module-path)))
|
|
|
|
|
(define build
|
|
|
|
|
(gexp
|
|
|
|
|
(begin
|
|
|
|
|
(use-modules (ice-9 ftw)
|
|
|
|
|
(ice-9 match)
|
|
|
|
|
(srfi srfi-26)
|
|
|
|
|
(system base compile))
|
|
|
|
|
|
|
|
|
|
(ungexp %mkdir-p-definition)
|
|
|
|
|
|
|
|
|
|
(define (regular? file)
|
|
|
|
|
(not (member file '("." ".."))))
|
|
|
|
|
|
|
|
|
|
(define (process-directory directory output)
|
|
|
|
|
(let ((entries (map (cut string-append directory "/" <>)
|
|
|
|
|
(scandir directory regular?))))
|
|
|
|
|
(for-each (lambda (entry)
|
|
|
|
|
(if (file-is-directory? entry)
|
|
|
|
|
(let ((output (string-append output "/"
|
|
|
|
|
(basename entry))))
|
|
|
|
|
(mkdir-p output)
|
|
|
|
|
(process-directory entry output))
|
|
|
|
|
(let* ((base (string-drop-right
|
|
|
|
|
(basename entry)
|
|
|
|
|
4)) ;.scm
|
|
|
|
|
(output (string-append output "/" base
|
|
|
|
|
".go")))
|
|
|
|
|
(compile-file entry
|
|
|
|
|
#:output-file output
|
|
|
|
|
#:opts
|
|
|
|
|
%auto-compilation-options))))
|
|
|
|
|
entries)))
|
|
|
|
|
|
|
|
|
|
(set! %load-path (cons (ungexp modules) %load-path))
|
|
|
|
|
(mkdir (ungexp output))
|
|
|
|
|
(chdir (ungexp modules))
|
|
|
|
|
(process-directory "." (ungexp output)))))
|
|
|
|
|
|
|
|
|
|
;; TODO: Pass MODULES as an environment variable.
|
|
|
|
|
(gexp->derivation name build
|
|
|
|
|
#:system system
|
|
|
|
|
#:guile-for-build guile
|
|
|
|
|
#:local-build? #t)))
|
|
|
|
|
|
2014-04-28 23:00:57 +02:00
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
;;; Convenience procedures.
|
|
|
|
|
;;;
|
|
|
|
|
|
2014-05-01 18:53:16 +02:00
|
|
|
|
(define (default-guile)
|
|
|
|
|
;; Lazily resolve 'guile-final'. This module must not refer to (gnu …)
|
|
|
|
|
;; modules directly, to avoid circular dependencies, hence this hack.
|
gnu: Split (gnu packages base), adding (gnu packages commencement).
* gnu/packages/base.scm (gnu-make-boot0, diffutils-boot0,
findutils-boot0, %boot0-inputs, nix-system->gnu-triplet, boot-triplet,
binutils-boot0, gcc-boot0, perl-boot0, linux-libre-headers-boot0,
texinfo-boot0, %boot1-inputs, glibc-final-with-bootstrap-bash,
cross-gcc-wrapper, static-bash-for-glibc, glibc-final,
gcc-boot0-wrapped, %boot2-inputs, binutils-final, libstdc++,
gcc-final, ld-wrapper-boot3, %boot3-inputs, bash-final, %boot4-inputs,
guile-final, gnu-make-final, ld-wrapper, coreutils-final, grep-final,
%boot5-inputs, %final-inputs, canonical-package, gcc-toolchain,
gcc-toolchain-4.8, gcc-toolchain-4.9): Move to...
* gnu/packages/commencement.scm: ... here. New file.
* gnu-system.am (GNU_SYSTEM_MODULES): Add it.
* build-aux/check-final-inputs-self-contained.scm: Adjust accordingly.
* gnu/packages/cross-base.scm: Likewise.
* gnu/packages/make-bootstrap.scm: Likewise.
* guix/build-system/cmake.scm (cmake-build): Likewise.
* guix/build-system/gnu.scm (standard-packages, gnu-build,
gnu-cross-build): Likewise.
* guix/build-system/perl.scm (perl-build): Likewise.
* guix/build-system/python.scm (python-build): Likewise.
* guix/build-system/trivial.scm (guile-for-build): Likewise.
* guix/download.scm (url-fetch): Likewise.
* guix/gexp.scm (default-guile): Likewise.
* guix/git-download.scm (git-fetch): Likewise.
* guix/monads.scm (run-with-store): Likewise.
* guix/packages.scm (default-guile): Likewise.
* guix/scripts/package.scm (guix-package): Likewise.
* guix/scripts/refresh.scm: Likewise.
* guix/svn-download.scm (svn-fetch): Likewise.
* tests/builders.scm (%bootstrap-inputs, %bootstrap-search-paths):
Likewise.
* tests/packages.scm ("GNU Make, bootstrap"): Likewise.
* tests/guix-package.sh: Likewise.
* gnu/services/base.scm: Use 'canonical-package' instead of xxx-final.
* gnu/services/xorg.scm: Likewise.
* gnu/system/vm.scm: Likewise.
* guix/scripts/pull.scm (guix-pull): Likewise.
2014-08-27 00:25:17 +02:00
|
|
|
|
(module-ref (resolve-interface '(gnu packages commencement))
|
2014-05-01 18:53:16 +02:00
|
|
|
|
'guile-final))
|
|
|
|
|
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(define* (gexp->script name exp
|
2014-05-01 18:53:16 +02:00
|
|
|
|
#:key (modules '()) (guile (default-guile)))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
"Return an executable script NAME that runs EXP using GUILE with MODULES in
|
|
|
|
|
its search path."
|
|
|
|
|
(mlet %store-monad ((modules (imported-modules modules))
|
|
|
|
|
(compiled (compiled-modules modules)))
|
|
|
|
|
(gexp->derivation name
|
|
|
|
|
(gexp
|
|
|
|
|
(call-with-output-file (ungexp output)
|
|
|
|
|
(lambda (port)
|
2014-06-04 17:26:54 +02:00
|
|
|
|
;; Note: that makes a long shebang. When the store
|
|
|
|
|
;; is /gnu/store, that fits within the 128-byte
|
|
|
|
|
;; limit imposed by Linux, but that may go beyond
|
|
|
|
|
;; when running tests.
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(format port
|
|
|
|
|
"#!~a/bin/guile --no-auto-compile~%!#~%"
|
|
|
|
|
(ungexp guile))
|
2014-09-07 23:57:36 +02:00
|
|
|
|
|
|
|
|
|
;; Write the 'eval-when' form so that it can be
|
|
|
|
|
;; compiled.
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(write
|
2014-09-07 23:57:36 +02:00
|
|
|
|
'(eval-when (expand load eval)
|
|
|
|
|
(set! %load-path
|
|
|
|
|
(cons (ungexp modules) %load-path))
|
|
|
|
|
(set! %load-compiled-path
|
|
|
|
|
(cons (ungexp compiled)
|
|
|
|
|
%load-compiled-path)))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
port)
|
|
|
|
|
(write '(ungexp exp) port)
|
|
|
|
|
(chmod port #o555)))))))
|
|
|
|
|
|
|
|
|
|
(define (gexp->file name exp)
|
|
|
|
|
"Return a derivation that builds a file NAME containing EXP."
|
|
|
|
|
(gexp->derivation name
|
|
|
|
|
(gexp
|
|
|
|
|
(call-with-output-file (ungexp output)
|
|
|
|
|
(lambda (port)
|
2014-07-16 15:48:28 +02:00
|
|
|
|
(write '(ungexp exp) port))))
|
|
|
|
|
#:local-build? #t))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
|
2015-01-12 23:26:52 +01:00
|
|
|
|
(define* (text-file* name #:rest text)
|
|
|
|
|
"Return as a monadic value a derivation that builds a text file containing
|
2015-03-28 21:26:33 +01:00
|
|
|
|
all of TEXT. TEXT may list, in addition to strings, objects of any type that
|
|
|
|
|
can be used in a gexp: packages, derivations, local file objects, etc. The
|
|
|
|
|
resulting store file holds references to all these."
|
2015-01-12 23:26:52 +01:00
|
|
|
|
(define builder
|
|
|
|
|
(gexp (call-with-output-file (ungexp output "out")
|
|
|
|
|
(lambda (port)
|
|
|
|
|
(display (string-append (ungexp-splicing text)) port)))))
|
|
|
|
|
|
|
|
|
|
(gexp->derivation name builder))
|
|
|
|
|
|
2014-04-28 23:00:57 +02:00
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
;;; Syntactic sugar.
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
(eval-when (expand load eval)
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(define* (read-ungexp chr port #:optional native?)
|
|
|
|
|
"Read an 'ungexp' or 'ungexp-splicing' form from PORT. When NATIVE? is
|
|
|
|
|
true, use 'ungexp-native' and 'ungexp-native-splicing' instead."
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(define unquote-symbol
|
|
|
|
|
(match (peek-char port)
|
|
|
|
|
(#\@
|
|
|
|
|
(read-char port)
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(if native?
|
|
|
|
|
'ungexp-native-splicing
|
|
|
|
|
'ungexp-splicing))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
(_
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(if native?
|
|
|
|
|
'ungexp-native
|
|
|
|
|
'ungexp))))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
|
|
|
|
|
(match (read port)
|
|
|
|
|
((? symbol? symbol)
|
|
|
|
|
(let ((str (symbol->string symbol)))
|
|
|
|
|
(match (string-index-right str #\:)
|
|
|
|
|
(#f
|
|
|
|
|
`(,unquote-symbol ,symbol))
|
|
|
|
|
(colon
|
|
|
|
|
(let ((name (string->symbol (substring str 0 colon)))
|
|
|
|
|
(output (substring str (+ colon 1))))
|
|
|
|
|
`(,unquote-symbol ,name ,output))))))
|
|
|
|
|
(x
|
|
|
|
|
`(,unquote-symbol ,x))))
|
|
|
|
|
|
|
|
|
|
(define (read-gexp chr port)
|
|
|
|
|
"Read a 'gexp' form from PORT."
|
|
|
|
|
`(gexp ,(read port)))
|
|
|
|
|
|
|
|
|
|
;; Extend the reader
|
|
|
|
|
(read-hash-extend #\~ read-gexp)
|
gexp: Add 'ungexp-native' and 'ungexp-native-splicing'.
* guix/gexp.scm (<gexp>)[natives]: New field.
(write-gexp): Use both 'gexp-references' and
'gexp-native-references'.
(gexp->derivation): Use both 'gexp-inputs' and 'gexp-native-inputs',
and append them.
(gexp-inputs): Add 'references' parameter and honor it.
(gexp-native-inputs): New procedure.
(gexp->sexp)[reference->sexp]: Add 'native?' parameter and honor it.
Use it, and use 'gexp-native-references'.
(gexp)[collect-native-escapes]: New procedure.
[escape->ref]: Handle 'ungexp-native' and 'ungexp-native-splicing'.
[substitute-ungexp, substitute-ungexp-splicing]: New procedures.
[substitute-references]: Use them, and handle 'ungexp-native' and
'ungexp-native-splicing'.
Adjust generated 'make-gexp' call to provide both normal references
and native references.
[read-ungexp]: Support 'ungexp-native' and
'ungexp-native-splicing'.
Add reader extension for #+.
* tests/gexp.scm (gexp-native-inputs): New procedure.
(gexp->sexp*): Add 'target' parameter.
("ungexp + ungexp-native",
"input list + ungexp-native",
"input list splicing + ungexp-native-splicing",
"gexp->derivation, ungexp-native",
"gexp->derivation, ungexp + ungexp-native"): New tests.
("sugar"): Add tests for #+ and #+@.
* doc/guix.texi (G-Expressions): Document 'ungexp-native' et al.
2014-08-18 14:53:10 +02:00
|
|
|
|
(read-hash-extend #\$ read-ungexp)
|
|
|
|
|
(read-hash-extend #\+ (cut read-ungexp <> <> #t)))
|
2014-04-28 23:00:57 +02:00
|
|
|
|
|
|
|
|
|
;;; gexp.scm ends here
|