~ruther/guix-local

b7dee6a0b8af90e5adaa5b35f8dda359de96868d — Maxim Cournoyer 8 years ago a5e0367
emacs-build-system: Add set-emacs-load-path phase.

This generalizes the mechanism by which the Emacs dependencies are made visible,
so that any build phase can make use of them.

* guix/build/emacs-build-system.scm (%legacy-install-suffix): New variable.
(%install-suffix): Redefine in terms of %legacy-install-suffix.
(set-emacs-load-path): Add new phase used for dependency resolution.
(build): Remove ad-hoc dependency discovery mechanism.
(emacs-input->el-directory): Add new procedure.
(emacs-inputs-el-directories): Use it.
(package-name-version->elpa-name-version): Fix typo.
(%standard-phases): Include the new `set-emacs-load-path' phase. Refactor to
make the ordering of the phases clearer.
* guix/build/emacs-utils.scm (emacs-byte-compile-directory): Remove the
optional `dependency-dirs' argument, which is now obsoleted by the
`set-emacs-load-path' phase.

Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2 files changed, 39 insertions(+), 22 deletions(-)

M guix/build/emacs-build-system.scm
M guix/build/emacs-utils.scm
M guix/build/emacs-build-system.scm => guix/build/emacs-build-system.scm +36 -14
@@ 2,6 2,7 @@
;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
;;; Copyright © 2016 David Thompson <davet@gnu.org>
;;; Copyright © 2016 Alex Kost <alezost@gmail.com>
;;; Copyright © 2018 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;


@@ 42,7 43,8 @@
;; Directory suffix where we install ELPA packages.  We avoid ".../elpa" as
;; Emacs expects to find the ELPA repository 'archive-contents' file and the
;; archive signature.
(define %install-suffix "/share/emacs/site-lisp/guix.d")
(define %legacy-install-suffix "/share/emacs/site-lisp")
(define %install-suffix (string-append %legacy-install-suffix "/guix.d"))

;; These are the default inclusion/exclusion regexps for the install phase.
(define %default-include '("^[^/]*\\.el$" "^[^/]*\\.info$" "^doc/.*\\.info$"))


@@ 72,17 74,25 @@ archive, a directory, or an Emacs Lisp file."
        #t)
      (gnu:unpack #:source source)))

(define* (set-emacs-load-path #:key inputs #:allow-other-keys)
  "Set the EMACSLOADPATH environment variable so that dependencies are found."
  (let* ((input-elisp-dirs (emacs-inputs-el-directories
                            (emacs-inputs-directories inputs)))
         (emacs-load-path-value (string-join
                                 input-elisp-dirs ":" 'suffix)))
    (setenv "EMACSLOADPATH" emacs-load-path-value)
    (format #t "environment variable `EMACSLOADPATH' set to ~a\n"
            emacs-load-path-value)))

(define* (build #:key outputs inputs #:allow-other-keys)
  "Compile .el files."
  (let* ((emacs (string-append (assoc-ref inputs "emacs") "/bin/emacs"))
         (out (assoc-ref outputs "out"))
         (elpa-name-ver (store-directory->elpa-name-version out))
         (el-dir (string-append out %install-suffix "/" elpa-name-ver))
         (deps-dirs (emacs-inputs-directories inputs)))
         (el-dir (string-append out %install-suffix "/" elpa-name-ver)))
    (setenv "SHELL" "sh")
    (parameterize ((%emacs emacs))
      (emacs-byte-compile-directory el-dir
                                    (emacs-inputs-el-directories deps-dirs)))))
      (emacs-byte-compile-directory el-dir))))

(define* (patch-el-files #:key outputs #:allow-other-keys)
  "Substitute the absolute \"/bin/\" directory with the right location in the


@@ 199,18 209,27 @@ store in '.el' files."
    (match inputs
      (((names . directories) ...) directories))))

(define (emacs-input->el-directory emacs-input)
  "Return the correct Elisp directory location of EMACS-INPUT or #f if none."
  (let ((legacy-elisp-dir (string-append emacs-input %legacy-install-suffix))
        (guix-elisp-dir (string-append
                         emacs-input %install-suffix "/"
                         (store-directory->elpa-name-version emacs-input))))
    (cond
     ((file-exists? guix-elisp-dir) guix-elisp-dir)
     ((file-exists? legacy-elisp-dir) legacy-elisp-dir)
     (else (format #t "warning: could not locate elisp directory under `~a'\n"
                   emacs-input)
           #f))))

(define (emacs-inputs-el-directories dirs)
  "Build the list of Emacs Lisp directories from the Emacs package directory
DIRS."
  (append-map (lambda (d)
                (list (string-append d "/share/emacs/site-lisp")
                      (string-append d %install-suffix "/"
                                     (store-directory->elpa-name-version d))))
              dirs))
  (filter-map emacs-input->el-directory dirs))

(define (package-name-version->elpa-name-version name-ver)
  "Convert the Guix package NAME-VER to the corresponding ELPA name-version
format.  Essnetially drop the prefix used in Guix."
format.  Essentially drop the prefix used in Guix."
  (if (emacs-package? name-ver)  ; checks for "emacs-" prefix
      (string-drop name-ver (string-length "emacs-"))
      name-ver))


@@ 224,12 243,15 @@ second hyphen.  This corresponds to 'name-version' as used in ELPA packages."

(define %standard-phases
  (modify-phases gnu:%standard-phases
    (add-after 'set-paths 'set-emacs-load-path set-emacs-load-path)
    (replace 'unpack unpack)
    (delete 'configure)
    (delete 'check)
    (delete 'install)
    (replace 'build build)
    (add-before 'build 'install install)
    ;; Move the build phase after install: the .el files are byte compiled
    ;; directly in the store.
    (delete 'build)
    (replace 'install install)
    (add-after 'install 'build build)
    (add-after 'install 'make-autoloads make-autoloads)
    (add-after 'make-autoloads 'patch-el-files patch-el-files)
    (add-after 'make-autoloads 'move-doc move-doc)))

M guix/build/emacs-utils.scm => guix/build/emacs-utils.scm +3 -8
@@ 58,14 58,9 @@
                  (update-directory-autoloads ,directory))))
    (emacs-batch-eval expr)))

(define* (emacs-byte-compile-directory dir #:optional (dependency-dirs '()))
  "Byte compile all files in DIR and its sub-directories.  Before compiling
the files, add DIR and all directories in DEPENDENCY-DIRS to 'load-path'."
  (let ((expr `(progn
                (add-to-list 'load-path ,dir)
                (when ',dependency-dirs
                  (setq load-path (append ',dependency-dirs load-path)))
                (byte-recompile-directory (file-name-as-directory ,dir) 0))))
(define* (emacs-byte-compile-directory dir)
  "Byte compile all files in DIR and its sub-directories."
  (let ((expr `(byte-recompile-directory (file-name-as-directory ,dir) 0)))
    (emacs-batch-eval expr)))

(define-syntax emacs-substitute-sexps