Please note:The SCons wiki is now restored from the attack in March 2013. All old passwords have been invalidated. Please reset your password if you have an account. If you note missing pages, please report them to webmaster@scons.org. Also, new account creation is currently disabled due to an ongoing spam flood (2013/08/27).
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)