s3: libsmbclient: Add missing talloc stackframe.
[bbaumbach/samba-autobuild/.git] / third_party / waf / wafadmin / Options.py
1 #!/usr/bin/env python
2 # encoding: utf-8
3 # Scott Newton, 2005 (scottn)
4 # Thomas Nagy, 2006 (ita)
5
6 "Custom command-line options"
7
8 import os, sys, imp, types, tempfile, optparse
9 import Logs, Utils
10 from Constants import *
11
12 cmds = 'distclean configure build install clean uninstall check dist distcheck'.split()
13
14 # TODO remove in waf 1.6 the following two
15 commands = {}
16 is_install = False
17
18 options = {}
19 arg_line = []
20 launch_dir = ''
21 tooldir = ''
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)
27
28 remote_repo = ['http://waf.googlecode.com/svn/']
29 """remote directory for the plugins"""
30
31
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/'
40
41 default_jobs = os.environ.get('JOBS', -1)
42 if default_jobs < 1:
43         try:
44                 if 'SC_NPROCESSORS_ONLN' in os.sysconf_names:
45                         default_jobs = os.sysconf('SC_NPROCESSORS_ONLN')
46                 else:
47                         default_jobs = int(Utils.cmd_output(['sysctl', '-n', 'hw.ncpu']))
48         except:
49                 if os.name == 'java': # platform.system() == 'Java'
50                         from java.lang import Runtime
51                         default_jobs = Runtime.getRuntime().availableProcessors()
52                 else:
53                         # environment var defined on win32
54                         default_jobs = int(os.environ.get('NUMBER_OF_PROCESSORS', 1))
55
56 default_destdir = os.environ.get('DESTDIR', '')
57
58 def get_usage(self):
59         cmds_str = []
60         module = Utils.g_module
61         if module:
62                 # create the help messages for commands
63                 tbl = module.__dict__
64                 keys = list(tbl.keys())
65                 keys.sort()
66
67                 if 'build' in tbl:
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'
73
74                 ban = ['set_options', 'init', 'shutdown']
75
76                 optlst = [x for x in keys if not x in ban
77                         and type(tbl[x]) is type(parse_args_impl)
78                         and tbl[x].__doc__
79                         and not x.startswith('_')]
80
81                 just = max([len(x) for x in optlst])
82
83                 for x in optlst:
84                         cmds_str.append('  %s: %s' % (x.ljust(just), tbl[x].__doc__))
85                 ret = '\n'.join(cmds_str)
86         else:
87                 ret = ' '.join(cmds)
88         return '''waf [command] [options]
89
90 Main commands (example: ./waf build -j4)
91 %s
92 ''' % ret
93
94
95 setattr(optparse.OptionParser, 'get_usage', get_usage)
96
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))
100
101         parser.formatter.width = Utils.get_term_cols()
102         p = parser.add_option
103
104         p('-j', '--jobs',
105                 type    = 'int',
106                 default = default_jobs,
107                 help    = 'amount of parallel jobs (%r)' % default_jobs,
108                 dest    = 'jobs')
109
110         p('-k', '--keep',
111                 action  = 'store_true',
112                 default = False,
113                 help    = 'keep running happily on independent task groups',
114                 dest    = 'keep')
115
116         p('-v', '--verbose',
117                 action  = 'count',
118                 default = 0,
119                 help    = 'verbosity level -v -vv or -vvv [default: 0]',
120                 dest    = 'verbose')
121
122         p('--nocache',
123                 action  = 'store_true',
124                 default = False,
125                 help    = 'ignore the WAFCACHE (if set)',
126                 dest    = 'nocache')
127
128         p('--zones',
129                 action  = 'store',
130                 default = '',
131                 help    = 'debugging zones (task_gen, deps, tasks, etc)',
132                 dest    = 'zones')
133
134         p('-p', '--progress',
135                 action  = 'count',
136                 default = 0,
137                 help    = '-p: progress bar; -pp: ide output',
138                 dest    = 'progress_bar')
139
140         p('--targets',
141                 action  = 'store',
142                 default = '',
143                 help    = 'build given task generators, e.g. "target1,target2"',
144                 dest    = 'compile_targets')
145
146         gr = optparse.OptionGroup(parser, 'configuration options')
147         parser.add_option_group(gr)
148         gr.add_option('-b', '--blddir',
149                 action  = 'store',
150                 default = '',
151                 help    = 'out dir for the project (configuration)',
152                 dest    = 'blddir')
153         gr.add_option('-s', '--srcdir',
154                 action  = 'store',
155                 default = '',
156                 help    = 'top dir for the project (configuration)',
157                 dest    = 'srcdir')
158         gr.add_option('--prefix',
159                 help    = 'installation prefix (configuration) [default: %r]' % default_prefix,
160                 default = default_prefix,
161                 dest    = 'prefix')
162
163         gr.add_option('--download',
164                 action  = 'store_true',
165                 default = False,
166                 help    = 'try to download the tools if missing',
167                 dest    = 'download')
168
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,
174                 dest    = 'destdir')
175         gr.add_option('-f', '--force',
176                 action  = 'store_true',
177                 default = False,
178                 help    = 'force file installation',
179                 dest    = 'force')
180
181         return parser
182
183 def parse_args_impl(parser, _args=None):
184         global options, commands, arg_line
185         (options, args) = parser.parse_args(args=_args)
186
187         arg_line = args
188         #arg_line = args[:] # copy
189
190         # By default, 'waf' is equivalent to 'waf build'
191         commands = {}
192         for var in cmds: commands[var] = 0
193         if not args:
194                 commands['build'] = 1
195                 args.append('build')
196
197         # Parse the command arguments
198         for arg in args:
199                 commands[arg] = True
200
201         # the check thing depends on the build
202         if 'check' in args:
203                 idx = args.index('check')
204                 try:
205                         bidx = args.index('build')
206                         if bidx > idx:
207                                 raise ValueError('build before check')
208                 except ValueError, e:
209                         args.insert(idx, 'build')
210
211         if args[0] != 'init':
212                 args.insert(0, 'init')
213
214         # TODO -k => -j0
215         if options.keep: options.jobs = 1
216         if options.jobs < 1: options.jobs = 1
217
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))
221
222         Logs.verbose = options.verbose
223         Logs.init_log()
224
225         if options.zones:
226                 Logs.zones = options.zones.split(',')
227                 if not Logs.verbose: Logs.verbose = 1
228         elif Logs.verbose > 0:
229                 Logs.zones = ['runner']
230         if Logs.verbose > 2:
231                 Logs.zones = ['*']
232
233 # TODO waf 1.6
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
237
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"""
242
243         parser = None
244         # make it possible to access the reference, like Build.bld
245
246         def __init__(self, module=None):
247                 self.parser = create_parser(module)
248                 self.cwd = os.getcwd()
249                 Handler.parser = self
250
251         def add_option(self, *k, **kw):
252                 self.parser.add_option(*k, **kw)
253
254         def add_option_group(self, *k, **kw):
255                 return self.parser.add_option_group(*k, **kw)
256
257         def get_option_group(self, opt_str):
258                 return self.parser.get_option_group(opt_str)
259
260         def sub_options(self, *k, **kw):
261                 if not k: raise Utils.WscriptError('folder expected')
262                 self.recurse(k[0], name='set_options')
263
264         def tool_options(self, *k, **kw):
265                 Utils.python_24_guard()
266
267                 if not k[0]:
268                         raise Utils.WscriptError('invalid tool_options call %r %r' % (k, kw))
269                 tools = Utils.to_list(k[0])
270
271                 # TODO waf 1.6 remove the global variable tooldir
272                 path = Utils.to_list(kw.get('tdir', kw.get('tooldir', tooldir)))
273
274                 for tool in tools:
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)
279                         try:
280                                 fun = module.set_options
281                         except AttributeError:
282                                 pass
283                         else:
284                                 fun(kw.get('option_group', self))
285
286         def parse_args(self, args=None):
287                 parse_args_impl(self.parser, args)