jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

270 lines
8.3KB

  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3. # Scott Newton, 2005 (scottn)
  4. # Thomas Nagy, 2006-2010 (ita)
  5. """
  6. Support for waf command-line options
  7. Provides default command-line options,
  8. as well as custom ones, used by the ``options`` wscript function.
  9. """
  10. import os, tempfile, optparse, sys, re
  11. from waflib import Logs, Utils, Context
  12. cmds = 'distclean configure build install clean uninstall check dist distcheck'.split()
  13. """
  14. Constant representing the default waf commands displayed in::
  15. $ waf --help
  16. """
  17. options = {}
  18. """
  19. A dictionary representing the command-line options::
  20. $ waf --foo=bar
  21. """
  22. commands = []
  23. """
  24. List of commands to execute extracted from the command-line. This list is consumed during the execution, see :py:func:`waflib.Scripting.run_commands`.
  25. """
  26. envvars = []
  27. """
  28. List of environment variable declarations placed after the Waf executable name.
  29. These are detected by searching for "=" in the rest arguments.
  30. """
  31. lockfile = os.environ.get('WAFLOCK', '.lock-waf_%s_build' % sys.platform)
  32. platform = Utils.unversioned_sys_platform()
  33. class opt_parser(optparse.OptionParser):
  34. """
  35. Command-line options parser.
  36. """
  37. def __init__(self, ctx):
  38. optparse.OptionParser.__init__(self, conflict_handler="resolve", version='waf %s (%s)' % (Context.WAFVERSION, Context.WAFREVISION))
  39. self.formatter.width = Logs.get_term_cols()
  40. self.ctx = ctx
  41. def print_usage(self, file=None):
  42. return self.print_help(file)
  43. def get_usage(self):
  44. """
  45. Return the message to print on ``waf --help``
  46. """
  47. cmds_str = {}
  48. for cls in Context.classes:
  49. if not cls.cmd or cls.cmd == 'options' or cls.cmd.startswith( '_' ):
  50. continue
  51. s = cls.__doc__ or ''
  52. cmds_str[cls.cmd] = s
  53. if Context.g_module:
  54. for (k, v) in Context.g_module.__dict__.items():
  55. if k in ('options', 'init', 'shutdown'):
  56. continue
  57. if type(v) is type(Context.create_context):
  58. if v.__doc__ and not k.startswith('_'):
  59. cmds_str[k] = v.__doc__
  60. just = 0
  61. for k in cmds_str:
  62. just = max(just, len(k))
  63. lst = [' %s: %s' % (k.ljust(just), v) for (k, v) in cmds_str.items()]
  64. lst.sort()
  65. ret = '\n'.join(lst)
  66. return '''waf [commands] [options]
  67. Main commands (example: ./waf build -j4)
  68. %s
  69. ''' % ret
  70. class OptionsContext(Context.Context):
  71. """
  72. Collect custom options from wscript files and parses the command line.
  73. Set the global :py:const:`waflib.Options.commands` and :py:const:`waflib.Options.options` values.
  74. """
  75. cmd = 'options'
  76. fun = 'options'
  77. def __init__(self, **kw):
  78. super(OptionsContext, self).__init__(**kw)
  79. self.parser = opt_parser(self)
  80. """Instance of :py:class:`waflib.Options.opt_parser`"""
  81. self.option_groups = {}
  82. jobs = self.jobs()
  83. p = self.add_option
  84. color = os.environ.get('NOCOLOR', '') and 'no' or 'auto'
  85. p('-c', '--color', dest='colors', default=color, action='store', help='whether to use colors (yes/no/auto) [default: auto]', choices=('yes', 'no', 'auto'))
  86. p('-j', '--jobs', dest='jobs', default=jobs, type='int', help='amount of parallel jobs (%r)' % jobs)
  87. p('-k', '--keep', dest='keep', default=0, action='count', help='continue despite errors (-kk to try harder)')
  88. p('-v', '--verbose', dest='verbose', default=0, action='count', help='verbosity level -v -vv or -vvv [default: 0]')
  89. p('--zones', dest='zones', default='', action='store', help='debugging zones (task_gen, deps, tasks, etc)')
  90. gr = self.add_option_group('Configuration options')
  91. self.option_groups['configure options'] = gr
  92. gr.add_option('-o', '--out', action='store', default='', help='build dir for the project', dest='out')
  93. gr.add_option('-t', '--top', action='store', default='', help='src dir for the project', dest='top')
  94. default_prefix = getattr(Context.g_module, 'default_prefix', os.environ.get('PREFIX'))
  95. if not default_prefix:
  96. if platform == 'win32':
  97. d = tempfile.gettempdir()
  98. default_prefix = d[0].upper() + d[1:]
  99. # win32 preserves the case, but gettempdir does not
  100. else:
  101. default_prefix = '/usr/local/'
  102. gr.add_option('--prefix', dest='prefix', default=default_prefix, help='installation prefix [default: %r]' % default_prefix)
  103. gr.add_option('--bindir', dest='bindir', help='bindir')
  104. gr.add_option('--libdir', dest='libdir', help='libdir')
  105. gr = self.add_option_group('Build and installation options')
  106. self.option_groups['build and install options'] = gr
  107. gr.add_option('-p', '--progress', dest='progress_bar', default=0, action='count', help= '-p: progress bar; -pp: ide output')
  108. gr.add_option('--targets', dest='targets', default='', action='store', help='task generators, e.g. "target1,target2"')
  109. gr = self.add_option_group('Step options')
  110. self.option_groups['step options'] = gr
  111. gr.add_option('--files', dest='files', default='', action='store', help='files to process, by regexp, e.g. "*/main.c,*/test/main.o"')
  112. default_destdir = os.environ.get('DESTDIR', '')
  113. gr = self.add_option_group('Installation and uninstallation options')
  114. self.option_groups['install/uninstall options'] = gr
  115. gr.add_option('--destdir', help='installation root [default: %r]' % default_destdir, default=default_destdir, dest='destdir')
  116. gr.add_option('-f', '--force', dest='force', default=False, action='store_true', help='force file installation')
  117. gr.add_option('--distcheck-args', metavar='ARGS', help='arguments to pass to distcheck', default=None, action='store')
  118. def jobs(self):
  119. """
  120. Find the amount of cpu cores to set the default amount of tasks executed in parallel. At
  121. runtime the options can be obtained from :py:const:`waflib.Options.options` ::
  122. from waflib.Options import options
  123. njobs = options.jobs
  124. :return: the amount of cpu cores
  125. :rtype: int
  126. """
  127. count = int(os.environ.get('JOBS', 0))
  128. if count < 1:
  129. if 'NUMBER_OF_PROCESSORS' in os.environ:
  130. # on Windows, use the NUMBER_OF_PROCESSORS environment variable
  131. count = int(os.environ.get('NUMBER_OF_PROCESSORS', 1))
  132. else:
  133. # on everything else, first try the POSIX sysconf values
  134. if hasattr(os, 'sysconf_names'):
  135. if 'SC_NPROCESSORS_ONLN' in os.sysconf_names:
  136. count = int(os.sysconf('SC_NPROCESSORS_ONLN'))
  137. elif 'SC_NPROCESSORS_CONF' in os.sysconf_names:
  138. count = int(os.sysconf('SC_NPROCESSORS_CONF'))
  139. if not count and os.name not in ('nt', 'java'):
  140. try:
  141. tmp = self.cmd_and_log(['sysctl', '-n', 'hw.ncpu'], quiet=0)
  142. except Exception:
  143. pass
  144. else:
  145. if re.match('^[0-9]+$', tmp):
  146. count = int(tmp)
  147. if count < 1:
  148. count = 1
  149. elif count > 1024:
  150. count = 1024
  151. return count
  152. def add_option(self, *k, **kw):
  153. """
  154. Wrapper for optparse.add_option::
  155. def options(ctx):
  156. ctx.add_option('-u', '--use', dest='use', default=False, action='store_true',
  157. help='a boolean option')
  158. """
  159. return self.parser.add_option(*k, **kw)
  160. def add_option_group(self, *k, **kw):
  161. """
  162. Wrapper for optparse.add_option_group::
  163. def options(ctx):
  164. gr = ctx.add_option_group('some options')
  165. gr.add_option('-u', '--use', dest='use', default=False, action='store_true')
  166. """
  167. try:
  168. gr = self.option_groups[k[0]]
  169. except KeyError:
  170. gr = self.parser.add_option_group(*k, **kw)
  171. self.option_groups[k[0]] = gr
  172. return gr
  173. def get_option_group(self, opt_str):
  174. """
  175. Wrapper for optparse.get_option_group::
  176. def options(ctx):
  177. gr = ctx.get_option_group('configure options')
  178. gr.add_option('-o', '--out', action='store', default='',
  179. help='build dir for the project', dest='out')
  180. """
  181. try:
  182. return self.option_groups[opt_str]
  183. except KeyError:
  184. for group in self.parser.option_groups:
  185. if group.title == opt_str:
  186. return group
  187. return None
  188. def parse_args(self, _args=None):
  189. """
  190. Parse arguments from a list (not bound to the command-line).
  191. :param _args: arguments
  192. :type _args: list of strings
  193. """
  194. global options, commands, envvars
  195. (options, leftover_args) = self.parser.parse_args(args=_args)
  196. for arg in leftover_args:
  197. if '=' in arg:
  198. envvars.append(arg)
  199. else:
  200. commands.append(arg)
  201. if options.destdir:
  202. options.destdir = os.path.abspath(os.path.expanduser(options.destdir))
  203. if options.verbose >= 1:
  204. self.load('errcheck')
  205. colors = {'yes' : 2, 'auto' : 1, 'no' : 0}[options.colors]
  206. Logs.enable_colors(colors)
  207. def execute(self):
  208. """
  209. See :py:func:`waflib.Context.Context.execute`
  210. """
  211. super(OptionsContext, self).execute()
  212. self.parse_args()