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