;;; 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 ;; 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