;; Applied patch from Yuuichi Teranishi <teranisi@gohome.org>.
[elisp/apel.git] / install.el
1 ;;; install.el --- Emacs Lisp package install utility
2
3 ;; Copyright (C) 1996,97,98,99,2001  Free Software Foundation, Inc.
4
5 ;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp>
6 ;;      Shuhei KOBAYASHI <shuhei@aqua.ocn.ne.jp>
7 ;; Created: 1996/08/18
8 ;; Keywords: install, byte-compile, directory detection
9
10 ;; This file is part of APEL (A Portable Emacs Library).
11
12 ;; This program is free software; you can redistribute it and/or
13 ;; modify it under the terms of the GNU General Public License as
14 ;; published by the Free Software Foundation; either version 2, or (at
15 ;; your option) any later version.
16
17 ;; This program is distributed in the hope that it will be useful, but
18 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 ;; General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING.  If not, write to
24 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25 ;; Boston, MA 02111-1307, USA.
26
27 ;;; Code:
28
29 (require 'poe)                          ; make-directory for v18
30 (require 'path-util)                    ; default-load-path
31
32
33 ;;; @ compile Emacs Lisp files
34 ;;;
35
36 (defun compile-elisp-module (module &optional dir force)
37   "Byte-compile MODULE.
38 MODULE is a symbol of emacs-lisp source file name without suffix.
39 Optional 2nd argument DIR is a directory where MODULE resides in.
40 Unless optional 3rd argument FORCE is non-nil, MODULE is byte-compiled
41 only when MODULE is newer than compiled file."
42   (setq module (expand-file-name (symbol-name module) dir))
43   (let ((el-file (concat module ".el"))
44         (elc-file (concat module ".elc")))
45     (if (or force (file-newer-than-file-p el-file elc-file))
46         (byte-compile-file el-file))))
47
48 (defun compile-elisp-modules (modules &optional dir force)
49   "Byte-compile MODULES.
50 See `compile-elisp-module' for more information."
51   (while modules
52     (compile-elisp-module (car modules) dir force)
53     (setq modules (cdr modules))))
54
55
56 ;;; @ install files
57 ;;;
58
59 (defvar install-overwritten-file-modes (+ (* 64 6)(* 8 4) 4) ; 0644
60   "Default file modes for files installed by `install-file'.")
61
62 (defun install-file (file src dst &optional move overwrite dry-run)
63   "Install FILE in SRC directory to DST directory.
64 If optional 4th argument MOVE is non-nil, remove SRC/FILE.
65 If optional 5th argument OVERWRITE is non-nil, remove DST/FILE first.
66 If optional 6th argument DRY-RUN is non-nil, just show what would have
67 been installed."
68   (if dry-run
69       (princ (format "%s -> %s\n" file dst))
70     (let ((src-file (expand-file-name file src))
71           (dst-file (expand-file-name file dst)))
72       (if (file-exists-p src-file)
73           (let ((current-file-modes (default-file-modes)))
74             (unwind-protect
75                 (condition-case err
76                     (progn
77                       (set-default-file-modes install-overwritten-file-modes)
78                       (if move
79                           (progn
80                             (rename-file src-file dst-file overwrite)
81                             (set-file-modes dst-file
82                                             install-overwritten-file-modes))
83                         (copy-file src-file dst-file overwrite t))
84                       (princ (format "%s -> %s\n" file dst)))
85                   (error
86                    (princ (format "%s: %s\n" file (nth 1 err)))))
87               (set-default-file-modes current-file-modes)))
88         (princ (format "%s: No such file or directory\n" src-file))))))
89
90 (defun install-files (files src dst &optional move overwrite dry-run)
91   "Install FILES.
92 See `install-file' for more information."
93   (or dry-run
94       (file-exists-p dst)
95       (make-directory dst t))
96   (while files
97     (install-file (car files) src dst move overwrite dry-run)
98     (setq files (cdr files))))
99
100
101 ;;; @@ install Emacs Lisp files
102 ;;;
103
104 (defun install-elisp-module (module src dst &optional dry-run)
105   "Install MODULE.
106 MODULE is a symbol of emacs-lisp source file name without suffix.
107 See `install-file' for information of the rest of arguments."
108   (let* ((name (symbol-name module))
109          (el-file (concat name ".el"))
110          (elc-file (concat name ".elc")))
111     (install-file el-file  src dst nil   'overwrite dry-run)
112     (install-file elc-file src dst 'move 'overwrite dry-run)))
113
114 (defun install-elisp-modules (modules src dst &optional dry-run)
115   "Install MODULES.
116 See `install-elisp-modules' for more information."
117   (or dry-run
118       (file-exists-p dst)
119       (make-directory dst t))
120   (while modules
121     (install-elisp-module (car modules) src dst dry-run)
122     (setq modules (cdr modules))))
123
124
125 ;;; @ detect install path
126 ;;;
127
128 (defvar install-prefix
129   (cond
130    ((<= emacs-major-version 18)
131     ;; The default of `exec-directory' is "/usr/local/emacs/etc".
132     ;; (See src/paths.h-dist)
133     (expand-file-name "../.." exec-directory))
134    ((featurep 'meadow)
135     ;; I have no idea, sorry.
136     (expand-file-name "../../.." data-directory))
137    ((featurep 'xemacs)
138     ;; The default of 'data-directory' is
139     ;; "/usr/local/lib/xemacs-$VERSION/etc".
140     (expand-file-name "../../.." data-directory))
141    (t
142     ;; The default of 'data-directory' is
143     ;; "/usr/local/lib/emacs/$VERSION/etc" (19.28 and earlier), or
144     ;; "/usr/local/share/emacs/$VERSION/etc" (19.29 and later).
145     (expand-file-name "../../../.." data-directory)))
146   "Install prefix, normally \"/usr/local\".")
147
148 ;; v18 does not have the default, please set explicitly.
149 (defvar install-elisp-prefix "site-lisp"
150   "Prefix for local lisp directory, normally \"site-lisp\".")
151
152 (defun install-detect-elisp-directory (&optional prefix elisp-prefix
153                                                  allow-version-specific)
154   (or prefix
155       (setq prefix install-prefix))
156   (or elisp-prefix
157       (setq elisp-prefix install-elisp-prefix))
158   (or (let ((rest default-load-path)
159             (regexp (concat "^"
160                             (expand-file-name (concat ".*/" elisp-prefix)
161                                               prefix)
162                             "/?$"))
163             (found nil))
164         (while (and rest (not found))
165           (if (string-match regexp (car rest))
166               (if (or allow-version-specific
167                       (not (string-match (format "/%d\\.%d"
168                                                  emacs-major-version
169                                                  emacs-minor-version)
170                                          (car rest))))
171                   (setq found (car rest))))
172           (setq rest (cdr rest)))
173         found)
174       ;; we couldn't find appropriate directory from `load-path'.
175       ;; use the default directory for each emacsen.
176       (expand-file-name (concat (if (and (not (featurep 'xemacs))
177                                          (or (>= emacs-major-version 20)
178                                              (and (= emacs-major-version 19)
179                                                   (> emacs-minor-version 28))))
180                                     "share/"
181                                   "lib/")
182                                 (cond
183                                  ((featurep 'xemacs) "xemacs/")
184                                  ;; unfortunately, unofficial mule based on
185                                  ;; 19.29 and later use "emacs/" by default.
186                                  ((boundp 'MULE) "mule/")
187                                  ((boundp 'NEMACS) "nemacs/")
188                                  (t "emacs/"))
189                                 elisp-prefix)
190                         prefix)))
191
192 (defvar install-default-elisp-directory
193   (install-detect-elisp-directory))
194
195
196 ;;; @ for XEmacs package system
197 ;;;
198
199 (defun install-update-package-files (package dir &optional dry-run)
200   (cond
201    (dry-run
202     (princ (format "Updating autoloads in directory %s..\n\n" dir))
203
204     (princ (format "Processing %s\n" dir))
205     (princ "Generating custom-load.el...\n\n")
206
207     (princ (format "Compiling %s...\n"
208                    (expand-file-name "auto-autoloads.el" dir)))
209     (princ (format "Wrote %s\n"
210                    (expand-file-name "auto-autoloads.elc" dir)))
211
212     (princ (format "Compiling %s...\n"
213                    (expand-file-name "custom-load.el" dir)))
214     (princ (format "Wrote %s\n"
215                    (expand-file-name "custom-load.elc" dir))))
216    (t
217     (setq autoload-package-name package)
218
219     (let ((command-line-args-left (list dir)))
220       (batch-update-directory))
221
222     (let ((command-line-args-left (list dir)))
223       (Custom-make-dependencies))
224
225     (byte-compile-file (expand-file-name "auto-autoloads.el" dir))
226     (byte-compile-file (expand-file-name "custom-load.el" dir)))))
227
228
229 ;;; @ Other Utilities
230 ;;;
231
232 (defun install-just-print-p ()
233   (let ((flag (getenv "MAKEFLAGS"))
234         (case-fold-search nil))
235     (princ (format "MAKEFLAGS=%s\n" (or flag "")))
236     (if flag
237         ;; Check whether MAKEFLAGS contain "n" option or not.
238         (string-match "^\\(\\(--[^ ]+ \\)+-\\|[^ =-]\\)*n" flag))))
239
240
241 ;;; @ end
242 ;;;
243
244 (require 'product)
245 (product-provide (provide 'install) (require 'apel-ver))
246
247 ;;; install.el ends here