summaryrefslogtreecommitdiff
path: root/guix/build/emacs-build-system.scm
diff options
context:
space:
mode:
Diffstat (limited to 'guix/build/emacs-build-system.scm')
-rw-r--r--guix/build/emacs-build-system.scm92
1 files changed, 65 insertions, 27 deletions
diff --git a/guix/build/emacs-build-system.scm b/guix/build/emacs-build-system.scm
index bd0d2e0266..b779847424 100644
--- a/guix/build/emacs-build-system.scm
+++ b/guix/build/emacs-build-system.scm
@@ -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,38 +74,63 @@ 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
store in '.el' files."
+
+ (define (file-contains-nul-char? file)
+ (call-with-input-file file
+ (lambda (in)
+ (let loop ((line (read-line in 'concat)))
+ (cond
+ ((eof-object? line) #f)
+ ((string-index line #\nul) #t)
+ (else (loop (read-line in 'concat))))))
+ #:binary #t))
+
(let* ((out (assoc-ref outputs "out"))
(elpa-name-ver (store-directory->elpa-name-version out))
(el-dir (string-append out %install-suffix "/" elpa-name-ver))
- (substitute-cmd (lambda ()
- (substitute* (find-files "." "\\.el$")
- (("\"/bin/([^.]\\S*)\"" _ cmd-name)
- (let ((cmd (which cmd-name)))
- (unless cmd
- (error
- "patch-el-files: unable to locate " cmd-name))
- (string-append "\"" cmd "\"")))))))
+
+ ;; (ice-9 regex) uses libc's regexp routines, which cannot deal with
+ ;; strings containing NULs. Filter out such files. TODO: Remove
+ ;; this workaround when <https://bugs.gnu.org/30116> is fixed.
+ (el-files (remove file-contains-nul-char?
+ (find-files (getcwd) "\\.el$"))))
+ (define (substitute-program-names)
+ (substitute* el-files
+ (("\"/bin/([^.]\\S*)\"" _ cmd-name)
+ (let ((cmd (which cmd-name)))
+ (unless cmd
+ (error "patch-el-files: unable to locate " cmd-name))
+ (string-append "\"" cmd "\"")))))
+
(with-directory-excursion el-dir
- ;; Some old '.el' files (e.g., tex-buf.el in AUCTeX) are still encoded
- ;; with the "ISO-8859-1" locale.
- (unless (false-if-exception (substitute-cmd))
+ ;; Some old '.el' files (e.g., tex-buf.el in AUCTeX) are still
+ ;; ISO-8859-1-encoded.
+ (unless (false-if-exception (substitute-program-names))
(with-fluids ((%default-port-encoding "ISO-8859-1"))
- (substitute-cmd))))
+ (substitute-program-names))))
#t))
(define* (install #:key outputs
@@ -199,18 +226,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 +260,14 @@ 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)))