]> git.donarmstrong.com Git - lilypond.git/blobdiff - SConstruct
* make/stepmake.make: include toplevel-version.make after config.make.
[lilypond.git] / SConstruct
index 4e5640dff2df81bc1c9112459e74cdcbc1643a22..9e7c40b1034e86f96d75b518ae791e7633fe1164 100644 (file)
@@ -22,9 +22,9 @@ Run from build tree
     PATH=$run/bin:$PATH
 
     #optionally, if you do not use custom.py below
     PATH=$run/bin:$PATH
 
     #optionally, if you do not use custom.py below
-    #export LILYPONDPREFIX=$run/share/lilypond
+    #export LILYPONDPREFIX=$run/share/lilypond/<VERSION>
 
 
-    lilypond-bin input/simple
+    lilypond input/simple
 
 Other targets
     scons mf-essential         # build minimal mf stuff
 
 Other targets
     scons mf-essential         # build minimal mf stuff
@@ -60,9 +60,20 @@ prefix=os.path.join (os.environ['HOME'], 'usr', 'pkg', 'lilypond')
 
 
 # TODO:
 
 
 # TODO:
-#  * usability
 
 
-#  * more program configure tests (mfont, ...?)
+#  * reality check:
+#     - too many stages in Environments setup
+#       (see also buildscripts/builders.py)
+#     - Home-brew scons.cach configuration caching
+#     - Home-brew source tarball generating -- [why] isn't that in SCons?
+
+#  * usability and documentation for "./configure; make" users
+
+#  * too much cruft in toplevel SConstruct
+
+#  * (optional) operation without CVS directories, from tarball
+
+#  * more program configure tests, actually use full executable name
 
 #  * install doc
 
 
 #  * install doc
 
@@ -70,6 +81,7 @@ prefix=os.path.join (os.environ['HOME'], 'usr', 'pkg', 'lilypond')
 
 #  * grep FIXME $(find . -name 'S*t')
 
 
 #  * grep FIXME $(find . -name 'S*t')
 
+#  * drop "fast"
 
 import re
 import glob
 
 import re
 import glob
@@ -83,28 +95,49 @@ import shutil
 EnsureSConsVersion (0, 95)
 
 usage = r'''Usage:
 EnsureSConsVersion (0, 95)
 
 usage = r'''Usage:
-scons [KEY=VALUE].. [TARGET|DIR]..
+[ENVVAR=VALUE]... scons [OPTION=VALUE]... [TARGET|DIR]...
 
 TARGETS: clean, config, doc, dist, install, mf-essential, po-update,
          realclean, release, sconsclean, tar, TAGS
 
 
 TARGETS: clean, config, doc, dist, install, mf-essential, po-update,
          realclean, release, sconsclean, tar, TAGS
 
+ENVVARS: BASH, CCFLAGS, CC, CXX, LIBS, PYTHON, SH...
+         (see SConstruct:config_vars)
+
+OPTIONS:
 '''
       
 
 config_cache = 'scons.cache'
 '''
       
 
 config_cache = 'scons.cache'
+if os.path.exists (config_cache) and 'config' in COMMAND_LINE_TARGETS:
+       os.unlink (config_cache)
 
 
+# All config_vars can be set as ENVVAR, eg:
+#
+#    CXX=g++-4.0 GS=~/usr/pkg/gs/bin/gs scons config
+#
+# append test_program variables automagically?
 config_vars = [
        'BASH',
 config_vars = [
        'BASH',
+       'BYTEORDER',
+       'CC',
        'CCFLAGS',
        'CPPPATH',
        'CPPDEFINES',
        'CCFLAGS',
        'CPPPATH',
        'CPPDEFINES',
+       'CXX',
        'CXXFLAGS',
        'DEFINES',
        'CXXFLAGS',
        'DEFINES',
+       'DVIPS',
+       'FONTFORGE',
+       'GCC',
+       'GXX',
+       'GS',
        'LIBS',
        'LINKFLAGS',
        'LIBS',
        'LINKFLAGS',
-       'METAFONT',
+       'MF',
+       'MFTRACE',
        'PERL',
        'PYTHON',
        'PERL',
        'PYTHON',
+       'SH',
        ]
 
 # Put your favourite stuff in custom.py
        ]
 
 # Put your favourite stuff in custom.py
@@ -131,7 +164,7 @@ opts.AddOptions (
        BoolOption ('checksums', 'use checksums instead of timestamps',
                    0),
        BoolOption ('fast', 'use timestamps, implicit cache, prune CPPPATH',
        BoolOption ('checksums', 'use checksums instead of timestamps',
                    0),
        BoolOption ('fast', 'use timestamps, implicit cache, prune CPPPATH',
-                   1),
+                   0),
        )
 
 srcdir = Dir ('.').srcnode ().abspath
        )
 
 srcdir = Dir ('.').srcnode ().abspath
@@ -142,18 +175,16 @@ package = packagepython.Package (srcdir)
 version = packagepython.version_tuple_to_str (package.version)
 
 ENV = { 'PATH' : os.environ['PATH'] }
 version = packagepython.version_tuple_to_str (package.version)
 
 ENV = { 'PATH' : os.environ['PATH'] }
