CmdLine.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #
  2. # Cython - Command Line Parsing
  3. #
  4. from __future__ import absolute_import
  5. import os
  6. import sys
  7. from . import Options
  8. usage = """\
  9. Cython (http://cython.org) is a compiler for code written in the
  10. Cython language. Cython is based on Pyrex by Greg Ewing.
  11. Usage: cython [options] sourcefile.{pyx,py} ...
  12. Options:
  13. -V, --version Display version number of cython compiler
  14. -l, --create-listing Write error messages to a listing file
  15. -I, --include-dir <directory> Search for include files in named directory
  16. (multiple include directories are allowed).
  17. -o, --output-file <filename> Specify name of generated C file
  18. -t, --timestamps Only compile newer source files
  19. -f, --force Compile all source files (overrides implied -t)
  20. -v, --verbose Be verbose, print file names on multiple compilation
  21. -p, --embed-positions If specified, the positions in Cython files of each
  22. function definition is embedded in its docstring.
  23. --cleanup <level> Release interned objects on python exit, for memory debugging.
  24. Level indicates aggressiveness, default 0 releases nothing.
  25. -w, --working <directory> Sets the working directory for Cython (the directory modules
  26. are searched from)
  27. --gdb Output debug information for cygdb
  28. --gdb-outdir <directory> Specify gdb debug information output directory. Implies --gdb.
  29. -D, --no-docstrings Strip docstrings from the compiled module.
  30. -a, --annotate Produce a colorized HTML version of the source.
  31. --annotate-coverage <cov.xml> Annotate and include coverage information from cov.xml.
  32. --line-directives Produce #line directives pointing to the .pyx source
  33. --cplus Output a C++ rather than C file.
  34. --embed[=<method_name>] Generate a main() function that embeds the Python interpreter.
  35. -2 Compile based on Python-2 syntax and code semantics.
  36. -3 Compile based on Python-3 syntax and code semantics.
  37. --3str Compile based on Python-3 syntax and code semantics without
  38. assuming unicode by default for string literals under Python 2.
  39. --lenient Change some compile time errors to runtime errors to
  40. improve Python compatibility
  41. --capi-reexport-cincludes Add cincluded headers to any auto-generated header files.
  42. --fast-fail Abort the compilation on the first error
  43. --warning-errors, -Werror Make all warnings into errors
  44. --warning-extra, -Wextra Enable extra warnings
  45. -X, --directive <name>=<value>[,<name=value,...] Overrides a compiler directive
  46. -E, --compile-time-env name=value[,<name=value,...] Provides compile time env like DEF would do.
  47. --module-name Fully qualified module name. If not given, it is deduced from the
  48. import path if source file is in a package, or equals the
  49. filename otherwise.
  50. -M, --depfile Produce depfiles for the sources
  51. """
  52. # The following experimental options are supported only on MacOSX:
  53. # -C, --compile Compile generated .c file to .o file
  54. # --link Link .o file to produce extension module (implies -C)
  55. # -+, --cplus Use C++ compiler for compiling and linking
  56. # Additional .o files to link may be supplied when using -X."""
  57. def bad_usage():
  58. sys.stderr.write(usage)
  59. sys.exit(1)
  60. def parse_command_line(args):
  61. from .Main import CompilationOptions, default_options
  62. pending_arg = []
  63. def pop_arg():
  64. if not args or pending_arg:
  65. bad_usage()
  66. if '=' in args[0] and args[0].startswith('--'): # allow "--long-option=xyz"
  67. name, value = args.pop(0).split('=', 1)
  68. pending_arg.append(value)
  69. return name
  70. return args.pop(0)
  71. def pop_value(default=None):
  72. if pending_arg:
  73. return pending_arg.pop()
  74. elif default is not None:
  75. return default
  76. elif not args:
  77. bad_usage()
  78. return args.pop(0)
  79. def get_param(option):
  80. tail = option[2:]
  81. if tail:
  82. return tail
  83. else:
  84. return pop_arg()
  85. options = CompilationOptions(default_options)
  86. sources = []
  87. while args:
  88. if args[0].startswith("-"):
  89. option = pop_arg()
  90. if option in ("-V", "--version"):
  91. options.show_version = 1
  92. elif option in ("-l", "--create-listing"):
  93. options.use_listing_file = 1
  94. elif option in ("-+", "--cplus"):
  95. options.cplus = 1
  96. elif option == "--embed":
  97. Options.embed = pop_value("main")
  98. elif option.startswith("-I"):
  99. options.include_path.append(get_param(option))
  100. elif option == "--include-dir":
  101. options.include_path.append(pop_value())
  102. elif option in ("-w", "--working"):
  103. options.working_path = pop_value()
  104. elif option in ("-o", "--output-file"):
  105. options.output_file = pop_value()
  106. elif option in ("-t", "--timestamps"):
  107. options.timestamps = 1
  108. elif option in ("-f", "--force"):
  109. options.timestamps = 0
  110. elif option in ("-v", "--verbose"):
  111. options.verbose += 1
  112. elif option in ("-p", "--embed-positions"):
  113. Options.embed_pos_in_docstring = 1
  114. elif option in ("-z", "--pre-import"):
  115. Options.pre_import = pop_value()
  116. elif option == "--cleanup":
  117. Options.generate_cleanup_code = int(pop_value())
  118. elif option in ("-D", "--no-docstrings"):
  119. Options.docstrings = False
  120. elif option in ("-a", "--annotate"):
  121. Options.annotate = True
  122. elif option == "--annotate-coverage":
  123. Options.annotate = True
  124. Options.annotate_coverage_xml = pop_value()
  125. elif option == "--convert-range":
  126. Options.convert_range = True
  127. elif option == "--line-directives":
  128. options.emit_linenums = True
  129. elif option == "--no-c-in-traceback":
  130. options.c_line_in_traceback = False
  131. elif option == "--gdb":
  132. options.gdb_debug = True
  133. options.output_dir = os.curdir
  134. elif option == "--gdb-outdir":
  135. options.gdb_debug = True
  136. options.output_dir = pop_value()
  137. elif option == "--lenient":
  138. Options.error_on_unknown_names = False
  139. Options.error_on_uninitialized = False
  140. elif option == '--init-suffix':
  141. options.init_suffix = pop_arg()
  142. elif option == '--source-root':
  143. Options.source_root = pop_arg()
  144. elif option == '-2':
  145. options.language_level = 2
  146. elif option == '-3':
  147. options.language_level = 3
  148. elif option == '--3str':
  149. options.language_level = '3str'
  150. elif option == "--capi-reexport-cincludes":
  151. options.capi_reexport_cincludes = True
  152. elif option == "--fast-fail":
  153. Options.fast_fail = True
  154. elif option == "--cimport-from-pyx":
  155. Options.cimport_from_pyx = True
  156. elif option in ('-Werror', '--warning-errors'):
  157. Options.warning_errors = True
  158. elif option in ('-Wextra', '--warning-extra'):
  159. options.compiler_directives.update(Options.extra_warnings)
  160. elif option == "--old-style-globals":
  161. Options.old_style_globals = True
  162. elif option == "--directive" or option.startswith('-X'):
  163. if option.startswith('-X') and option[2:].strip():
  164. x_args = option[2:]
  165. else:
  166. x_args = pop_value()
  167. try:
  168. options.compiler_directives = Options.parse_directive_list(
  169. x_args, relaxed_bool=True,
  170. current_settings=options.compiler_directives)
  171. except ValueError as e:
  172. sys.stderr.write("Error in compiler directive: %s\n" % e.args[0])
  173. sys.exit(1)
  174. elif option == "--compile-time-env" or option.startswith('-E'):
  175. if option.startswith('-E') and option[2:].strip():
  176. x_args = option[2:]
  177. else:
  178. x_args = pop_value()
  179. try:
  180. options.compile_time_env = Options.parse_compile_time_env(
  181. x_args, current_settings=options.compile_time_env)
  182. except ValueError as e:
  183. sys.stderr.write("Error in compile-time-env: %s\n" % e.args[0])
  184. sys.exit(1)
  185. elif option == "--module-name":
  186. options.module_name = pop_value()
  187. elif option in ('-M', '--depfile'):
  188. options.depfile = True
  189. elif option.startswith('--debug'):
  190. option = option[2:].replace('-', '_')
  191. from . import DebugFlags
  192. if option in dir(DebugFlags):
  193. setattr(DebugFlags, option, True)
  194. else:
  195. sys.stderr.write("Unknown debug flag: %s\n" % option)
  196. bad_usage()
  197. elif option in ('-h', '--help'):
  198. sys.stdout.write(usage)
  199. sys.exit(0)
  200. else:
  201. sys.stderr.write(usage)
  202. sys.stderr.write("Unknown compiler flag: %s\n" % option)
  203. sys.exit(1)
  204. else:
  205. sources.append(pop_arg())
  206. if pending_arg:
  207. bad_usage()
  208. if options.use_listing_file and len(sources) > 1:
  209. sys.stderr.write(
  210. "cython: Only one source file allowed when using -o\n")
  211. sys.exit(1)
  212. if len(sources) == 0 and not options.show_version:
  213. bad_usage()
  214. if Options.embed and len(sources) > 1:
  215. sys.stderr.write(
  216. "cython: Only one source file allowed when using --embed\n")
  217. sys.exit(1)
  218. if options.module_name:
  219. if options.timestamps:
  220. sys.stderr.write(
  221. "cython: Cannot use --module-name with --timestamps\n")
  222. sys.exit(1)
  223. if len(sources) > 1:
  224. sys.stderr.write(
  225. "cython: Only one source file allowed when using --module-name\n")
  226. sys.exit(1)
  227. return options, sources