Ce serveur Gitlab sera éteint le 30 juin 2020, pensez à migrer vos projets vers les serveurs gitlab-research.centralesupelec.fr et gitlab-student.centralesupelec.fr !

el-get-byte-compile.el 8.05 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
;;; el-get --- Manage the external elisp bits and pieces you depend upon
;;
;; Copyright (C) 2010-2011 Dimitri Fontaine
;;
;; Author: Dimitri Fontaine <dim@tapoueh.org>
;; URL: http://www.emacswiki.org/emacs/el-get
;; GIT: https://github.com/dimitri/el-get
;; Licence: WTFPL, grab your copy here: http://sam.zoy.org/wtfpl/
;;
;; This file is NOT part of GNU Emacs.
;;
;; Install
13
;;     Please see the README.md file from the same distribution
14

Ryan C. Thompson's avatar
Ryan C. Thompson committed
15
(require 'cl)                           ; yes I like loop
16 17
(require 'bytecomp)

18 19 20 21 22 23 24 25 26 27 28 29 30 31
;; byte-recompile-file:
;;
;;  - in Emacs23 will not recompile a file when the source is newer than the
;;    bytecode (.elc)
;;
;;  - in Emacs24 has another different and unhelpful behavior:
;;
;;    If the `.elc' file does not exist, normally this function *does not*
;;    compile FILENAME. If ARG is 0, that means compile the file even if it
;;    has never been compiled before.
;;
;; so we just define our own
(defun el-get-byte-compile-file (el)
  "Byte compile the EL file, and skips unnecessary compilation.
32 33

Specifically, if the compiled elc file already exists and is
34 35
newer, then compilation is skipped."
  (let ((elc (concat (file-name-sans-extension el) ".elc"))
Ryan C. Thompson's avatar
Ryan C. Thompson committed
36 37
        ;; Byte-compile runs emacs-lisp-mode-hook; disable it
        emacs-lisp-mode-hook byte-compile-warnings)
38
    (when (or (not (file-exists-p elc))
Ryan C. Thompson's avatar
Ryan C. Thompson committed
39
              (not (file-newer-than-file-p elc el)))
40
      (condition-case err
Ryan C. Thompson's avatar
Ryan C. Thompson committed
41 42 43
          (byte-compile-file el)
        ((debug error) ;; catch-all, allow for debugging
         (message "%S" (error-message-string err)))))))
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62

(defun el-get-byte-compile-file-or-directory (file)
  "Byte-compile FILE or all files within it if it is a directory."
  (let ((byte-compile-warnings nil)
        ;; Byte-compile runs emacs-lisp-mode-hook; disable it
        emacs-lisp-mode-hook)
    (if (file-directory-p file)
        (byte-recompile-directory file 0)
      (el-get-byte-compile-file file))))

(defun el-get-assemble-files-for-byte-compilation (package)
  "Assemble a list of *absolute* paths to byte-compile for PACKAGE."
  (when el-get-byte-compile
    (let* ((source   (el-get-package-def package))
           (comp-prop (plist-get source :compile))
           (compile (el-get-as-list comp-prop))
           ;; nocomp is true only if :compile is explicitly set to nil.
           (explicit-nocomp (and (plist-member source :compile)
                                 (not comp-prop)))
Ryan C. Thompson's avatar
Ryan C. Thompson committed
63 64 65 66
           (method   (el-get-package-method source))
           (pdir     (el-get-package-directory package))
           (el-path  (el-get-load-path package))
           (files '()))
67 68 69 70 71 72 73 74 75 76
      (cond
       (compile
        ;; only byte-compile what's in the :compile property of the recipe
        (dolist (path compile)
          (let ((fullpath (expand-file-name path pdir)))
            (if (file-exists-p fullpath)
                ;; path is a file/dir, so add it literally
                (add-to-list 'files fullpath)
              ;; path is a regexp, so add matching file names in package dir
              (mapc (apply-partially 'add-to-list 'files)
Ryan C. Thompson's avatar
Ryan C. Thompson committed
77
                    (directory-files pdir nil path))))))
78 79 80 81 82 83 84 85 86 87 88 89 90 91

       ;; If package has (:compile nil), or package has its own build
       ;; instructions, or package is already pre-compiled by the
       ;; installation method, then don't compile anything.
       ((or explicit-nocomp
            (el-get-build-commands package)
            (member method '(apt-get fink pacman)))
        nil)

       ;; Default: compile the package's entire load-path
       (t
        (mapc (apply-partially 'add-to-list 'files) el-path)))
      files)))

92 93 94 95 96 97 98
(defun el-get-clean-stale-compiled-files (dir &optional recursive)
  "In DIR, delete all elc files older than their corresponding el files.

With optional arg RECURSIVE, do so in all subdirectories as well."
  ;; Process elc files in this dir
  (let ((elc-files (directory-files dir 'full "\\.elc$")))
    (loop for elc in elc-files
99
          for el = (concat (file-name-sans-extension elc) ".el")
100 101
          if (and (file-exists-p elc)
                  (not (file-directory-p elc))
102
                  (not (file-newer-than-file-p elc el)))
103
          do (progn
104
               (message "el-get-byte-compile: Cleaning stale compiled file %s" elc)
105 106 107 108
               (delete-file elc nil)))
    ;; Process subdirectories recursively
    (when recursive
      (loop for dir in (directory-files dir 'full)
109
            for localdir = (file-name-nondirectory dir)
110
            if (file-directory-p dir)
111
            unless (member localdir '("." ".."
Ryan C. Thompson's avatar
Ryan C. Thompson committed
112 113 114 115 116 117 118
                                      ;; This list of dirs to ignore courtesy of ack
                                      ;; http://betterthangrep.com/
                                      "autom4te.cache" "blib" "_build"
                                      ".bzr" ".cdv" "cover_db" "CVS" "_darcs"
                                      "~.dep" "~.dot" ".git" ".hg" "_MTN"
                                      "~.nib" ".pc" "~.plst" "RCS" "SCCS"
                                      "_sgbak" ".svn"))
119
            do (el-get-clean-stale-compiled-files dir recursive)))))
120

121 122 123 124 125 126 127
(defun el-get-byte-compile-from-stdin ()
  "byte compile files from stdin.

Standard input must be a property list with properties
`:load-path' and `:compile-files', each of which should have a
value that is a list of strings. The variable `load-path' will be
set from the `:load-path' property, and then all the files listed
128 129 130 131
in `:compile-files' will be byte-compiled.

Standard input can also contain a `:clean-directory' property,
whose value is a directory to be cleared of stale elc files."
132 133
  (assert noninteractive nil
          "`el-get-byte-compile-from-stdin' is to be used only with -batch")
134
  (let* ((input-data (read-minibuffer ""))
135
         (load-path (append (plist-get input-data :load-path) load-path))
136 137
         (files (plist-get input-data :compile-files))
         (dir-to-clean (plist-get input-data :clean-directory)))
138 139
    (unless (or dir-to-clean files)
      (warn "Did not get a list of files to byte-compile or a directory to clean. The input may have been corrupted."))
140 141 142
    (when dir-to-clean
      (assert (stringp dir-to-clean) nil
              "The value of `:clean-directory' must be a string.")
143
      (message "el-get-byte-compile: Cleaning stale compiled files in %s" dir-to-clean)
144
      (el-get-clean-stale-compiled-files dir-to-clean 'recursive))
145 146 147 148
    (loop for f in files
          do (progn
               (message "el-get-byte-compile: %s" f)
               (el-get-byte-compile-file-or-directory f)))))
149 150

(defun el-get-byte-compile-process (package buffer working-dir sync files)
151
  "return the `el-get-start-process-list' entry to byte compile PACKAGE"
152
  (let* ((input-data
153
          (list :load-path (cons "." load-path)
154 155
                :compile-files files
                :clean-directory (el-get-package-directory package)))
156
         (subprocess-function 'el-get-byte-compile-from-stdin)
157 158 159
         (bytecomp-command
          `(,el-get-emacs
            "-Q" "-batch" "-f" "toggle-debug-on-error"
160 161 162
            "-l" ,(file-name-sans-extension
                   (symbol-file subprocess-function 'defun))
            "-f" ,(symbol-name subprocess-function))))
163
    `(:command-name "byte-compile"
Ryan C. Thompson's avatar
Ryan C. Thompson committed
164 165 166
                    :buffer-name ,buffer
                    :default-directory ,working-dir
                    :shell t
167
                    :stdin ,input-data
Ryan C. Thompson's avatar
Ryan C. Thompson committed
168 169 170 171 172 173
                    :sync ,sync
                    :program ,(car bytecomp-command)
                    :args ,(cdr bytecomp-command)
                    :message ,(format "el-get-build %s: byte-compile ok." package)
                    :error ,(format
                             "el-get could not byte-compile %s" package))))
174 175 176

(defun el-get-byte-compile (package)
  "byte compile files for given package"
177 178
  (interactive
   (list (el-get-read-package-with-status "Byte compile" "installed")))
179
  (let ((pdir  (el-get-package-directory package))
Ryan C. Thompson's avatar
Ryan C. Thompson committed
180 181
        (buf   "*el-get-byte-compile*")
        (files (el-get-assemble-files-for-byte-compilation package)))
182 183 184 185
    (el-get-start-process-list
     package
     (list (el-get-byte-compile-process package buf pdir t files))
     nil)))
186 187

(provide 'el-get-byte-compile)