-for key in ['LD_LIBRARY_PATH', 'GUILE_LOAD_PATH', 'PKG_CONFIG_PATH']:
+for key in ['LD_LIBRARY_PATH', 'GUILE_LOAD_PATH', 'PKG_CONFIG_PATH', 'TEXMF']:
        if os.environ.has_key (key):
                ENV[key] = os.environ[key]
 
 env = Environment (
        ENV = ENV,
        if os.environ.has_key (key):
                ENV[key] = os.environ[key]
 
 env = Environment (
        ENV = ENV,
-
-       BASH = '/bin/bash',
-       PERL = '/usr/bin/perl',
-       PYTHON = '/usr/bin/python',
-       SH = '/bin/sh',
-
+       BYTEORDER = sys.byteorder.upper (),
+       CC = '$GCC',
+       CXX = '$GXX',
+       CPPDEFINES = '-DHAVE_CONFIG_H',
        MAKEINFO = 'LANG= makeinfo',
        MF_TO_TABLE_PY = srcdir + '/buildscripts/mf-to-table.py',
        
        MAKEINFO = 'LANG= makeinfo',
        MF_TO_TABLE_PY = srcdir + '/buildscripts/mf-to-table.py',
        
@@ -166,14 +197,17 @@ env = Environment (
        TOPLEVEL_VERSION = version,
        )
 
        TOPLEVEL_VERSION = version,
        )
 
+Help (usage + opts.GenerateHelpText (env))
+
 # Add all config_vars to opts, so that they will be read and saved
 # together with the other configure options.
 map (lambda x: opts.AddOptions ((x,)), config_vars)
 # Add all config_vars to opts, so that they will be read and saved
 # together with the other configure options.
 map (lambda x: opts.AddOptions ((x,)), config_vars)
-
-Help (usage + opts.GenerateHelpText (env))
-
 opts.Update (env)
 
 opts.Update (env)
 
+for key in config_vars:
+       if os.environ.has_key (key):
+               env[key] = os.environ[key]
+
 if env['fast']:
        # Usability switch (Anthony Roach).
        # See http://www.scons.org/cgi-bin/wiki/GoFastButton
 if env['fast']:
        # Usability switch (Anthony Roach).
        # See http://www.scons.org/cgi-bin/wiki/GoFastButton
@@ -201,10 +235,10 @@ env.Alias ('config', config_cache)
 
 cachedir = os.path.join (outdir, 'build-cache')
 
 
 cachedir = os.path.join (outdir, 'build-cache')
 
-if not os.path.exists(cachedir):
-       os.makedirs(cachedir)
+if not os.path.exists (cachedir):
+       os.makedirs (cachedir)
 
 
-CacheDir (os.path.join (outdir, 'build-cache'))
+CacheDir (cachedir)
 
 # No need to set $LILYPONDPREFIX to run lily, but cannot install...
 if env['debugging'] and not 'install' in COMMAND_LINE_TARGETS:
 
 # No need to set $LILYPONDPREFIX to run lily, but cannot install...
 if env['debugging'] and not 'install' in COMMAND_LINE_TARGETS:
@@ -214,6 +248,8 @@ prefix = env['prefix']
 bindir = os.path.join (prefix, 'bin')
 sharedir = os.path.join (prefix, 'share')
 libdir = os.path.join (prefix, 'lib')
 bindir = os.path.join (prefix, 'bin')
 sharedir = os.path.join (prefix, 'share')
 libdir = os.path.join (prefix, 'lib')
+libdir_package = os.path.join (libdir, package.name)
+lidbir_package_version = os.path.join (libdir_package, version)
 localedir = os.path.join (sharedir, 'locale')
 sharedir_doc_package = os.path.join (sharedir, 'doc', package.name)
 sharedir_package = os.path.join (sharedir, package.name)
 localedir = os.path.join (sharedir, 'locale')
 sharedir_doc_package = os.path.join (sharedir, 'doc', package.name)
 sharedir_package = os.path.join (sharedir, package.name)
@@ -234,64 +270,104 @@ def list_sort (lst):
 
 
 def configure (target, source, env):
 
 
 def configure (target, source, env):
-       vre = re.compile ('^.*[^-.0-9]([0-9][0-9]*\.[0-9][.0-9]*).*$', re.DOTALL)
+       vre = re.compile ('^.*[^-.0-9]([0-9][0-9]*\.[0-9]([.0-9]*[0-9])*).*$',
+                         re.DOTALL)
        def get_version (program):
        def get_version (program):
-               command = '(%(program)s --version || %(program)s -V) 2>&1' % vars ()
+               command = '(pkg-config --modversion %(program)s || %(program)s --version || %(program)s -V) 2>&1' % vars ()
                pipe = os.popen (command)
                output = pipe.read ()
                if pipe.close ():
                        return None
                v = re.sub (vre, '\\1', output)
                pipe = os.popen (command)
                output = pipe.read ()
                if pipe.close ():
                        return None
                v = re.sub (vre, '\\1', output)
+               if v[-1] == '\n':
+                       v = v[:-1]
                return string.split (v, '.')
 
                return string.split (v, '.')
 
-       def test_program (lst, program, minimal, description, package):
+       def test_version (lst, full_name, minimal, description, package):
+               program = os.path.basename (full_name)
                sys.stdout.write ('Checking %s version... ' % program)
                actual = get_version (program)
                if not actual:
                        print 'not found'
                        lst.append ((description, package, minimal, program,
                                     'not installed'))
                sys.stdout.write ('Checking %s version... ' % program)
                actual = get_version (program)
                if not actual:
                        print 'not found'
                        lst.append ((description, package, minimal, program,
                                     'not installed'))
-                       return
-               sys.stdout.write (string.join (actual, '.'))
-               sys.stdout.write ('\n')
-               if actual < string.split (minimal, '.'):
+                       return 0
+               print string.join (actual, '.')
+               if map (string.atoi, actual) \
+                  < map (string.atoi, string.split (minimal, '.')):
                        lst.append ((description, package, minimal, program,
                                     string.join (actual, '.')))
                        lst.append ((description, package, minimal, program,
                                     string.join (actual, '.')))
+                       return 0
+               return 1
 
 
-       for i in ['bash', 'perl', 'python', 'sh']:
-               sys.stdout.write ('Checking for %s... ' % i)
-               c = WhereIs (i)
-               key = string.upper (i)
-               if c:
-                       env[key] = c
-                       sys.stdout.write (c)
+       def test_program (lst, program, minimal, description, package):
+               key = program.upper ()
+               if key.find ('+-'):
+                       key = re.sub ('\+', 'X', key)
+                       key = re.sub ('-', '_', key)
+               sys.stdout.write ('Checking for %s ... ' % program)
+               if env.has_key (key):
+                       f = env[key]
+                       sys.stdout.write ('(cached) ')
                else:
                else:
-                       sys.stdout.write ('not found: %s (using: %s)' \
-                                         % (c, env[key]))
-                       # Hmm? abort?
-               sys.stdout.write ('\n')
+                       f = WhereIs (program)
+                       env[key] = f
+               if not f:
+                       print 'not found'
+                       lst.append ((description, package, minimal, program,
+                                    'not installed'))
+                       return 0
+               print f
+               return test_version (lst, program, minimal, description, package)
+
+       def test_lib (lst, program, minimal, description, package):
+               # FIXME: test for Debian or RPM (or -foo?) based dists
+               # to guess (or get correct!: apt-cache search?)
+               # package name.
+               #if os.system ('pkg-config --atleast-version=0 freetype2'):
+               # barf
+               if test_version (lst, program, minimal, description,
+                                'lib%(package)s-dev or %(package)s-devel'
+                                % vars ()):
+                       env.ParseConfig ('pkg-config --cflags --libs %(program)s'
+                                        % vars ())
+                       return 1
+               return 0
 
        required = []
 
        required = []
+       test_program (required, 'bash', '2.0', 'Bash', 'bash')
        test_program (required, 'gcc', '2.8', 'GNU C compiler', 'gcc')
        test_program (required, 'g++', '3.0.5', 'GNU C++ compiler', 'g++')
        test_program (required, 'gcc', '2.8', 'GNU C compiler', 'gcc')
        test_program (required, 'g++', '3.0.5', 'GNU C++ compiler', 'g++')
-       test_program (required, 'python', '2.1', 'Python (www.python.org)', 'python')
        test_program (required, 'guile-config', '1.6', 'GUILE development',
                        'libguile-dev or guile-devel')
        test_program (required, 'guile-config', '1.6', 'GUILE development',
                        'libguile-dev or guile-devel')
-       # Do not use bison 1.50 and 1.75.
-       test_program (required, 'bison', '1.25', 'Bison -- parser generator',
-                       'bison')
-       test_program (required, 'flex', '0.0', 'Flex -- lexer generator', 'flex')
-
+       test_program (required, 'mf', '0.0', 'Metafont', 'tetex-bin')
+       test_program (required, 'mftrace', '1.1.9',
+                     'mftrace (http://xs4all.nl/~hanwen/mftrace)', 'mftrace')
+       test_program (required, 'potrace', '0.0', 'Potrace', 'potrace')
+       test_program (required, 'python', '2.1', 'Python (www.python.org)',
+                     'python')
+       test_program (required, 'sh', '0.0', 'Bourne shell', 'sh')
 
        optional = []
 
        optional = []
-       test_program (optional, 'makeinfo', '4.7', 'Makeinfo tool', 'texinfo')
-       test_program (optional, 'guile', '1.6', 'GUILE scheme',
-                       'libguile-dev or guile-devel')
-       test_program (optional, 'mftrace', '1.0.27', 'Metafont tracing Type1',
+       # Do not use bison 1.50 and 1.75.
+       #test_program (optional, 'foo', '2.0', 'Foomatic tester', 'bar')
+       test_program (optional, 'bison', '1.25', 'Bison -- parser generator',
+                       'bison')
+       test_program (optional, 'dvips', '0.0', 'Dvips', 'tetex-bin')
+       test_program (optional, 'fontforge', '0.0.20041224', 'FontForge',
+                     'fontforge')
+       test_program (optional, 'flex', '0.0', 'Flex -- lexer generator',
+                     'flex')
+       test_program (optional, 'guile', '1.6', 'GUILE scheme', 'guile')
+       test_program (optional, 'gs', '8.14',
+                     'Ghostscript PostScript interpreter',
+                     'gs or gs-afpl or gs-esp or gs-gpl')
+       test_program (optional, 'mftrace', '1.1.0', 'Metafont tracing Type1',
                        'mftrace')
                        'mftrace')
+       test_program (optional, 'makeinfo', '4.7', 'Makeinfo tool', 'texinfo')
        test_program (optional, 'perl', '4.0',
        test_program (optional, 'perl', '4.0',
-                       'Perl practical efficient readonly language', 'perl')
-       #test_program (optional, 'foo', '2.0', 'Foomatic tester', 'bar')
+                     'Perl practical efficient readonly language', 'perl')
+       #test_program (optional, 'ps2pdf', '0.0', 'Ps2pdf', 'gs')
 
        def CheckYYCurrentBuffer (context):
                context.Message ('Checking for yy_current_buffer... ')
 
        def CheckYYCurrentBuffer (context):
                context.Message ('Checking for yy_current_buffer... ')
@@ -308,29 +384,65 @@ def configure (target, source, env):
                context.Result (ret)
                return ret
 
                context.Result (ret)
                return ret
 
+       def CheckLibkpathseaSo (context):
+               saveCFLAGS = []
+               if context.env.has_key ('CFLAGS'):
+                       saveCFLAGS = context.env['CFLAGS']
+               CFLAGS_shared_no_debugging = filter (lambda x: x != '-g',
+                                                    saveCFLAGS)\
+                                                    + ['-shared']
+               # FIXME: how does this work, with scons
+               context.env.Replace (CFLAGS = CFLAGS_shared_no_debugging)
+               #context.env.Replace (CFLAGS = '')
+               #context.env.Append (CFLAGS = ['-shared'])
+               context.Message ('Checking for libkpathsea... ')
+               ret = conf.TryLink ('''#include <kpathsea/kpathsea.h>
+               int main ()
+               {
+               kpse_var_expand ("\$TEXMF");
+               return 0;
+               }
+               ''', '.c')
+               context.env.Replace (CFLAGS = saveCFLAGS)
+               # FIXME: this prints 'ok' already
+               context.Result (ret)
+               if not ret:
+                       return 0
+               
+               sys.stdout.write ('Checking for libkpathsea.so... ')
+               testfile = str (context.sconf.lastTarget)
+               shared_size = os.path.getsize (testfile)
+               ret = shared_size < 40000
+               if ret:
+                       print 'ok'
+               else:
+                       print 'no'
+               return ret
+
        conf = Configure (env, custom_tests = { 'CheckYYCurrentBuffer'
        conf = Configure (env, custom_tests = { 'CheckYYCurrentBuffer'
-                                               : CheckYYCurrentBuffer })
+                                               : CheckYYCurrentBuffer,
+                                               'CheckLibkpathseaSo'
+                                               : CheckLibkpathseaSo })
 
        defines = {
           'DIRSEP' : "'%s'" % os.sep,
           'PATHSEP' : "'%s'" % os.pathsep,
 
        defines = {
           'DIRSEP' : "'%s'" % os.sep,
           'PATHSEP' : "'%s'" % os.pathsep,
-          'TOPLEVEL_VERSION' : '"' + version + '"',
-          'PACKAGE': '"' + package.name + '"',
-          'DATADIR' : '"' + sharedir + '"',
-          'LILYPOND_DATADIR' : '"' + sharedir_package + '"',
-          'LOCAL_LILYPOND_DATADIR' : '"' + sharedir_package_version + '"',
-          'LOCALEDIR' : '"' + localedir + '"',
+          'PACKAGE': '"%s"' % package.name,
+          'DATADIR' : '"%s"' % sharedir,
+          'PACKAGE_DATADIR' : '"%s"' % sharedir_package,
+          'LOCALEDIR' : '"%s"' %localedir,
        }
        conf.env.Append (DEFINES = defines)
 
        command = r"""python -c 'import sys; sys.stdout.write ("%s/include/python%s" % (sys.prefix, sys.version[:3]))'""" #"
        }
        conf.env.Append (DEFINES = defines)
 
        command = r"""python -c 'import sys; sys.stdout.write ("%s/include/python%s" % (sys.prefix, sys.version[:3]))'""" #"
-       PYTHON_INCLUDE = os.popen (command).read ()
+       PYTHON_INCLUDE = os.popen (command).read ()#[:-1]
        if env['fast']:
        if env['fast']:
-               env.Append (CCFLAGS = ['-I%s ' % PYTHON_INCLUDE])
+               env.Append (CCFLAGS = ['-I%s' % PYTHON_INCLUDE])
        else:
        else:
-               env.Append (CPPPATH = PYTHON_INCLUDE)
+               env.Append (CPPPATH = [PYTHON_INCLUDE])
 
 
-       headers = ('sys/stat.h', 'assert.h', 'kpathsea/kpathsea.h', 'Python.h')
+       headers = ('sys/stat.h', 'assert.h', 'kpathsea/kpathsea.h', 'libio.h',
+                  'Python.h')
        for i in headers:
                if conf.CheckCHeader (i):
                        key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
        for i in headers:
                if conf.CheckCHeader (i):
                        key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
@@ -342,7 +454,8 @@ def configure (target, source, env):
                        key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
                        conf.env['DEFINES'][key] = 1
 
                        key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
                        conf.env['DEFINES'][key] = 1
 
-       functions = ('gettext', 'isinf', 'memmem', 'snprintf', 'vsnprintf')
+       functions = ('fopencookie', 'funopen',
+                    'gettext', 'isinf', 'memmem', 'snprintf', 'vsnprintf')
        for i in functions:
                if 0 or conf.CheckFunc (i):
                        key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
        for i in functions:
                if 0 or conf.CheckFunc (i):
                        key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
@@ -351,6 +464,9 @@ def configure (target, source, env):
        if conf.CheckYYCurrentBuffer ():
                conf.env['DEFINES']['HAVE_FLEXLEXER_YY_CURRENT_BUFFER'] = 1
 
        if conf.CheckYYCurrentBuffer ():
                conf.env['DEFINES']['HAVE_FLEXLEXER_YY_CURRENT_BUFFER'] = 1
 
+       if conf.CheckLibkpathseaSo ():
+               conf.env['DEFINES']['HAVE_LIBKPATHSEA_SO'] = '1'
+
        if conf.CheckLib ('dl'):
                pass
 
        if conf.CheckLib ('dl'):
                pass
 
@@ -372,18 +488,33 @@ def configure (target, source, env):
        #this could happen after flower...
        env.ParseConfig ('guile-config compile')
 
        #this could happen after flower...
        env.ParseConfig ('guile-config compile')
 
+       test_program (required, 'pkg-config', '0.9.0',
+                     'pkg-config library compile manager', 'pkg-config')
+       if test_lib (required, 'freetype2', '0.0',
+                    'Development files for FreeType 2 font engine',
+                    'freetype6'):
+               conf.env['DEFINES']['HAVE_FREETYPE2'] = '1'
+               
+       if test_lib (required, 'pangoft2', '1.6.0',
+                    'Development files for pango, with FreeType2',
+                    'pango1.0'):
+               conf.env['DEFINES']['HAVE_PANGO_FT2'] = '1'
+               conf.env['DEFINES']['HAVE_PANGO16'] = '1'
+
+       if test_lib (optional, 'fontconfig', '2.2.0',
+                    'Development files for fontconfig', 'fontconfig1'):
+               conf.env['DEFINES']['HAVE_FONTCONFIG'] = '1'
+       
        #this could happen only for compiling pango-*
        if env['gui']:
        #this could happen only for compiling pango-*
        if env['gui']:
-               env.ParseConfig ('pkg-config --cflags --libs gtk+-2.0')
-               env.ParseConfig ('pkg-config --cflags --libs pango')
+               test_lib (required, 'gtk+-2.0', '2.4.0',
+                         'Development files for GTK+', 'gtk2.0')
+               if test_lib (required, 'pango', '1.6.0',
+                         'Development files for pango', 'pango1.0'):
+                       conf.env['DEFINES']['HAVE_PANGO16'] = '1'
+                       
                if conf.CheckCHeader ('pango/pangofc-fontmap.h'):
                        conf.env['DEFINES']['HAVE_PANGO_PANGOFC_FONTMAP_H'] = '1'
                if conf.CheckCHeader ('pango/pangofc-fontmap.h'):
                        conf.env['DEFINES']['HAVE_PANGO_PANGOFC_FONTMAP_H'] = '1'
-
-               if conf.CheckLib ('pango-1.0',
-                                 'pango_fc_font_map_add_decoder_find_func'):
-                       conf.env['DEFINES']['HAVE_PANGO_CVS'] = '1'
-                       conf.env['DEFINES']['HAVE_PANGO_FC_FONT_MAP_ADD_DECODER_FIND_FUNC'] = '1'
-
        if env['fast']:
                # Using CCFLAGS = -I<system-dir> rather than CPPPATH = [
                # <system-dir>] speeds up SCons
        if env['fast']:
                # Using CCFLAGS = -I<system-dir> rather than CPPPATH = [
                # <system-dir>] speeds up SCons
@@ -452,10 +583,22 @@ def save_config_cache (env):
                sys.stdout.write ('\n')
                sys.stdout.write ('LilyPond configured')
                sys.stdout.write ('\n')
                sys.stdout.write ('\n')
                sys.stdout.write ('LilyPond configured')
                sys.stdout.write ('\n')
-               sys.stdout.write ('now run')
+               sys.stdout.write ('Now run')
                sys.stdout.write ('\n')
                sys.stdout.write ('    scons [TARGET|DIR]...')
                sys.stdout.write ('\n')
                sys.stdout.write ('\n')
                sys.stdout.write ('    scons [TARGET|DIR]...')
                sys.stdout.write ('\n')
+               sys.stdout.write ('\n')
+               sys.stdout.write ('Examples:')
+               sys.stdout.write ('\n')
+               sys.stdout.write ('    scons lily    # build lilypond')
+               sys.stdout.write ('\n')
+               sys.stdout.write ('    scons all     # build everything')
+               sys.stdout.write ('\n')
+               sys.stdout.write ('    scons doc     # build documentation')
+               sys.stdout.write ('\n')
+               ## TODO
+               ## sys.stdout.write ('    scons prefix=/usr DESTDIR=/tmp/pkg all install')
+               ## sys.stdout.write ('\n')
                Exit (0)
        elif not env['checksums']:
                # When using timestams, config.hh is NEW.  The next
                Exit (0)
        elif not env['checksums']:
                # When using timestams, config.hh is NEW.  The next
@@ -468,9 +611,6 @@ def save_config_cache (env):
                s = os.system (command)
                Exit (s)
 
                s = os.system (command)
                Exit (s)
 
-
-if os.path.exists (config_cache) and 'config' in COMMAND_LINE_TARGETS:
-       os.unlink (config_cache)
 # WTF?
 # scons: *** Calling Configure from Builders is not supported.
 # env.Command (config_cache, None, configure)
 # WTF?
 # scons: *** Calling Configure from Builders is not supported.
 # env.Command (config_cache, None, configure)
@@ -490,18 +630,21 @@ SConscript ('buildscripts/builder.py')
 env.PrependENVPath ('PATH',
                    os.path.join (env['absbuild'], env['out'], 'usr/bin'))
 
 env.PrependENVPath ('PATH',
                    os.path.join (env['absbuild'], env['out'], 'usr/bin'))
 
-if os.environ.has_key ('TEXMF'):
-       env.Append (ENV = {'TEXMF' : os.environ['TEXMF']})
+LILYPONDPREFIX = os.path.join (run_prefix, 'share/lilypond/', version)
+
 env.Append (ENV = {
 env.Append (ENV = {
-       'TEXMF' : '{$LILYPONDPREFIX,' \
+       #'LILYPONDPREFIX' : os.path.join (run_prefix, 'share/lilypond/', version),
+       'LILYPONDPREFIX' : LILYPONDPREFIX,
+       # ugh, can't use LILYPONDPREFIX here
+       #'TEXMF' : '{' + os.path.join (run_prefix, 'share/lilypond/', version)\
+       #+ ',' \
+       'TEXMF' : '{$LILYPONDPREFIX,'
        + os.popen ('kpsexpand \$TEXMF').read ()[:-1] + '}',
        + os.popen ('kpsexpand \$TEXMF').read ()[:-1] + '}',
-       'LILYPONDPREFIX' : os.path.join (run_prefix, 'share/lilypond'),
        })
 
 BUILD_ABC2LY = '${set__x}$PYTHON $srcdir/scripts/abc2ly.py'
        })
 
 BUILD_ABC2LY = '${set__x}$PYTHON $srcdir/scripts/abc2ly.py'
-BUILD_LILYPOND = '${set__x}$PYTHON $srcdir/scripts/lilypond.py${__verbose}'
-BUILD_LILYPOND_BIN = '$absbuild/$out/lilypond-bin ${__verbose}'
-BUILD_LILYPOND_BOOK = '$PYTHON $srcdir/scripts/lilypond-book.py --verbose'
+BUILD_LILYPOND = '$absbuild/lily/$out/lilypond ${__verbose}'
+BUILD_LILYPOND_BOOK = '$PYTHON $srcdir/scripts/lilypond-book.py ${__verbose}'
 
 
 # post-option environment-update
 
 
 # post-option environment-update
@@ -516,23 +659,28 @@ env.Append (
        sharedir_doc_package = sharedir_doc_package,
        sharedir_package_version = sharedir_package_version,
 
        sharedir_doc_package = sharedir_doc_package,
        sharedir_package_version = sharedir_package_version,
 
+       # global build verbosity switch
+       __verbose = ' --verbose',
+       
        LILYPOND = BUILD_LILYPOND,
        ABC2LY = BUILD_ABC2LY,
        LILYPOND_BOOK = BUILD_LILYPOND_BOOK,
        LILYPOND_BOOK_FORMAT = 'texi-html',
        MAKEINFO_FLAGS = '--css-include=$srcdir/Documentation/texinfo.css',
        LILYPOND = BUILD_LILYPOND,
        ABC2LY = BUILD_ABC2LY,
        LILYPOND_BOOK = BUILD_LILYPOND_BOOK,
        LILYPOND_BOOK_FORMAT = 'texi-html',
        MAKEINFO_FLAGS = '--css-include=$srcdir/Documentation/texinfo.css',
-
+       # should not be necessary
+       # PYTHONPATH = ['$absbuild/python/$out'],
        TEXI2DVI_PAPERSIZE = '@afourpaper',
        TEXI2DVI_PAPERSIZE = '@afourpaper',
-       TEXI2DVI_FLAGS = [ '-t $TEXI2DVI_PAPERSIZE'],
+       TEXI2DVI_FLAGS = [ '-t$TEXI2DVI_PAPERSIZE'],
        DVIPS_PAPERSIZE = 'a4',
        DVIPS_PAPERSIZE = 'a4',
-       DVIPS_FLAGS = ['-t $DVIPS_PAPERSIZE',
+       DVIPS_FLAGS = ['-t$DVIPS_PAPERSIZE',
                       '-u+lilypond.map',
                       '-u+ec-mftrace.map'],
        PSPDF_FLAGS = ['-sPAPERSIZE=$DVIPS_PAPERSIZE'],
        )
 
                       '-u+lilypond.map',
                       '-u+ec-mftrace.map'],
        PSPDF_FLAGS = ['-sPAPERSIZE=$DVIPS_PAPERSIZE'],
        )
 
