comparison 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
comparison
equal deleted inserted replaced
19:e97972cc7110 20:07ff8cf8a0f1
1 #! /usr/bin/env python 1 #! /usr/bin/env python
2 # encoding: utf-8 2 # encoding: utf-8
3 import sys 3 import os
4 import platform
5 import re
4 6
5 from waflib import Utils, Options, Context 7 from waflib import Utils, Options, Context, Logs, Errors
6 8
7 option_values = { 9 try:
8 'bindir' : ('user executables', '${EXEC_PREFIX}/bin'), 10 from collections import OrderedDict
9 'sbindir' : ('system admin executables', '${EXEC_PREFIX}/sbin'), 11 except ImportError:
10 'libexecdir' : ('program executables', '${EXEC_PREFIX}/libexec'), 12 # Python 2.6 doesn't have an OrderedDict, so we'll provide one.
11 'sharedstatedir': ('modifiable architecture-independent data', 13 from ordereddict import OrderedDict
12 '${PREFIX}/com'),
13 'localstatedir' : ('modifiable single-machine data', '${PREFIX}/var'),
14 'libdir' : ('object code libraries', '${EXEC_PREFIX}/lib'),
15 'includedir' : ('C header files', '${PREFIX}/include'),
16 'oldincludedir' : ('C header files for non-gcc', '/usr/include'),
17 'datarootdir' : ('read-only arch.-independent data root',
18 '${PREFIX}/share'),
19 # datadir and sysconfdir definitions deviate from GNU standards by
20 # appending the ${APPNAME}, but it makes the install script simpler since
21 # we don't have to redefine install paths on Windows.
22 'datadir' : ('read-only architecture-independent data',
23 '${DATAROOTDIR}/${APPNAME}'),
24 'sysconfdir' : ('read-only single-machine data',
25 '${PREFIX}/etc/${APPNAME}'),
26 'infodir' : ('info documentation', '${DATAROOTDIR}/info'),
27 'localedir' : ('locale-dependent data', '${DATAROOTDIR}/locale'),
28 'mandir' : ('man documentation', '${DATAROOTDIR}/man'),
29 'docdir' : ('documentation root', '${DATAROOTDIR}/doc/${APPNAME}'),
30 'htmldir' : ('html documentation', '${DOCDIR}'),
31 'dvidir' : ('dvi documentation', '${DOCDIR}'),
32 'pdfdir' : ('pdf documentation', '${DOCDIR}'),
33 'psdir' : ('ps documentation', '${DOCDIR}'),
34 }
35 14
36 if sys.platform == 'Windows': 15 prefix_values = OrderedDict(
37 option_values['PREFIX'][1] = '${PROGRAM_FILES}/${APPNAME}' 16 [
38 option_values['BINDIR'][1] = '${EXEC_PREFIX}' 17 ('prefix', ['installation prefix', '/usr/local']),
39 option_values['SYSCONFDIR'][1] = '${PREFIX}' 18 ('exec_prefix',
40 option_values['DATAROOTDIR'][1] = '${PREFIX}' 19 ['installation prefix for platform-dependent binary files',
41 option_values['DATADIR'][1] = '${DATAROOTDIR}/data' 20 '${PREFIX}'])
42 option_values['DOCDIR'][1] = '${DATAROOTDIR}/doc' 21 ]
22 )
43 23
44 def get_param(varname, default): 24 option_values = OrderedDict(
45 return getattr(Options.options, varname, '') or default 25 [
26 ('bindir', ['user executables', '${EXEC_PREFIX}/bin']),
27 ('sbindir', ['system admin executables', '${EXEC_PREFIX}/sbin']),
28 ('libexecdir', ['program executables', '${EXEC_PREFIX}/libexec']),
29 ('sharedstatedir', ['modifiable architecture-independent data',
30 '${PREFIX}/com']),
31 ('localstatedir', ['modifiable single-machine data', '${PREFIX}/var']),
32 ('libdir', ['object code libraries', '${EXEC_PREFIX}/lib']),
33 ('includedir', ['C header files', '${PREFIX}/include']),
34 ('oldincludedir', ['C header files for non-gcc', '/usr/include']),
35 ('datarootdir', ['read-only arch.-independent data root',
36 '${PREFIX}/share']),
37 # datadir and sysconfdir definitions deviate from GNU standards by
38 # appending the ${APPNAME}, but it makes the install script simpler
39 # since we don't have to redefine install paths on Windows.
40 ('datadir', ['read-only architecture-independent data',
41 '${DATAROOTDIR}/${APPNAME}']),
42 ('sysconfdir', ['read-only single-machine data',
43 '${PREFIX}/etc/${APPNAME}']),
44 ('infodir', ['info documentation', '${DATAROOTDIR}/info']),
45 ('localedir', ['locale-dependent data', '${DATAROOTDIR}/locale']),
46 ('mandir', ['man documentation', '${DATAROOTDIR}/man']),
47 ('docdir', ['documentation root', '${DATAROOTDIR}/doc/${APPNAME}']),
48 ('htmldir', ['html documentation', '${DOCDIR}']),
49 ('dvidir', ['dvi documentation', '${DOCDIR}']),
50 ('pdfdir', ['pdf documentation', '${DOCDIR}']),
51 ('psdir', ['ps documentation', '${DOCDIR}']),
52 ]
53 )
46 54
47 def configure(conf): 55 if platform.system() == 'Windows':
48 env = conf.env 56 prefix_values['prefix'][1] = '${PROGRAMFILES}/${APPNAME}'
49 env['LIBDIR'] = [] 57
50 env['BINDIR'] = [] 58 option_values['bindir'][1] = '${EXEC_PREFIX}'
51 env['EXEC_PREFIX'] = get_param('EXEC_PREFIX', env['PREFIX']) 59 option_values['sysconfdir'][1] = '${PREFIX}'
52 env['APPNAME'] = getattr(Context.g_module, 'APPNAME') 60 option_values['datarootdir'][1] = '${PREFIX}'
53 env['INSTALL_PATHS'] = ['PREFIX', 'EXEC_PREFIX'] 61 option_values['datadir'][1] = '${DATAROOTDIR}/data'
54 complete = False 62 option_values['docdir'][1] = '${DATAROOTDIR}/doc'
55 iter = 0 63 del option_values['oldincludedir']
56 while not complete and iter < len(option_values) + 1: 64 del option_values['mandir']
57 iter += 1
58 complete = True
59 for name in option_values:
60 help, default = option_values[name]
61 name = name.upper()
62 if not env[name]:
63 try:
64 env[name] = Utils.subst_vars(get_param(name, default), env)
65 except TypeError:
66 complete = False
67 env['INSTALL_PATHS'].append(name)
68 if not complete:
69 lst = [name for name in option_values if not env[name.upper()]]
70 raise Errors.WafError('Variable substitution failure %r' % lst)
71 65
72 def options(opt): 66 def options(opt):
73 inst_dir = opt.add_option_group( 67 inst_dir = opt.add_option_group(
74 'Installation directories', 68 'Installation directories',
75 'By default, "waf install" will install all files into their ' 69 'By default, "waf install" will install all files into their '
76 'appropriate directories under ${PREFIX}. The installation prefix can ' 70 'appropriate directories under ${PREFIX}. The installation prefix can '
77 'be specified using the "--prefix" option, for example ' 71 'be specified using the "--prefix" option, for example '
78 '"--prefix=$HOME"' 72 '"--prefix=$HOME"'
79 ) 73 )
80 for k in ('--prefix', '--destdir'): 74 help_template = '{0} [Default: %default]'
81 option = opt.parser.get_option(k) 75 for prefix_name in prefix_values.keys():
82 if option: 76 # Remove any of the core WAF options if they conflict with our options.
83 opt.parser.remove_option(k) 77 if opt.parser.get_option(prefix_name):
84 inst_dir.add_option(option) 78 opt.parser.remove_option(prefix_name)
85 inst_dir.add_option( 79 help, default = prefix_values[prefix_name]
86 '--exec-prefix', 80 option_name = '--' + prefix_name
87 help='installation prefix [Default: ${PREFIX}]', 81 inst_dir.add_option(option_name, help=help_template.format(help),
88 default=inst_dir.defaults['prefix'], 82 default=default, dest=prefix_name)
89 dest='EXEC_PREFIX', 83
90 ) 84 # Move the --destdir option to the inst_dir group for consistency.
91 dirs_options = opt.add_option_group( 85 destdir_option = opt.parser.get_option('destdir')
86 if destdir_option:
87 opt.parser.remove_option('destdir')
88 inst_dir.add_option(destdir_option)
89
90 predef_dirs = opt.add_option_group(
92 'Pre-defined installation directories', 91 'Pre-defined installation directories',
93 '' 92 ''
94 ) 93 )
95 for name in option_values: 94 for name in option_values:
96 help, default = option_values[name] 95 help, default = option_values[name]
97 option_name = '--' + name 96 option_name = '--' + name
98 str_help = '{0} [Default: %default]'.format(help) 97 predef_dirs.add_option(option_name, help=help_template.format(help),
99 dirs_options.add_option(option_name, help=str_help, default=default, 98 default=default, dest=name)
100 dest=name.upper()) 99
100 def configure(conf):
101 def set_env_paths(path_values):
102 errors_raised = False
103 index = 0
104 print(path_values.keys(), path_values)
105 for option_name in path_values.keys():
106 help, default = path_values[option_name]
107 upper_option_name = option_name.upper()
108 try:
109 env[upper_option_name] = Utils.subst_vars(
110 getattr(conf.options, option_name),
111 env,
112 )
113 except TypeError:
114 errors_raised = True
115 env['INSTALL_PATHS'].append(upper_option_name)
116 if errors_raised:
117 failed_path_names = [name for name in option_values if
118 upper_option_name not in env]
119 else:
120 failed_path_names = []
121 return failed_path_names
122
123 env = conf.env
124 if platform.system() == 'Windows':
125 try:
126 env['PROGRAMFILES'] = os.environ['PROGRAMFILES']
127 except KeyError:
128 Logs.warn('PROGRAMFILES environmental variable is not set')
129 if re.search(r'\$\{PROGRAMFILES\}', conf.options.prefix):
130 Logs.error(
131 'unable to find path to Program Files direcotry, please '
132 'set the PROGRAMFILES environmental variable or '
133 'override installation prefix with --prefix'
134 )
135 if 'APPNAME' not in env:
136 env['APPNAME'] = Context.g_module.APPNAME
137 env['INSTALL_PATHS'] = []
138 failed_path_names = []
139 failed_path_names.extend(set_env_paths(prefix_values))
140 failed_path_names.extend(set_env_paths(option_values))
141 if failed_path_names:
142 error_message = 'failed to expand install paths {0!r}'
143 raise Errors.ConfigurationError(
144 error_message.format(failed_path_names)
145 )