3 # Scott Newton, 2005 (scottn)
4 # Thomas Nagy, 2006 (ita)
6 "Custom command-line options"
8 import os
, sys
, imp
, types
, tempfile
, optparse
10 from Constants
import *
12 cmds
= 'distclean configure build install clean uninstall check dist distcheck'.split()
14 # TODO remove in waf 1.6 the following two
22 lockfile
= os
.environ
.get('WAFLOCK', '.lock-wscript')
23 try: cache_global
= os
.path
.abspath(os
.environ
['WAFCACHE'])
24 except KeyError: cache_global
= ''
25 platform
= Utils
.unversioned_sys_platform()
26 conf_file
= 'conf-runs-%s-%d.pickle' % (platform
, ABI
)
28 remote_repo
= ['http://waf.googlecode.com/svn/']
29 """remote directory for the plugins"""
32 # Such a command-line should work: JOBS=4 PREFIX=/opt/ DESTDIR=/tmp/ahoj/ waf configure
33 default_prefix
= os
.environ
.get('PREFIX')
34 if not default_prefix
:
35 if platform
== 'win32':
36 d
= tempfile
.gettempdir()
37 default_prefix
= d
[0].upper() + d
[1:]
38 # win32 preserves the case, but gettempdir does not
39 else: default_prefix
= '/usr/local/'
41 default_jobs
= os
.environ
.get('JOBS', -1)
44 if 'SC_NPROCESSORS_ONLN' in os
.sysconf_names
:
45 default_jobs
= os
.sysconf('SC_NPROCESSORS_ONLN')
47 default_jobs
= int(Utils
.cmd_output(['sysctl', '-n', 'hw.ncpu']))
49 if os
.name
== 'java': # platform.system() == 'Java'
50 from java
.lang
import Runtime
51 default_jobs
= Runtime
.getRuntime().availableProcessors()
53 # environment var defined on win32
54 default_jobs
= int(os
.environ
.get('NUMBER_OF_PROCESSORS', 1))
56 default_destdir
= os
.environ
.get('DESTDIR', '')
60 module
= Utils
.g_module
62 # create the help messages for commands
64 keys
= list(tbl
.keys())
68 if not module
.build
.__doc
__:
69 module
.build
.__doc
__ = 'builds the project'
70 if 'configure' in tbl
:
71 if not module
.configure
.__doc
__:
72 module
.configure
.__doc
__ = 'configures the project'
74 ban
= ['set_options', 'init', 'shutdown']
76 optlst
= [x
for x
in keys
if not x
in ban
77 and type(tbl
[x
]) is type(parse_args_impl
)
79 and not x
.startswith('_')]
81 just
= max([len(x
) for x
in optlst
])
84 cmds_str
.append(' %s: %s' % (x
.ljust(just
), tbl
[x
].__doc
__))
85 ret
= '\n'.join(cmds_str
)
88 return '''waf [command] [options]
90 Main commands (example: ./waf build -j4)
95 setattr(optparse
.OptionParser
, 'get_usage', get_usage
)
97 def create_parser(module
=None):
98 Logs
.debug('options: create_parser is called')
99 parser
= optparse
.OptionParser(conflict_handler
="resolve", version
= 'waf %s (%s)' % (WAFVERSION
, WAFREVISION
))
101 parser
.formatter
.width
= Utils
.get_term_cols()
102 p
= parser
.add_option
106 default
= default_jobs
,
107 help = 'amount of parallel jobs (%r)' % default_jobs
,
111 action
= 'store_true',
113 help = 'keep running happily on independent task groups',
119 help = 'verbosity level -v -vv or -vvv [default: 0]',
123 action
= 'store_true',
125 help = 'ignore the WAFCACHE (if set)',
131 help = 'debugging zones (task_gen, deps, tasks, etc)',
134 p('-p', '--progress',
137 help = '-p: progress bar; -pp: ide output',
138 dest
= 'progress_bar')
143 help = 'build given task generators, e.g. "target1,target2"',
144 dest
= 'compile_targets')
146 gr
= optparse
.OptionGroup(parser
, 'configuration options')
147 parser
.add_option_group(gr
)
148 gr
.add_option('-b', '--blddir',
151 help = 'out dir for the project (configuration)',
153 gr
.add_option('-s', '--srcdir',
156 help = 'top dir for the project (configuration)',
158 gr
.add_option('--prefix',
159 help = 'installation prefix (configuration) [default: %r]' % default_prefix
,
160 default
= default_prefix
,
163 gr
.add_option('--download',
164 action
= 'store_true',
166 help = 'try to download the tools if missing',
169 gr
= optparse
.OptionGroup(parser
, 'installation options')
170 parser
.add_option_group(gr
)
171 gr
.add_option('--destdir',
172 help = 'installation root [default: %r]' % default_destdir
,
173 default
= default_destdir
,
175 gr
.add_option('-f', '--force',
176 action
= 'store_true',
178 help = 'force file installation',
183 def parse_args_impl(parser
, _args
=None):
184 global options
, commands
, arg_line
185 (options
, args
) = parser
.parse_args(args
=_args
)
188 #arg_line = args[:] # copy
190 # By default, 'waf' is equivalent to 'waf build'
192 for var
in cmds
: commands
[var
] = 0
194 commands
['build'] = 1
197 # Parse the command arguments
201 # the check thing depends on the build
203 idx
= args
.index('check')
205 bidx
= args
.index('build')
207 raise ValueError('build before check')
208 except ValueError, e
:
209 args
.insert(idx
, 'build')
211 if args
[0] != 'init':
212 args
.insert(0, 'init')
215 if options
.keep
: options
.jobs
= 1
216 if options
.jobs
< 1: options
.jobs
= 1
218 if 'install' in sys
.argv
or 'uninstall' in sys
.argv
:
219 # absolute path only if set
220 options
.destdir
= options
.destdir
and os
.path
.abspath(os
.path
.expanduser(options
.destdir
))
222 Logs
.verbose
= options
.verbose
226 Logs
.zones
= options
.zones
.split(',')
227 if not Logs
.verbose
: Logs
.verbose
= 1
228 elif Logs
.verbose
> 0:
229 Logs
.zones
= ['runner']
234 # 1. rename the class to OptionsContext
235 # 2. instead of a class attribute, use a module (static 'parser')
236 # 3. parse_args_impl was made in times when we did not know about binding new methods to classes
238 class Handler(Utils
.Context
):
239 """loads wscript modules in folders for adding options
240 This class should be named 'OptionsContext'
241 A method named 'recurse' is bound when used by the module Scripting"""
244 # make it possible to access the reference, like Build.bld
246 def __init__(self
, module
=None):
247 self
.parser
= create_parser(module
)
248 self
.cwd
= os
.getcwd()
249 Handler
.parser
= self
251 def add_option(self
, *k
, **kw
):
252 self
.parser
.add_option(*k
, **kw
)
254 def add_option_group(self
, *k
, **kw
):
255 return self
.parser
.add_option_group(*k
, **kw
)
257 def get_option_group(self
, opt_str
):
258 return self
.parser
.get_option_group(opt_str
)
260 def sub_options(self
, *k
, **kw
):
261 if not k
: raise Utils
.WscriptError('folder expected')
262 self
.recurse(k
[0], name
='set_options')
264 def tool_options(self
, *k
, **kw
):
265 Utils
.python_24_guard()
268 raise Utils
.WscriptError('invalid tool_options call %r %r' % (k
, kw
))
269 tools
= Utils
.to_list(k
[0])
271 # TODO waf 1.6 remove the global variable tooldir
272 path
= Utils
.to_list(kw
.get('tdir', kw
.get('tooldir', tooldir
)))
275 tool
= tool
.replace('++', 'xx')
276 if tool
== 'java': tool
= 'javaw'
277 if tool
.lower() == 'unittest': tool
= 'unittestw'
278 module
= Utils
.load_tool(tool
, path
)
280 fun
= module
.set_options
281 except AttributeError:
284 fun(kw
.get('option_group', self
))
286 def parse_args(self
, args
=None):
287 parse_args_impl(self
.parser
, args
)