1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
|
-*-indented-text-*-
First, for the purposes of this policy, some terminology:
<flavor> - a particular flavor of Emacs, for example:
emacs
xemacs21
add-on package - any package which wishes to use the emacsen-common
infrastructure, usually in order to byte-compile itself for some
subset of the currently installed emacs flavors.
<package> - the name of an add-on package, for example:
auctex
bbdb
gnus
1) Guarding use of emacsen-common infrastructure
Any use of the emacsen-common infrastructure must be guarded by a
test for the existence of the emacsen-common installed state
file. i.e.:
if test -e /var/lib/emacsen-common/state/package/installed/emacsen-common
then
emacs-package-install ...
fi
Of course this requirement does not apply for the maintainer
scripts of any package that depends on emacsen-common, which
includes all add-on packages and all emacsen main <flavor>
packages: emacs-lucid, xemacs21, etc. So in practice, this guard
should rarely be necessary.
2) Flavor indication
Each flavor's binary must set the variable debian-emacs-flavor to be
the same as the name of the debian-package. For example, the
emacs-lucid package does this in startup.el:
(defconst debian-emacs-flavor 'emacs
"A symbol representing the particular debian flavor of emacs running.
Something like 'emacs, 'xemacs21, etc.")
For now, debian-emacs-flavor should be defined regardless of the
use of -q or --no-site-file.
3) Emacs startup strategy
On startup each emacsen must call (debian-startup <flavor>). During
debian-startup, the relevant flavor-specific site-start.d files will
be loaded via debian-run-directories, e.g:
emacs: /etc/emacs/site-start.d
xemacs21: /etc/xemacs21/site-start.d
The next question is, "Where should we run debian-startup?" The
safest possibility, and the one I had originally intended was to
modify lisp/startup.el to do the right thing, and I had also
intended that --no-site-file would disable all of the Debian startup
bits, including calling Debian startup. So here's what emacs-lucid
has in startup.el:
;; Debian startup
(if site-run-file
(progn
;; Load all the Debian package snippets.
;; It's in here because we want -q to kill it too.
(if (load "debian-startup" t t nil)
(debian-startup debian-emacs-flavor))
;; Now the normal site file...
(load site-run-file t t nil)))
This makes sure that Debian's bits are setup as early as possible,
and requires only minor modifications to the emacs source.
At a minimum debian-startup calls debian-run-directories which
collects the union of all the file base names (i.e. without any .el
or .elc extension, and without the directory component:
i.e. /etc/xemacs21/site-start.d/50foo.elc => 50foo), then
temporarily augments the emacs load path to include
/etc/<flavor>/site-start.d, and calls (load base-name) in
string< order.
4) /usr/share/<flavor>/site-lisp/
This directory must be treated as part of the normal emacsen load
path, and add-on packages should place their files there (see
below), e.g.:
emacs: /usr/share/emacs/site-lisp/
xemacs21: /usr/share/xemacs21/site-lisp/
5) Emacs add-on package support (examples below should make this much clearer)
A) Each add-on package must add a "Depends: emacsen-common (>=
2.0.8)" and include a file like this that indicates its
emacsen-common compatibility level:
/usr/lib/emacsen-common/packages/compat/<package>
This file should contain a single integer, which at the moment
should be 0. (Currently, the file is just used to distinguish
between old-style packages and new-style packages.)
B) Each add-on package may place a file named the same as the
package in
/usr/lib/emacsen-common/packages/install/
/usr/lib/emacsen-common/packages/remove/
and the package must make these calls from the given maintainer
scripts:
preinst:
/usr/lib/emacsen-common/emacs-package-install --preinst <package>
postinst:
/usr/lib/emacsen-common/emacs-package-install --postinst <package>
prerm:
/usr/lib/emacsen-common/emacs-package-remove --prerm <package>
The postinst call must not be made until the package is
completely configured and otherwise ready for use, and the prerm
call must be made before any changes that would make the package
not completely configured and ready for use.
These calls will ensure that the add-on package's emacsen-common
install and remove scripts are called at the appropriate times.
In particular the postinst call will trigger the install script
for every flavor of emacs that's already completely installed.
If flavors are being installed simultaneously, the install script
may be delayed until that flavor's postinst runs.
When the install or remove script is called, the add-on package
can assume that the flavor for which it is being invoked is
completely installed (i.e. past the significant parts of its
postinst).
The install and remove scripts will be invoked with a single
argument, the <flavor> being installed or removed.
So if emacs and xemacs21 flavors are fully installed, installing
add-on foo will result in calls to:
/usr/lib/emacsen-common/packages/install/foo emacs
/usr/lib/emacsen-common/packages/install/foo xemacs21
emacs-package remove does the symmetric thing.
C) Add-on packages need not declare a dependency on any emacs
flavors, but they must declare a dependency on emacsen-common
(see above, and (of course) must declare dependencies on any
other relevant packages, including relevant add-on packages, or
tools needed by the install/remove scripts.
The emacsen-common infrastructure will ensure that the
install/remove script invocations are ordered to respect
inter-add-on package dependencies.
D) Each add-on package has the right to place files into the
following directories:
/etc/<flavor>/site-start.d
/usr/share/<flavor>/site-lisp/<package-name>
E) If an add-on package compiles any of its Emacs Lisp sources
(which must be compiled to a subdirectory of
/usr/share/<flavor>/site-lisp/<package-name> -- see section 4
above), the corresponding .el file must be available in the same
directory as the corresponding .elc file, either directly, via
symlink, or hardlink.
For example, if add-on package foo produces
/usr/share/emacs/site-lisp/foo/bar.elc, then
/usr/share/emacs/site-lisp/foo/bar.el must refer to the
corresponding source file. This ensures that Emacs will be able
to locate the source code for the add-on package when using M-x
find-function, etc.
F) Each emacsen main package (i.e. emacs-lucid, xemacs21, etc.) must
depend on emacsen-common (>= 3.0.0).
G) Each emacsen main package (i.e. emacs-lucid, emacs-nox, etc.)
must make these calls from the given maintainer scripts:
preinst:
/usr/lib/emacsen-common/emacs-install --preinst <flavor>
postinst:
/usr/lib/emacsen-common/emacs-install --postinst <flavor>
prerm:
/usr/lib/emacsen-common/emacs-remove --prerm <flavor>
The postinst call must not be made until the package is
completely configured and ready for use, and the prerm call must
be made before any changes that would make the package not
completely configured and ready for use.
These calls will ensure that all of the relevant add-on packages'
emacsen-common install and remove scripts are called at the
appropriate times. In particular the postinst call may trigger
the install scripts and the prerm script may trigger the remove
scripts for any package that is ready. If add-on packages are
being installed simultaneously, the add-on install scripts may be
delayed until their postinst scripts are run.
6) Mandatory binary path
Each emacsen must be available as /usr/bin/<flavor> in addition to
any normal binary path so that when add-on package install/remove
scripts are called, they can just use /usr/bin/"$1" to get the
right binary for byte-compilation.
7) Virtual package
Each emacsen main package must "Provides: emacsen", and packages
that just need to make sure some flavor of emacs is installed
should "Depends: emacsen". If they depend on specific flavors of
emacs, then they should list those dependencies explicitly instead.
8) Emacs lisp load path.
At a minimum, each emacs must have the following directories in this
relative order in their load path:
/usr/local/share/<flavor>/site-lisp
/usr/share/<flavor>/site-lisp
Emacs add-on packages may not modify load-path directly. They must
use (debian-pkg-add-load-path-item <path>). This function will
make sure that their additions end up in the right place -- before
the emacs system directories, but after the /usr/local/
directories.
9) Usage of autoload instead of load in the site-start.d files.
It's been suggested, and is probably a good idea that maintainers
switch to using autoload rather than load when possible in their
site-start.d files. For example, instead of (load "some-package"),
you should use autoloads for all the top level, user visible
functions.
That's it. Hopefully this gives the add-on package maintainers the
flexibility they need to be able to DTRT, and the common case won't be
all that difficult.
Examples:
1) xemacs21 and the add-on packages tm and auctex are already installed,
and now someone installs emacs23.
In its prerm, emacs23 would make this call:
/usr/lib/emacsen-common/emacs-install --postinst emacs23
which would result in calls to
/usr/lib/emacsen-common/packages/install/auctex emacs23
/usr/lib/emacsen-common/packages/emacs/install/tm emacs23
2) Now, given (1), assume that someone removes xemacs21.
In its prerm, xemacs21 would make this call:
/usr/lib/emacsen-common/emacs-remove --prerm xemacs21
which would result in calls to
/usr/lib/emacsen-common/packages/remove/auctex xemacs21
/usr/lib/emacsen-common/packages/remove/tm xemacs21
3) Now assume emacs23 and xemacs21 are installed, and that someone removes
tm.
The call to emacsen-package-remove in tm's prerm will result in
the following calls:
/usr/lib/emacsen-common/packages/remove/tm emacs23
/usr/lib/emacsen-common/packages/remove/tm xemacs21
In the remove/tm file, tm is responsible for cleaning up any files
it put into its allowed locations:
/etc/<flavor>/site-start.d/
/usr/share/<flavor>/site-lisp/tm
4) Now assume that emacs and auctex are not installed, and that
someone installs both at the same time.
At some point during the installation, after emacs and auctex are
fully configured, this command will be invoked:
/usr/lib/emacsen-common/packages/remove/auctex emacs
This call may happen from either emacs or auctex's postinst as a
result of their respective calls to emacs-install and
emacs-package-install. Which package causes the invocation will
depend on the order in which dpkg decides to invoke their postint
scripts. The emacsen-common infrastructure makes sure that the
last one wins.
5) Finally, please see sample-package-install-foo and
sample-package-remove-foo in /usr/share/doc/emacsen-common/. These
are sample install and remove scripts for a hypothetical package
"foo" that only needs to byte compile a list of files for each
flavor.
|