307 lines
9.2 KiB
EmacsLisp
307 lines
9.2 KiB
EmacsLisp
;;; install.el --- Emacs Lisp package install utility
|
|
|
|
;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2006
|
|
;; Free Software Foundation, Inc.
|
|
|
|
;; Author: MORIOKA Tomohiko <tomo@m17n.org>
|
|
;; Created: 1996/08/18
|
|
;; Keywords: install, byte-compile, directory detection
|
|
|
|
;; This file is part of APEL (A Portable Emacs Library).
|
|
|
|
;; This program 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 2, or (at
|
|
;; your option) any later version.
|
|
|
|
;; This program 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 Emacs; see the file COPYING. If not, write to
|
|
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
;; Boston, MA 02110-1301, USA.
|
|
|
|
;;; Code:
|
|
|
|
(require 'poe) ; make-directory for v18
|
|
(require 'path-util) ; default-load-path
|
|
|
|
|
|
;;; @ compile Emacs Lisp files
|
|
;;;
|
|
|
|
(defun compile-elisp-module (module &optional path every-time)
|
|
(setq module (expand-file-name (symbol-name module) path))
|
|
(let ((el-file (concat module ".el"))
|
|
(elc-file (concat module ".elc")))
|
|
(if (or every-time
|
|
(file-newer-than-file-p el-file elc-file))
|
|
(byte-compile-file el-file))))
|
|
|
|
(defun compile-elisp-modules (modules &optional path every-time)
|
|
(mapcar
|
|
(function
|
|
(lambda (module)
|
|
(compile-elisp-module module path every-time)))
|
|
modules))
|
|
|
|
|
|
;;; @ install files
|
|
;;;
|
|
|
|
(defvar install-overwritten-file-modes (+ (* 64 6)(* 8 4) 4)) ; 0644
|
|
|
|
(defun install-file (file src dest &optional move overwrite just-print)
|
|
(if just-print
|
|
(princ (format "%s -> %s\n" file dest))
|
|
(let ((src-file (expand-file-name file src)))
|
|
(if (file-exists-p src-file)
|
|
(let ((full-path (expand-file-name file dest)))
|
|
(if (and (file-exists-p full-path) overwrite)
|
|
(delete-file full-path))
|
|
(copy-file src-file full-path t t)
|
|
(set-file-modes full-path install-overwritten-file-modes)
|
|
(if move
|
|
(catch 'tag
|
|
(while (and (file-exists-p src-file)
|
|
(file-writable-p src-file))
|
|
(condition-case err
|
|
(progn
|
|
(delete-file src-file)
|
|
(throw 'tag nil))
|
|
(error (princ (format "%s\n" (nth 1 err))))))))
|
|
(princ (format "%s -> %s\n" file dest)))))))
|
|
|
|
(defun install-files (files src dest &optional move overwrite just-print)
|
|
(or just-print
|
|
(file-exists-p dest)
|
|
(make-directory dest t))
|
|
(mapcar
|
|
(function
|
|
(lambda (file)
|
|
(install-file file src dest move overwrite just-print)))
|
|
files))
|
|
|
|
|
|
;;; @@ install Emacs Lisp files
|
|
;;;
|
|
|
|
(defun install-elisp-module (module src dest &optional just-print del-elc)
|
|
(let (el-file elc-file)
|
|
(let ((name (symbol-name module)))
|
|
(setq el-file (concat name ".el"))
|
|
(setq elc-file (concat name ".elc")))
|
|
(let ((src-file (expand-file-name el-file src)))
|
|
(if (not (file-exists-p src-file))
|
|
nil
|
|
(if just-print
|
|
(princ (format "%s -> %s\n" el-file dest))
|
|
(let ((full-path (expand-file-name el-file dest)))
|
|
(if (file-exists-p full-path)
|
|
(delete-file full-path))
|
|
(copy-file src-file full-path t t)
|
|
(set-file-modes full-path install-overwritten-file-modes)
|
|
(princ (format "%s -> %s\n" el-file dest)))))
|
|
(setq src-file (expand-file-name elc-file src))
|
|
(if (not (file-exists-p src-file))
|
|
(let ((full-path (expand-file-name elc-file dest)))
|
|
(if (and del-elc (file-exists-p full-path))
|
|
(if just-print
|
|
(princ (format "%s -> to be deleted\n" full-path))
|
|
(delete-file full-path)
|
|
(princ (format "%s -> deleted\n" full-path)))))
|
|
(if just-print
|
|
(princ (format "%s -> %s\n" elc-file dest))
|
|
(let ((full-path (expand-file-name elc-file dest)))
|
|
(if (file-exists-p full-path)
|
|
(delete-file full-path))
|
|
(copy-file src-file full-path t t)
|
|
(set-file-modes full-path install-overwritten-file-modes)
|
|
(catch 'tag
|
|
(while (file-exists-p src-file)
|
|
(condition-case err
|
|
(progn
|
|
(delete-file src-file)
|
|
(throw 'tag nil))
|
|
(error (princ (format "%s\n" (nth 1 err)))))))
|
|
(princ (format "%s -> %s\n" elc-file dest))))))))
|
|
|
|
(defun install-elisp-modules (modules src dest &optional just-print del-elc)
|
|
(or just-print
|
|
(file-exists-p dest)
|
|
(make-directory dest t))
|
|
(mapcar
|
|
(function
|
|
(lambda (module)
|
|
(install-elisp-module module src dest just-print del-elc)))
|
|
modules))
|
|
|
|
|
|
;;; @ detect install path
|
|
;;;
|
|
|
|
;; install to shared directory (maybe "/usr/local")
|
|
(defvar install-prefix
|
|
(if (or (<= emacs-major-version 18)
|
|
(featurep 'xemacs)
|
|
(featurep 'meadow) ; for Meadow
|
|
(and (eq system-type 'windows-nt) ; for NTEmacs
|
|
(>= emacs-major-version 20)))
|
|
(expand-file-name "../../.." exec-directory)
|
|
(expand-file-name "../../../.." data-directory)))
|
|
|
|
(defvar install-elisp-prefix
|
|
(if (>= emacs-major-version 19)
|
|
"site-lisp"
|
|
;; v18 does not have standard site directory.
|
|
"local.lisp"))
|
|
|
|
;; Avoid compile warning.
|
|
(eval-when-compile (autoload 'replace-in-string "subr"))
|
|
|
|
(defun install-detect-elisp-directory (&optional prefix elisp-prefix
|
|
allow-version-specific)
|
|
(or prefix
|
|
(setq prefix install-prefix))
|
|
(or elisp-prefix
|
|
(setq elisp-prefix install-elisp-prefix))
|
|
(or (catch 'tag
|
|
(let ((rest (delq nil (copy-sequence default-load-path)))
|
|
(regexp
|
|
(concat "^"
|
|
(regexp-quote (if (featurep 'xemacs)
|
|
;; Handle backslashes (Windows)
|
|
(replace-in-string
|
|
(file-name-as-directory
|
|
(expand-file-name prefix))
|
|
"\\\\" "/")
|
|
(file-name-as-directory
|
|
(expand-file-name prefix))))
|
|
".*/"
|
|
(regexp-quote
|
|
(if (featurep 'xemacs)
|
|
;; Handle backslashes (Windows)
|
|
(replace-in-string elisp-prefix "\\\\" "/")
|
|
elisp-prefix))
|
|
"/?$"))
|
|
dir)
|
|
(while rest
|
|
(setq dir (if (featurep 'xemacs)
|
|
;; Handle backslashes (Windows)
|
|
(replace-in-string (car rest) "\\\\" "/")
|
|
(car rest)))
|
|
(if (string-match regexp dir)
|
|
(if (or allow-version-specific
|
|
(not (string-match (format "/%d\\.%d"
|
|
emacs-major-version
|
|
emacs-minor-version)
|
|
dir)))
|
|
(throw 'tag (car rest))))
|
|
(setq rest (cdr rest)))))
|
|
(expand-file-name (concat (if (and (not (featurep 'xemacs))
|
|
(or (>= emacs-major-version 20)
|
|
(and (= emacs-major-version 19)
|
|
(> emacs-minor-version 28))))
|
|
"share/"
|
|
"lib/")
|
|
(cond
|
|
((featurep 'xemacs)
|
|
(if (featurep 'mule)
|
|
"xmule/"
|
|
"xemacs/"))
|
|
;; unfortunately, unofficial mule based on
|
|
;; 19.29 and later use "emacs/" by default.
|
|
((boundp 'MULE) "mule/")
|
|
((boundp 'NEMACS) "nemacs/")
|
|
(t "emacs/"))
|
|
elisp-prefix)
|
|
prefix)))
|
|
|
|
(defvar install-default-elisp-directory
|
|
(install-detect-elisp-directory))
|
|
|
|
|
|
;;; @ for XEmacs package system
|
|
;;;
|
|
|
|
(defun install-get-default-package-directory ()
|
|
(let ((dirs (append
|
|
(cond
|
|
((boundp 'early-package-hierarchies)
|
|
(append (if early-package-load-path
|
|
early-package-hierarchies)
|
|
(if late-package-load-path
|
|
late-package-hierarchies)
|
|
(if last-package-load-path
|
|
last-package-hierarchies)) )
|
|
((boundp 'early-packages)
|
|
(append (if early-package-load-path
|
|
early-packages)
|
|
(if late-package-load-path
|
|
late-packages)
|
|
(if last-package-load-path
|
|
last-packages)) ))
|
|
(if (and (boundp 'configure-package-path)
|
|
(listp configure-package-path))
|
|
(delete "" configure-package-path))))
|
|
dir)
|
|
(while (and (setq dir (car dirs))
|
|
(not (file-exists-p dir)))
|
|
(setq dirs (cdr dirs)))
|
|
dir))
|
|
|
|
(defun install-update-package-files (package dir &optional just-print)
|
|
(cond
|
|
(just-print
|
|
(princ (format "Updating autoloads in directory %s..\n\n" dir))
|
|
|
|
(princ (format "Processing %s\n" dir))
|
|
(princ "Generating custom-load.el...\n\n")
|
|
|
|
(princ (format "Compiling %s...\n"
|
|
(expand-file-name "auto-autoloads.el" dir)))
|
|
(princ (format "Wrote %s\n"
|
|
(expand-file-name "auto-autoloads.elc" dir)))
|
|
|
|
(princ (format "Compiling %s...\n"
|
|
(expand-file-name "custom-load.el" dir)))
|
|
(princ (format "Wrote %s\n"
|
|
(expand-file-name "custom-load.elc" dir))))
|
|
(t
|
|
(if (fboundp 'batch-update-directory-autoloads)
|
|
;; XEmacs 21.5.19 and newer.
|
|
(let ((command-line-args-left (list package dir)))
|
|
(batch-update-directory-autoloads))
|
|
(setq autoload-package-name package)
|
|
(let ((command-line-args-left (list dir)))
|
|
(batch-update-directory)))
|
|
|
|
(let ((command-line-args-left (list dir)))
|
|
(Custom-make-dependencies))
|
|
|
|
(byte-compile-file (expand-file-name "auto-autoloads.el" dir))
|
|
(byte-compile-file (expand-file-name "custom-load.el" dir)))))
|
|
|
|
|
|
;;; @ Other Utilities
|
|
;;;
|
|
|
|
(defun install-just-print-p ()
|
|
(let ((flag (getenv "MAKEFLAGS"))
|
|
(case-fold-search nil))
|
|
(princ (format "%s\n" flag))
|
|
(if flag
|
|
(string-match "^\\(\\(--[^ ]+ \\)+-\\|[^ =-]\\)*n" flag))))
|
|
|
|
|
|
;;; @ end
|
|
;;;
|
|
|
|
(require 'product)
|
|
(product-provide (provide 'install) (require 'apel-ver))
|
|
|
|
;;; install.el ends here
|