- introduced layouts

This commit is contained in:
michel-schinz 2003-12-16 22:16:43 +00:00
parent ebc512096b
commit 19754f5cdf
1 changed files with 237 additions and 161 deletions

View File

@ -75,13 +75,13 @@ package are stored below it.
The unpacking directory contains at least the following files: The unpacking directory contains at least the following files:
- install-pkg install-pkg
a script performing the installation of the package, a script performing the installation of the package,
- README README
a textual file containing a short description of the package, a textual file containing a short description of the package,
- COPYING COPYING
a textual file containing the license of the package. a textual file containing the license of the package.
* Downloading and installation of packages * Downloading and installation of packages
@ -90,102 +90,46 @@ A package can be installed on a target machine by downloading its
archive, expanding it and finally running the installation script archive, expanding it and finally running the installation script
located in the unpacking directory. located in the unpacking directory.
All files belonging to a package will be installed in a single ** Layouts
directory called the "package installation directory". The package
installation directory contains all files, and only files belonging to
the (version of the) package.
Rationale: The installation script installs files according to some given layout.
A layout maps abstract locations to concrete directories on the target
machine. For example, a layout could map the abstract location "doc"
(where documentation is stored) to the directory
"/usr/local/share/doc/my_package".
Such an organisation makes it easy to uninstall package by just Currently, the following abstract locations are defined:
recursively deleting a single directory. It also makes it trivial to
know to which package a given file belongs.
** Root directory layout base
The package installation directory will be an indirect sub-directory The "base" location of a package, where the package loading
of some "package root directory". A package root directory is a script "load.scm" resides.
directory on the target machine which contains all installed packages.
There can be several package roots on a target machine, for example
one for packages installed globally, and one per user for "personal"
packages.
A package root directory contains exactly two sub-directories, and active
nothing else. These directories are called "installed" and "active".
The "installed" directory contains exactly one directory per package, Location containing a symbolic link, with the same name as the
and nothing else (N.B. here "package" really means "package" and not package (without the version), pointing to the "base" location of
"package version"). These directories have the same name as the the package. This link is used to designate the "active" version
package they contain. For every installed version of a package, there of a package, that is the one to load when a package is requested
is a sub-directory of the package directory. These directories are by giving only its name, without explicit version.
named using the printed representation of the version they contain.
The "active" directory contains only symbolic links which point to scheme
package version directories. There is at most one symbolic link per
installed package. These symbolic links identify the active (or
default) version of a package, that is the version will be used if a
script asks for a given package without explicitly which version is
required.
Example: Location containing all Scheme code. If the package comes with
some examples showing its usage, they are put in a sub-directory
called "examples" of this location.
Let's imagine a system on which the directory lib
"/usr/local/lib/scsh/modules" serves as the package root directory. On
this system, versions 1.0 and 2.0 of a package called "package_1" are
installed, the latter being active. Further, version 1.5.4 of a
package called "package_2" is installed and active. The contents of
the package root would look as follows:
/usr/local/lib/scsh/modules/ Location containing platform-dependent libraries.
installed/
package_1/
1.0/
all files belonging to v1.0 of package_1 (and nothing else)
2.0/
all files belonging to v2.0 of package_1
package_2/
1.5.4/
all files belonging to v1.5.4 of package_2
active/
package_1 -> ../installed/package_1/2.0
package_2 -> ../installed/package_2/1.5.4
** Package directory layout doc
Even though the exact contents of the package directory will depend on Location containing all the package documentation. This location
the package, all package directories are laid out according to the contains one or more sub-directories which store the documentation
rules below. These rules make it easy to examine the contents of a in various formats. The contents of these sub-directories is
package directory, and find important data like the package standardised as follows, to make it easy for users to find the
documentation. document they need:
The standard layout is shown below. Some directories are of course
optional because not all packages have something to put in all of
them.
load.scm
Scheme file written in Scheme 48's exec language, whose role is to
define all the structures which belong to a package.
scheme/
Directory containing all the Scheme code of the package.
lib/
Directory containing one sub-directory per platform for which the
package was installed. These sub-directories contain the shared
libraries for the given platform; the name of a given platform is
the one given by autoconf's "config.guess" script.
<platform>/
Directory containing the shared libraries for <platform>.
doc/
Directory containing the documentation of the package, possibly in
different formats.
html/ html/
@ -202,9 +146,85 @@ them.
ps/ ps/
Directory containing the PostScript documentation of the Directory containing the PostScript documentation of the
package, if any; this directory should contain at least one file package, if any; this directory should contain at least one
called "<package>.ps" where "<package>" is the name of the file called "<package>.ps" where "<package>" is the name of
package. the package.
misc-shared
Location containing miscellaneous data which does not belong to
any directory above, and which is platform-independant.
The directories to which a layout maps these abstract locations are
not absolute directories, but rather relative ones. Therefore, a
layout alone is not enough to know where files will end up on the
target machine: a prefix is also required. This prefix is specified on
the command-line during installation, using the "--prefix" option, as
explained below.
Example :
Let's imagine that a user is installing version 1.2 of a package
called "foo". This package contains a file called "COPYING" which has
to be installed in sub-directory "license" of the "doc" location. If
the user chooses to use the default layout, which maps "doc" to
directory "<package_full_name>/doc" (see below), and specifies
"/usr/local/etc/scsh/modules" as a prefix, then the "COPYING" file
will end up in:
/usr/local/etc/scsh/modules/foo-1.2/doc/license/COPYING
\_________________________/ \_________/ \_____________/
1 2 3
Part 1 is the prefix, part 2 is the layout's mapping for the "doc"
location, and part 3 is the file name relative to the location.
*** Predefined layouts
Every installation script comes with a set of predefined layouts
which serve different aims. They are described below.
**** The "scsh" layout
The "scsh" layout is the default layout. It maps all locations to
sub-directories of a single directory, called the package installation
directory, which contains all the files of the package being installed
and nothing else. Its name is simply the full name of the package in
question, and it resides in the "prefix" directory.
The "scsh" layout maps locations as follows:
base -> <prefix>/<package_full_name>
active -> <prefix>
scheme -> <prefix>/<package_full_name>/scheme
lib -> <prefix>/<package_full_name>/lib/<platform>
doc -> <prefix>/<package_full_name>/doc
misc-shared -> <prefix>/<package_full_name>
This layout is well suited for installations performed without the
assistance of an additional package manager, because it makes many
common operations easy. For example, finding to which package a file
belongs is trivial, as is the removal of an installed package.
**** The "fhs" layout
The "fhs" layout maps locations according to the File Hierarchy
Standard (FHS, see ...), as follows:
base -> <prefix>/share/scsh/modules/<package_full_name>
active -> <prefix>/share/scsh/modules
scheme -> <prefix>/share/scsh/modules/<package_full_name>/scheme
lib -> <prefix>/lib/scsh/modules/<package_full_name>
doc -> <prefix>/share/doc/<package_full_name>
misc-shared -> <prefix>/share/scsh/modules/<package_full_name>
The main advantage of this layout is that it adheres to the FHS
standard, and is therefore compatible with several packaging policies,
like Debian's, Fink's and others. Its main drawback is that files
belonging to a given package are scattered, and therefore hard to find
when removing or upgrading a package. Its use should therefore be
considered only if third-party tools are available to track files
belonging to a package.
** File permissions ** File permissions
@ -213,16 +233,19 @@ TODO
** Installation procedure ** Installation procedure
Packages are installed using the "install-pkg" script located in the Packages are installed using the "install-pkg" script located in the
package archive. This script must be given the name of the root package archive. This script must be given the name of the prefix
directory in which to perform installation with the "--root" option. using the "--prefix" option. It also accepts the following options:
It also accepts the following options:
--dry-run or -n --layout <name>
Specifies the layout to use.
--dry-run
Print what actions would be performed to install the package, but Print what actions would be performed to install the package, but
do not perform them. do not perform them.
--inactive or -i --inactive
Do not activate package after installing it. Do not activate package after installing it.
@ -238,8 +261,8 @@ TODO (my current idea is to add support to install-lib to easily
To use a package, its "loading script" must be loaded in Scheme 48's To use a package, its "loading script" must be loaded in Scheme 48's
exec package. The loading script for a package is a file written in exec package. The loading script for a package is a file written in
the Scheme 48 exec language, whose name is "load.scm" and which is the Scheme 48 exec language, whose name is "load.scm" and which
located directly in the package installation directory. resides in the "base" location.
To load this file, one typically uses scsh's "-lel" option along with To load this file, one typically uses scsh's "-lel" option along with
a properly defined SCSH_LIB_DIRS environment variable. a properly defined SCSH_LIB_DIRS environment variable.
@ -251,27 +274,40 @@ configuration, and this value can be overridden by setting the
environment variable SCSH_LIB_DIRS before running scsh. environment variable SCSH_LIB_DIRS before running scsh.
In order for scsh to find the package loading scripts, one must make In order for scsh to find the package loading scripts, one must make
sure that scsh's library search path contains the names of both the sure that scsh's library search path contains the names of all
"installed" and the "active" directories of *every* existing package "active" locations which containing packages.
root directories.
Example:
On a system where the package root directory is
"/usr/local/lib/scsh/modules", the SCSH_LIB_DIRS environment variable
has to contain at least the following two directories:
/usr/local/lib/scsh/modules/active
/usr/local/lib/scsh/modules/installed
The names of these directories should not end with a slash (/), as The names of these directories should not end with a slash (/), as
this forces scsh to search them recursively. This could *drastically* this forces scsh to search them recursively. This could *drastically*
slow down scsh when looking for packages. slow down scsh when looking for packages.
A package named "foo" can then be used from a script provided that the Example:
following option is added to its command line:
-lel foo/load.scm Let's imagine a machine on which the system administrator installs
scsh packages according to the "fhs" layout in prefix directory
"/usr/local". The "active" location for these packages corresponds to
the directory "/usr/local/share/scsh/modules", according to the layout
specification above.
Let's also imagine that there is a user called "john" on this machine,
who installs additional scsh packages for himself in his home
directory, using "/home/john/scsh-packages" as a prefix. To ease their
management, he uses the "scsh" layout. The "active" location for these
packages corresponds to the directory "/home/john/scsh-packages",
according to the layout specification above.
In order to be able to use scsh packages installed both by the
administrator and by himself, user "john" needs to put both active
directories in his SCSH_LIB_DIRS environment variable. The value of
this variable will therefore be:
"/usr/local/share/scsh/modules" "/home/john/scsh-packages"
Now, in order to use packages "foo" and "bar" in one of his script,
user "john" just needs to load their loading script using the -lel
option when invoking scsh, as follows:
-lel foo/load.scm -lel bar/load.scm
* Writing packages * Writing packages
@ -284,26 +320,28 @@ to simplify this task a small scsh installation framework is provided.
This framework is composed of several files which are meant to be This framework is composed of several files which are meant to be
included in the package archive. These files are: included in the package archive. These files are:
- install-pkg install-pkg
a trivial sh script which launches scsh on the main function of a trivial sh script which launches scsh on the main function of
the installation library, passing it all the arguments given by the installation library, passing it all the arguments given by
the user, the user,
- install-lib.scm install-lib.scm
the code for the installation library, whose public interface is
the code for the installation library, documented below, documented below,
- install-lib-module.scm
install-lib-module.scm
Scheme 48 interface and structure definitions for the installation Scheme 48 interface and structure definitions for the installation
library. library,
configure.scm
a Scheme library providing a function to query the name of the
platform, needed by some layouts.
As explained above, when the install-pkg script is invoked, it launches As explained above, when the install-pkg script is invoked, it launches
scsh on the main function of the installation library, which does the scsh on the main function of the installation library, which does the
following: following:
- parse the command line arguments (e.g the --root option), - parse the command line arguments (e.g the --prefix option),
- load the package definition file, a (Scheme) file called - load the package definition file, a (Scheme) file called
"pkg-def.scm", which is supplied by the package author and which "pkg-def.scm", which is supplied by the package author and which
@ -322,81 +360,119 @@ specifies the name, version and installation code for the package. The
package definition statement is expressed using the following syntax package definition statement is expressed using the following syntax
exported from the installation library: exported from the installation library:
(define-package <name> <version> <body> ...) (syntax) (define-package <name> <version> <extensions> <body> ...) (syntax)
Define a package to be installed. NAME is the package name (a Define a package to be installed. NAME is the package name (a
string), VERSION its version (a list of integers) and BODY is the string), VERSION its version (a list of integers), EXTENSIONS is an
list of statements to be evaluated in order to install the package. association list of extensions, and BODY is the list of statements
to be evaluated in order to install the package.
The installation statements typically use functions of the The installation statements typically use functions of the
installation library in order to install files in their target installation library in order to install files in their target
location. The following functions are currently exported: location. The following functions are currently exported:
(install-file <file> [<target-dir>] [<perms>]) (install-file <file> <location> [<target-dir>] [<perms>])
Install the given file in TARGET-DIR. TARGET-DIR is specified Install the given FILE in the sub-directory TARGET-DIR (which must
relative to the package directory, and defaults to "." (i.e. the be a relative directory) of the given LOCATION.
package directory itself). If the target directory does not exist,
it is created along with all its parents, as needed. If the directory in which the file is about to be installed does not
exist, it is created along with all its parents, as needed. If FILE
is a string, then the installed file will have the same name as the
original one. If FILE is a pair, then its first element specifies
the name of the source file, and its second element the name it will
have once installed. The second element must be a simple file name,
without any directory part.
The copied file and all directories created by this command have The copied file and all directories created by this command have
their permissions set to PERMS, an integer which defaults to #o755 their permissions set to PERMS, an integer which defaults to #o755
(i.e. read, write and execute for the owner, read and execute for (i.e. read, write and execute for the owner, read and execute for
the rest). the rest).
(install-files <file-list> [<target-dir>] [<perms>]) (install-files <file-list> <location> [<target-dir>] [<perms>])
Like install-file but for several files, which are specified as a Like install-file but for several files, which are specified as a
list. list. Each element in the list can be either a simple string or a
pair, as explained above.
(install-directory <dir> [<target-dir>] [<perms>]) (install-directory <dir> <location> [<target-dir>] [<perms>])
Install the given directory and all its contents, including Install the given DIRectory and all its contents, including
sub-directories, in TARGET-DIR. This is similar to what INSTALL-FILE sub-directories, in sub-directory TARGET-DIR of LOCATION. This is
does, but for complete hierarchies. similar to what INSTALL-FILE does, but for complete hierarchies.
Notice that DIR will be installed as a sub-directory of TARGET-DIR. Notice that DIR will be installed as a sub-directory of TARGET-DIR.
(install-directories <dir-list> [<target-dir>] [<perms>]) (install-directories <dir-list> <location> [<target-dir>] [<perms>])
Install several directories in one go. Install several directories in one go.
(install-directory-contents <dir> <location> [<target-dir>] [<perms>])
Install the *contents* of the given DIRectory in sub-directory
TARGET of LOCATION.
An additional function exists to query the mapping of a location:
(get-directory <location> <install?>)
Get the absolute name of the directory to which the current layout
maps the abstract LOCATION. If INSTALL? is true, the directory is
the one valid during installation; If it is false, the directory is
the one valid after installation, that is when the package is later
used.
The distinction between installation-time and usage-time directories
is necessary to support staged installation, as performed by package
managers like Debian's APT.
Example: Example:
A typical package definition file for a simple package called A typical package definition file for a simple package called
"my_package" whose version is 1.2 could look like this: "my_package" whose version is 1.2 could look like this:
(define-package "my_package" (1 2) (define-package "my_package" (1 2)
(install-file "load.scm") (install-file "load.scm" 'base)
(install-directories '("scheme" "doc"))) (install-directory-contents "scheme" 'scheme)
(install-file ("LICENSE" . "COPYING") 'doc)
(install-directory-contents "doc" 'doc))
With such a definition, invoking the installation script with With such a definition, invoking the installation script with
"/usr/local/lib/scsh/modules" as package root would have the "/usr/local/" as prefix and "fhs" as layout would have the following
following effects: effects:
1. The package directory 1. The base directory
/usr/local/lib/scsh/modules/installed/my_package/1.2 /usr/local/share/scsh/modules/my_package-1.2
would be created. would be created and file "load.scm" would be copied to it.
2. File "load.scm" would be copied to this directory.
3. All the contents of the directory called "scheme" would be copied 3. All the contents of the directory called "scheme" would be copied
to directory to directory
/usr/local/lib/scsh/modules/installed/my_package/1.2/scheme /usr/local/share/scsh/modules/my_package-1.2/scheme
The same would happen for the contents of directory "doc". which would be created before, if needed.
4. The package would be activated by creating a symbolic link with 4. File "LICENSE" would be copied to directory
/usr/local/share/doc/my_package-1.2/
with name "COPYING".
5. All the contents of the directory called "doc" would be copied to
directory
/usr/local/share/doc/my_package-1.2/
6. The package would be activated by creating a symbolic link with
name name
/usr/local/lib/scsh/modules/active/my_package /usr/local/share/scsh/modules/my_package
pointing to pointing to
../installed/my_package/1.2 ./my_package-1.2
** Packages containing C code (for shared libraries) ** Packages containing C code (for shared libraries)
@ -424,13 +500,13 @@ installation script described above to install scsh packages. This
script currently provides some support for staged installations, script currently provides some support for staged installations,
which are required by several packaging systems. which are required by several packaging systems.
This support is provided through an additional option, --dest-root, This support is provided through an additional option,
which specifies the package root in which the files have to be copied --install-prefix, which specifies the prefix in which the files have
by the installation script. The files will then have to be moved from to be copied by the installation script. The files will then have to
this location to their final root directory, i.e. the one given be moved from this location to their final prefix directory, i.e. the
through the --root option, by the system packaging tools. one given through the --prefix option, by the system packaging tools.
(The --dest-root option plays the same role as the DEST_DIR (The --install-prefix option plays the same role as the DEST_DIR
variable which is typically given to "make install", for makefiles variable which is typically given to "make install", for makefiles
which support staging directories). which support staging directories).
@ -446,12 +522,12 @@ Package
(Package) unpacking directory (Package) unpacking directory
(Packages) root directory Layout
(Package) installation directory (Abstract) location
Package loading script Package loading script
* Version * Version
$Id: proposal.txt,v 1.1 2003/12/14 12:14:21 michel-schinz Exp $ $Id: proposal.txt,v 1.2 2003/12/16 22:16:43 michel-schinz Exp $