diff waf_paths.py @ 20:07ff8cf8a0f1

Fixed WAF install paths issue on Windows. * Reorganized the waf_paths.py WAF tool so that install paths are correctly set on Windows. * Added ordereddict.py for use by the waf_paths.py WAF tool on python versions less than 2.7. * Renamed the waf script to waf.py so that Windows users get the benefits of the .py file extension. * Fixed a bug where the FifePath entry in parpg.cfg was not getting set to the default python site-package path. * Fixed a bug in the Windows parpg.bat launcher where quotation marks (") were screwing up the PYTHONPATH variable.
author M. George Hansen <technopolitica@gmail.com>
date Wed, 15 Jun 2011 13:21:25 -1000
parents 15107282d9eb
children feceb6130570
line wrap: on
line diff
--- a/waf_paths.py	Fri Jun 10 11:57:39 2011 -1000
+++ b/waf_paths.py	Wed Jun 15 13:21:25 2011 -1000
@@ -1,73 +1,67 @@
 #! /usr/bin/env python
 # encoding: utf-8
-import sys
+import os
+import platform
+import re
 
-from waflib import Utils, Options, Context
+from waflib import Utils, Options, Context, Logs, Errors
 
-option_values = {
-    'bindir'        : ('user executables', '${EXEC_PREFIX}/bin'),
-    'sbindir'       : ('system admin executables', '${EXEC_PREFIX}/sbin'),
-    'libexecdir'    : ('program executables', '${EXEC_PREFIX}/libexec'),
-    'sharedstatedir': ('modifiable architecture-independent data',
-                       '${PREFIX}/com'),
-    'localstatedir' : ('modifiable single-machine data', '${PREFIX}/var'),
-    'libdir'        : ('object code libraries', '${EXEC_PREFIX}/lib'),
-    'includedir'    : ('C header files', '${PREFIX}/include'),
-    'oldincludedir' : ('C header files for non-gcc', '/usr/include'),
-    'datarootdir'   : ('read-only arch.-independent data root',
-                       '${PREFIX}/share'),
-    # datadir and sysconfdir definitions deviate from GNU standards by
-    # appending the ${APPNAME}, but it makes the install script simpler since
-    # we don't have to redefine install paths on Windows.
-    'datadir'       : ('read-only architecture-independent data',
-                       '${DATAROOTDIR}/${APPNAME}'),
-    'sysconfdir'    : ('read-only single-machine data',
-                       '${PREFIX}/etc/${APPNAME}'),
-    'infodir'       : ('info documentation', '${DATAROOTDIR}/info'),
-    'localedir'     : ('locale-dependent data', '${DATAROOTDIR}/locale'),
-    'mandir'        : ('man documentation', '${DATAROOTDIR}/man'),
-    'docdir'        : ('documentation root', '${DATAROOTDIR}/doc/${APPNAME}'),
-    'htmldir'       : ('html documentation', '${DOCDIR}'),
-    'dvidir'        : ('dvi documentation', '${DOCDIR}'),
-    'pdfdir'        : ('pdf documentation', '${DOCDIR}'),
-    'psdir'         : ('ps documentation', '${DOCDIR}'),
-}
+try:
+    from collections import OrderedDict
+except ImportError:
+    # Python 2.6 doesn't have an OrderedDict, so we'll provide one.
+    from ordereddict import OrderedDict
+
+prefix_values = OrderedDict(
+    [
+        ('prefix', ['installation prefix', '/usr/local']),
+        ('exec_prefix',
+         ['installation prefix for platform-dependent binary files',
+          '${PREFIX}'])
+    ]
+)
 
-if sys.platform == 'Windows':
-    option_values['PREFIX'][1] = '${PROGRAM_FILES}/${APPNAME}'
-    option_values['BINDIR'][1] = '${EXEC_PREFIX}'
-    option_values['SYSCONFDIR'][1] = '${PREFIX}'
-    option_values['DATAROOTDIR'][1] = '${PREFIX}'
-    option_values['DATADIR'][1] = '${DATAROOTDIR}/data'
-    option_values['DOCDIR'][1] = '${DATAROOTDIR}/doc'
-
-def get_param(varname, default):
-        return getattr(Options.options, varname, '') or default
+option_values = OrderedDict(
+    [
+        ('bindir', ['user executables', '${EXEC_PREFIX}/bin']),
+        ('sbindir', ['system admin executables', '${EXEC_PREFIX}/sbin']),
+        ('libexecdir', ['program executables', '${EXEC_PREFIX}/libexec']),
+        ('sharedstatedir', ['modifiable architecture-independent data',
+                            '${PREFIX}/com']),
+        ('localstatedir', ['modifiable single-machine data', '${PREFIX}/var']),
+        ('libdir', ['object code libraries', '${EXEC_PREFIX}/lib']),
+        ('includedir', ['C header files', '${PREFIX}/include']),
+        ('oldincludedir', ['C header files for non-gcc', '/usr/include']),
+        ('datarootdir', ['read-only arch.-independent data root',
+                         '${PREFIX}/share']),
+        # datadir and sysconfdir definitions deviate from GNU standards by
+        # appending the ${APPNAME}, but it makes the install script simpler
+        # since we don't have to redefine install paths on Windows.
+        ('datadir', ['read-only architecture-independent data',
+                     '${DATAROOTDIR}/${APPNAME}']),
+        ('sysconfdir', ['read-only single-machine data',
+                        '${PREFIX}/etc/${APPNAME}']),
+        ('infodir', ['info documentation', '${DATAROOTDIR}/info']),
+        ('localedir', ['locale-dependent data', '${DATAROOTDIR}/locale']),
+        ('mandir', ['man documentation', '${DATAROOTDIR}/man']),
+        ('docdir', ['documentation root', '${DATAROOTDIR}/doc/${APPNAME}']),
+        ('htmldir', ['html documentation', '${DOCDIR}']),
+        ('dvidir', ['dvi documentation', '${DOCDIR}']),
+        ('pdfdir', ['pdf documentation', '${DOCDIR}']),
+        ('psdir', ['ps documentation', '${DOCDIR}']),
+    ]
+)
 
-def configure(conf):
-    env = conf.env
-    env['LIBDIR'] = []
-    env['BINDIR'] = []
-    env['EXEC_PREFIX'] = get_param('EXEC_PREFIX', env['PREFIX'])
-    env['APPNAME'] = getattr(Context.g_module, 'APPNAME')
-    env['INSTALL_PATHS'] = ['PREFIX', 'EXEC_PREFIX']
-    complete = False
-    iter = 0
-    while not complete and iter < len(option_values) + 1:
-        iter += 1
-        complete = True
-        for name in option_values:
-            help, default = option_values[name]
-            name = name.upper()
-            if not env[name]:
-                try:
-                    env[name] = Utils.subst_vars(get_param(name, default), env)
-                except TypeError:
-                    complete = False
-            env['INSTALL_PATHS'].append(name)
-    if not complete:
-        lst = [name for name in option_values if not env[name.upper()]]
-        raise Errors.WafError('Variable substitution failure %r' % lst)
+if platform.system() == 'Windows':
+    prefix_values['prefix'][1] = '${PROGRAMFILES}/${APPNAME}'
+    
+    option_values['bindir'][1] = '${EXEC_PREFIX}'
+    option_values['sysconfdir'][1] = '${PREFIX}'
+    option_values['datarootdir'][1] = '${PREFIX}'
+    option_values['datadir'][1] = '${DATAROOTDIR}/data'
+    option_values['docdir'][1] = '${DATAROOTDIR}/doc'
+    del option_values['oldincludedir']
+    del option_values['mandir']
 
 def options(opt):
     inst_dir = opt.add_option_group(
@@ -77,24 +71,75 @@
         'be specified using the "--prefix" option, for example '
         '"--prefix=$HOME"'
     )
-    for k in ('--prefix', '--destdir'):
-        option = opt.parser.get_option(k)
-        if option:
-            opt.parser.remove_option(k)
-            inst_dir.add_option(option)
-    inst_dir.add_option(
-        '--exec-prefix',
-        help='installation prefix [Default: ${PREFIX}]',
-        default=inst_dir.defaults['prefix'],
-        dest='EXEC_PREFIX',
-    )
-    dirs_options = opt.add_option_group(
+    help_template = '{0} [Default: %default]'
+    for prefix_name in prefix_values.keys():
+        # Remove any of the core WAF options if they conflict with our options.
+        if opt.parser.get_option(prefix_name):
+            opt.parser.remove_option(prefix_name)
+        help, default = prefix_values[prefix_name]
+        option_name = '--' + prefix_name
+        inst_dir.add_option(option_name, help=help_template.format(help),
+                            default=default, dest=prefix_name)
+    
+    # Move the --destdir option to the inst_dir group for consistency.
+    destdir_option = opt.parser.get_option('destdir')
+    if destdir_option:
+        opt.parser.remove_option('destdir')
+        inst_dir.add_option(destdir_option)
+    
+    predef_dirs = opt.add_option_group(
         'Pre-defined installation directories',
         ''
     )
     for name in option_values:
         help, default = option_values[name]
         option_name = '--' + name
-        str_help = '{0} [Default: %default]'.format(help)
-        dirs_options.add_option(option_name, help=str_help, default=default,
-                                dest=name.upper())
+        predef_dirs.add_option(option_name, help=help_template.format(help),
+                               default=default, dest=name)
+
+def configure(conf):
+    def set_env_paths(path_values):
+        errors_raised = False
+        index = 0
+        print(path_values.keys(), path_values)
+        for option_name in path_values.keys():
+            help, default = path_values[option_name]
+            upper_option_name = option_name.upper()
+            try:
+                env[upper_option_name] = Utils.subst_vars(
+                    getattr(conf.options, option_name),
+                    env,
+                )
+            except TypeError:
+                errors_raised = True
+            env['INSTALL_PATHS'].append(upper_option_name)
+        if errors_raised:
+            failed_path_names = [name for name in option_values if
+                                 upper_option_name not in env]
+        else:
+            failed_path_names = []
+        return failed_path_names
+    
+    env = conf.env
+    if platform.system() == 'Windows':
+        try:
+            env['PROGRAMFILES'] = os.environ['PROGRAMFILES']
+        except KeyError:
+            Logs.warn('PROGRAMFILES environmental variable is not set')
+            if re.search(r'\$\{PROGRAMFILES\}', conf.options.prefix):
+                Logs.error(
+                    'unable to find path to Program Files direcotry, please '
+                    'set the PROGRAMFILES environmental variable or '
+                    'override installation prefix with --prefix'
+                )
+    if 'APPNAME' not in env:
+        env['APPNAME'] = Context.g_module.APPNAME
+    env['INSTALL_PATHS'] = []
+    failed_path_names = []
+    failed_path_names.extend(set_env_paths(prefix_values))
+    failed_path_names.extend(set_env_paths(option_values))
+    if failed_path_names:
+        error_message = 'failed to expand install paths {0!r}'
+        raise Errors.ConfigurationError(
+            error_message.format(failed_path_names)
+        )