+env.Append (CCFLAGS = ['-pipe', '-Wno-pmf-conversions'])
 if env['debugging']:
 if env['debugging']:
-       env.Append (CCFLAGS = ['-g', '-pipe'])
+       env.Append (CCFLAGS = ['-g'])
 if env['optimising']:
        env.Append (CCFLAGS = '-O2')
        env.Append (CXXFLAGS = ['-DSTRING_UTILS_INLINED'])
 if env['optimising']:
        env.Append (CCFLAGS = '-O2')
        env.Append (CXXFLAGS = ['-DSTRING_UTILS_INLINED'])
@@ -542,6 +690,8 @@ if env['warnings']:
 
 # ugr,huh?
 env.Append (LINKFLAGS = ['-Wl,--export-dynamic'])
 
 # ugr,huh?
 env.Append (LINKFLAGS = ['-Wl,--export-dynamic'])
+# FIXME: ParseConfig ignores -L flag?
+env.Append (LINKFLAGS = ['-L/usr/X11R6/lib'])
 
 if env['verbose']:
        env['__verbose'] = ' --verbose'
 
 if env['verbose']:
        env['__verbose'] = ' --verbose'
@@ -606,11 +756,14 @@ env.Command (version_hh, '#/VERSION',
 # post-config environment update
 env.Append (
        run_prefix = run_prefix,
 # post-config environment update
 env.Append (
        run_prefix = run_prefix,
-       LILYPONDPREFIX = os.path.join (run_prefix, 'share/lilypond'),
+       LILYPONDPREFIX = LILYPONDPREFIX,
 
 
-       LIBPATH = [os.path.join (absbuild, 'flower', env['out']),],
+       # FIXME: move to lily/SConscript?
+       LIBPATH = [os.path.join (absbuild, 'flower', env['out']),
+                  os.path.join (absbuild, 'kpath-guile', env['out']),],
        CPPPATH = [outdir, ],
        CPPPATH = [outdir, ],
-       LILYPOND_PATH = ['.', '$srcdir/input',
+       LILYPOND_PATH = ['.',
+                        '$srcdir/input',
                         '$srcdir/input/regression',
                         '$srcdir/input/test',
                         '$srcdir/input/tutorial',
                         '$srcdir/input/regression',
                         '$srcdir/input/test',
                         '$srcdir/input/tutorial',
@@ -659,36 +812,58 @@ def symlink_tree (target, source, env):
                os.symlink (frm, os.path.basename (dst))
        shutil.rmtree (run_prefix)
        prefix = os.path.join (env['out'], 'usr')
                os.symlink (frm, os.path.basename (dst))
        shutil.rmtree (run_prefix)
        prefix = os.path.join (env['out'], 'usr')
-       map (lambda x: symlink (x[0], os.path.join (prefix, x[1])),
+       map (lambda x: symlink (x[0], os.path.join (prefix,
+                                                   x[1] % {'ver' : version})),
             # ^# := source dir
             # @  := out
             # /$ := add dst file_name
             (('python',     'lib/lilypond/python'),
             # ^# := source dir
             # @  := out
             # /$ := add dst file_name
             (('python',     'lib/lilypond/python'),
-             ('lily/',      'bin/lilypond-bin'),
-             ('scripts/',   'bin/lilypond'),
+             # ugh
+             ('python',     'share/lilypond/%(ver)s/python'),
+             ('lily/',      'bin/lilypond'),
+             ('scripts/',   'bin/convert-ly'),
              ('scripts/',   'bin/lilypond-book'),
              ('scripts/',   'bin/lilypond-book'),
-             ('mf',         'share/lilypond/dvips/mf-out'),
-             ('#ps',        'share/lilypond/dvips/ps'),
-             ('#ps',        'share/lilypond/tex/music-drawing-routines.ps'),
-             ('mf',         'share/lilypond/otf'),
-             ('mf',         'share/lilypond/tfm'),
-             ('#mf',        'share/lilypond/fonts/mf'),
-             ('mf',         'share/lilypond/fonts/otf'),
-             ('mf',         'share/lilypond/fonts/tfm'),
-             ('mf',         'share/lilypond/fonts/type1'),
-             ('#tex',       'share/lilypond/tex/source'),
-             ('tex',        'share/lilypond/tex/tex-out'),
-             ('mf',         'share/lilypond/tex/mf-out'),
-             ('#ly',        'share/lilypond/ly'),
-             ('#scm',       'share/lilypond/scm'),
-             ('#ps',        'share/lilypond/ps'),
+             ('scripts/',   'bin/ps2png'),
+             ('mf',         'share/lilypond/%(ver)s/dvips/mf-out'),
+             ('#ps',        'share/lilypond/%(ver)s/dvips/ps'),
+             ('#ps',        'share/lilypond/%(ver)s/tex/music-drawing-routines.ps'),
+             ('mf',         'share/lilypond/%(ver)s/otf'),
+             ('mf',         'share/lilypond/%(ver)s/tfm'),
+             ('tex',        'share/lilypond/%(ver)s/tex/enc'),
+             ('#mf',        'share/lilypond/%(ver)s/fonts/mf'),
+             ('mf',         'share/lilypond/%(ver)s/fonts/map'),
+             ('mf',         'share/lilypond/%(ver)s/fonts/otf'),
+             ('mf',         'share/lilypond/%(ver)s/fonts/tfm'),
+             ('mf',         'share/lilypond/%(ver)s/fonts/type1'),
+             ('#tex',       'share/lilypond/%(ver)s/tex/source'),
+             ('tex',        'share/lilypond/%(ver)s/tex/tex-out'),
+             ('mf',         'share/lilypond/%(ver)s/tex/mf-out'),
+             ('#ly',        'share/lilypond/%(ver)s/ly'),
+             ('#scm',       'share/lilypond/%(ver)s/scm'),
+             ('#scripts',   'share/lilypond/%(ver)s/scripts'),
+             ('#ps',        'share/lilypond/%(ver)s/ps'),
              ('po/@/nl.mo', 'share/locale/nl/LC_MESSAGES/lilypond.mo'),
              ('po/@/nl.mo', 'share/locale/nl/LC_MESSAGES/lilypond.mo'),
-             ('elisp',      'share/lilypond/elisp')))
+             ('elisp',      'share/lilypond/%(ver)s/elisp')))
+
+       print "FIXME: BARF BARF BARF"
+       os.chdir (absbuild)
+       out = env['out']
+       ver = version
+       prefix = os.path.join (env['out'], 'usr/share/lilypond/%(ver)s/fonts'
+                              % vars ())
+       for ext in ('enc', 'map', 'otf', 'svg', 'tfm', 'pfa'):
+               dir = os.path.join (absbuild, prefix, ext)
+               os.system ('rm -f ' + dir)
+               mkdirs (dir)
+               os.chdir (dir)
+               os.system ('ln -s ../../../../../../../mf/%(out)s/*.%(ext)s .'
+                          % vars ())
        os.chdir (srcdir)
 
        os.chdir (srcdir)
 
-if env['debugging']:
+if 1: #env['debugging']:
        stamp = os.path.join (run_prefix, 'stamp')
        stamp = os.path.join (run_prefix, 'stamp')
-       env.Command (stamp, 'SConstruct', [symlink_tree, 'touch $TARGET'])
+       env.Command (stamp, ['#/SConstruct', '#/VERSION'],
+                    [symlink_tree, 'touch $TARGET'])
        env.Depends ('lily', stamp)
        
 #### dist, tar
        env.Depends ('lily', stamp)
        
 #### dist, tar
@@ -702,18 +877,20 @@ def cvs_entry_is_file (line):
        return line[0] == '/' and line[-2] == '/'
 
 def cvs_dirs (dir):
        return line[0] == '/' and line[-2] == '/'
 
 def cvs_dirs (dir):
-       ENTRIES = os.path.join (dir, 'CVS/Entries')
-       if not os.path.exists (ENTRIES):
+       entries = os.path.join (dir, 'CVS/Entries')
+       if not os.path.exists (entries):
                return []
                return []
-       entries = open (ENTRIES).readlines ()
+       entries = open (entries).readlines ()
        dir_entries = filter (cvs_entry_is_dir, entries)
        dirs = map (lambda x: os.path.join (dir, x[2:x[2:].index ('/')+3]),
                    dir_entries)
        return dirs + map (cvs_dirs, dirs)
 
 def cvs_files (dir):
        dir_entries = filter (cvs_entry_is_dir, entries)
        dirs = map (lambda x: os.path.join (dir, x[2:x[2:].index ('/')+3]),
                    dir_entries)
        return dirs + map (cvs_dirs, dirs)
 
 def cvs_files (dir):
-       ENTRIES = os.path.join (dir, 'CVS/Entries')
-       entries = open (ENTRIES).readlines ()
+       entries = os.path.join (dir, 'CVS/Entries')
+       if not os.path.exists (entries):
+               return []
+       entries = open (entries).readlines ()
        file_entries = filter (cvs_entry_is_file, entries)
        files = map (lambda x: x[1:x[1:].index ('/')+1], file_entries)
        return map (lambda x: os.path.join (dir, x), files)
        file_entries = filter (cvs_entry_is_file, entries)
        files = map (lambda x: x[1:x[1:].index ('/')+1], file_entries)
        return map (lambda x: os.path.join (dir, x), files)
@@ -727,17 +904,32 @@ def flatten (tree, lst):
                                lst.append (i)
        return lst
 
                                lst.append (i)
        return lst
 
+if os.path.isdir ('%(srcdir)s/CVS' % vars ()):
+       subdirs = flatten (cvs_dirs ('.'), [])
+else:
+       # ugh
+       command = 'cd %(srcdir)s \
+       && find . -name SConscript | sed s@/SConscript@@' % vars ()
+       subdirs = string.split (os.popen (command).read ())
+
 if env['fast']\
    and 'all' not in COMMAND_LINE_TARGETS\
    and 'doc' not in COMMAND_LINE_TARGETS\
    and 'web' not in COMMAND_LINE_TARGETS\
    and 'install' not in COMMAND_LINE_TARGETS\
    and 'clean' not in COMMAND_LINE_TARGETS:
 if env['fast']\
    and 'all' not in COMMAND_LINE_TARGETS\
    and 'doc' not in COMMAND_LINE_TARGETS\
    and 'web' not in COMMAND_LINE_TARGETS\
    and 'install' not in COMMAND_LINE_TARGETS\
    and 'clean' not in COMMAND_LINE_TARGETS:
-       subdirs = ['lily', 'lily/include', 'flower', 'flower/include', 'mf']
+       subdirs = ['lily',
+                  'flower',
+                  'kpath-guile',
+                  'mf',
+                  'python',
+                  ]
+
+if os.path.isdir ('%(srcdir)s/CVS' % vars ()):
+       src_files = reduce (lambda x, y: x + y, map (cvs_files, subdirs))
 else:
 else:
-       subdirs = flatten (cvs_dirs ('.'), [])
+       src_files = ['foobar']
 
 
-src_files = reduce (lambda x, y: x + y, map (cvs_files, subdirs))
 readme_files = ['AUTHORS', 'README', 'INSTALL', 'NEWS']
 txt_files = map (lambda x: x + '.txt', readme_files)
 
 readme_files = ['AUTHORS', 'README', 'INSTALL', 'NEWS']
 txt_files = map (lambda x: x + '.txt', readme_files)
 
@@ -780,14 +972,16 @@ if not env['fast']:
        web_ball = web_base + '.tar.gz'
        env['footify'] = 'MAILADDRESS=bug-lilypond@gnu.org $PYTHON stepmake/bin/add-html-footer.py --name=lilypond --version=$TOPLEVEL_VERSION'
        web_ext = ['.html', '.ly', '.midi', '.pdf', '.png', '.ps.gz', '.txt',]
        web_ball = web_base + '.tar.gz'
        env['footify'] = 'MAILADDRESS=bug-lilypond@gnu.org $PYTHON stepmake/bin/add-html-footer.py --name=lilypond --version=$TOPLEVEL_VERSION'
        web_ext = ['.html', '.ly', '.midi', '.pdf', '.png', '.ps.gz', '.txt',]
-       web_path = '-path "*/$out/*"' + string.join (web_ext, ' -or -path "*/$out/*"')
+       web_path = '-path "*/$out/*"' + string.join (web_ext, ' -or -path "*/$out/*"') + '-or -type l'
        env['web_path'] = web_path
        web_list = os.path.join (outdir, 'weblist')
        # compatible make heritits
        # fixme: generate in $outdir is cwd/builddir
        env.Command (web_list,
        env['web_path'] = web_path
        web_list = os.path.join (outdir, 'weblist')
        # compatible make heritits
        # fixme: generate in $outdir is cwd/builddir
        env.Command (web_list,
-                    ## this is correct, but takes > 5min if you have a peder :-)
-                    ##'doc',
+                    ## Adding 'doc' dependency is correct, but takes
+                    ## > 5min extra if you have a peder :-)
+                    #'doc',
+                    
                     '#/VERSION',
                     ['$PYTHON buildscripts/mutopia-index.py -o examples.html ./',
                      'cd $absbuild && $footify $$(find . -name "*.html" -print)',
                     '#/VERSION',
                     ['$PYTHON buildscripts/mutopia-index.py -o examples.html ./',
                      'cd $absbuild && $footify $$(find . -name "*.html" -print)',