Differences between revisions 9 and 10
Revision 9 as of 2006-09-27 11:31:30
Size: 4619
Editor: gauss
Comment: Changed 'addOptions' to 'AddOptions' as stated in the usag example
Revision 10 as of 2008-03-12 02:47:01
Size: 4619
Editor: localhost
Comment: converted to 1.6 markup
No differences found!

Installer

This page describes a minimal installer which tries to mimic autoconf. It adds the following options to your SConstruct:

  • prefix

  • eprefix

  • bindir

  • libdir

  • includedir

The module

The following code can be saved in a file named installer.py :

   1 """ installer
   2 
   3 This module defines a minimal installer for scons build scripts.  It is aimed
   4 at *nix like systems, but I guess it could easily be adapted to other ones as
   5 well.
   6 """
   7 
   8 import fnmatch, os, os.path
   9 import SCons.Defaults
  10 
  11 PREFIX = "prefix"
  12 EPREFIX = "eprefix"
  13 BINDIR = "bindir"
  14 LIBDIR = "libdir"
  15 INCLUDEDIR = "includedir"
  16 
  17 def AddOptions( opts ):
  18         """ Adds the installer options to the opts.  """
  19         opts.Add( PREFIX, "Directory of architecture independant files.", "/usr" )
  20         opts.Add( EPREFIX, "Directory of architecture dependant files.", "${%s}" % PREFIX )
  21         opts.Add( BINDIR, "Directory of executables.", "${%s}/bin" % EPREFIX )
  22         opts.Add( LIBDIR, "Directory of libraries.", "${%s}/lib" % EPREFIX )
  23         opts.Add( INCLUDEDIR, "Directory of header files.", "${%s}/include" % PREFIX )
  24 
  25 
  26 class Installer:
  27     """ A basic installer. """
  28     def __init__( self, env ):
  29         """ Initialize the installer.
  30 
  31         @param configuration A dictionary containing the configuration.
  32         @param env The installation environment.
  33         """
  34         self._prefix = env.get( PREFIX, "/usr" )
  35         self._eprefix = env.get( EPREFIX, self._prefix )
  36         self._bindir = env.get( BINDIR, os.path.join( self._eprefix, "bin" ) )
  37         self._libdir = env.get( LIBDIR, os.path.join( self._eprefix, "lib" ) )
  38         self._includedir = env.get( INCLUDEDIR, os.path.join( self._prefix, "include" ) )
  39         self._env = env
  40 
  41     def Add( self, destdir, name, basedir="", perm=0644 ):
  42         destination = os.path.join( destdir, basedir )
  43         obj = self._env.Install( destination, name )
  44         self._env.Alias( "install", destination )
  45         for i in obj:
  46             self._env.AddPostAction( i, SCons.Defaults.Chmod( str(i), perm ) )
  47 
  48     def AddProgram( self, program ):
  49         """ Install a program.
  50 
  51         @param program The program to install.
  52         """
  53         self.Add( self._bindir, program, perm=0755 )
  54 
  55     def AddLibrary( self, library ):
  56         """ Install a library.
  57 
  58         @param library the library to install.
  59         """
  60         self.Add( self._libdir, library )
  61 
  62     def AddHeader( self, header, basedir="" ):
  63         self.Add( self._includedir, header, basedir )
  64 
  65     def AddHeaders( self, parent, pattern, basedir="", recursive=False ):
  66         """ Installs a set of headers.
  67 
  68         @param parent The parent directory of the headers.
  69         @param pattern A pattern to identify the files that are headers.
  70         @param basedir The subdirectory in which to install the headers.
  71         @param recursive Search recursively for headers.
  72         """
  73         for entry in os.listdir( parent ):
  74             entrypath = os.path.join( parent, entry )
  75             if os.path.isfile( entrypath ) and fnmatch.fnmatch( entry, pattern ):
  76                 self.AddHeader( entrypath, basedir )
  77             elif os.path.isdir( entrypath ) and recursive:
  78                 self.AddHeaders( entrypath, pattern, os.path.join( basedir, entry ), recursive )

Using the installer

Once the installer.py file is in the SConstruct directory, it can be used like this:

   1 import installer
   2 
   3 env = Environment()
   4 opts = Options( 'options.conf', ARGUMENTS )
   5 # add your custom options here
   6 
   7 # add the installer options
   8 installer.AddOptions( opts )
   9 opts.Update( env )
  10 opts.Save( 'options.conf')
  11 Help( opts.GenerateHelpText( env ) )
  12 
  13 # create the installer
  14 install = installer.Installer( env )
  15 
  16 # adds a program to the installer
  17 program = env.Program( your_program_options )
  18 install.AddProgram( program )
  19 
  20 # adds a library to the installer
  21 lib = env.Library( your_library_options )
  22 install.AddLibrary( lib )
  23 
  24 # adds headers to the installer
  25 install.AddHeaders( "path/to/headers", "*.hpp" )

You can now install your program in a custom location with a call to

scons prefix=/home/sweet/usr install

and you can later uninstall with a call to:

scons -c install

Shortcomings

  • A file named .sconsign is installed and never removed

  • The install path options must not change between install and uninstall
  • Library versions are not handled

Installer (last edited 2008-03-12 02:47:01 by localhost)