Index: third_party/cython/src/Cython/Build/BuildExecutable.py |
diff --git a/third_party/cython/src/Cython/Build/BuildExecutable.py b/third_party/cython/src/Cython/Build/BuildExecutable.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6df3135ec1f00de436a4ab12aea69b94a0af3019 |
--- /dev/null |
+++ b/third_party/cython/src/Cython/Build/BuildExecutable.py |
@@ -0,0 +1,139 @@ |
+""" |
+Compile a Python script into an executable that embeds CPython and run it. |
+Requires CPython to be built as a shared library ('libpythonX.Y'). |
+ |
+Basic usage: |
+ |
+ python cythonrun somefile.py [ARGS] |
+""" |
+ |
+DEBUG = True |
+ |
+import sys |
+import os |
+from distutils import sysconfig |
+ |
+def get_config_var(name, default=''): |
+ return sysconfig.get_config_var(name) or default |
+ |
+INCDIR = sysconfig.get_python_inc() |
+LIBDIR1 = get_config_var('LIBDIR') |
+LIBDIR2 = get_config_var('LIBPL') |
+PYLIB = get_config_var('LIBRARY') |
+PYLIB_DYN = get_config_var('LDLIBRARY') |
+if PYLIB_DYN == PYLIB: |
+ # no shared library |
+ PYLIB_DYN = '' |
+else: |
+ PYLIB_DYN = os.path.splitext(PYLIB_DYN[3:])[0] # 'lib(XYZ).so' -> XYZ |
+ |
+CC = get_config_var('CC', os.environ.get('CC', '')) |
+CFLAGS = get_config_var('CFLAGS') + ' ' + os.environ.get('CFLAGS', '') |
+LINKCC = get_config_var('LINKCC', os.environ.get('LINKCC', CC)) |
+LINKFORSHARED = get_config_var('LINKFORSHARED') |
+LIBS = get_config_var('LIBS') |
+SYSLIBS = get_config_var('SYSLIBS') |
+EXE_EXT = sysconfig.get_config_var('EXE') |
+ |
+def _debug(msg, *args): |
+ if DEBUG: |
+ if args: |
+ msg = msg % args |
+ sys.stderr.write(msg + '\n') |
+ |
+def dump_config(): |
+ _debug('INCDIR: %s', INCDIR) |
+ _debug('LIBDIR1: %s', LIBDIR1) |
+ _debug('LIBDIR2: %s', LIBDIR2) |
+ _debug('PYLIB: %s', PYLIB) |
+ _debug('PYLIB_DYN: %s', PYLIB_DYN) |
+ _debug('CC: %s', CC) |
+ _debug('CFLAGS: %s', CFLAGS) |
+ _debug('LINKCC: %s', LINKCC) |
+ _debug('LINKFORSHARED: %s', LINKFORSHARED) |
+ _debug('LIBS: %s', LIBS) |
+ _debug('SYSLIBS: %s', SYSLIBS) |
+ _debug('EXE_EXT: %s', EXE_EXT) |
+ |
+def runcmd(cmd, shell=True): |
+ if shell: |
+ cmd = ' '.join(cmd) |
+ _debug(cmd) |
+ else: |
+ _debug(' '.join(cmd)) |
+ |
+ try: |
+ import subprocess |
+ except ImportError: # Python 2.3 ... |
+ returncode = os.system(cmd) |
+ else: |
+ returncode = subprocess.call(cmd, shell=shell) |
+ |
+ if returncode: |
+ sys.exit(returncode) |
+ |
+def clink(basename): |
+ runcmd([LINKCC, '-o', basename + EXE_EXT, basename+'.o', '-L'+LIBDIR1, '-L'+LIBDIR2] |
+ + [PYLIB_DYN and ('-l'+PYLIB_DYN) or os.path.join(LIBDIR1, PYLIB)] |
+ + LIBS.split() + SYSLIBS.split() + LINKFORSHARED.split()) |
+ |
+def ccompile(basename): |
+ runcmd([CC, '-c', '-o', basename+'.o', basename+'.c', '-I' + INCDIR] + CFLAGS.split()) |
+ |
+def cycompile(input_file, options=()): |
+ from Cython.Compiler import Version, CmdLine, Main |
+ options, sources = CmdLine.parse_command_line(list(options or ()) + ['--embed', input_file]) |
+ _debug('Using Cython %s to compile %s', Version.version, input_file) |
+ result = Main.compile(sources, options) |
+ if result.num_errors > 0: |
+ sys.exit(1) |
+ |
+def exec_file(program_name, args=()): |
+ runcmd([os.path.abspath(program_name)] + list(args), shell=False) |
+ |
+def build(input_file, compiler_args=(), force=False): |
+ """ |
+ Build an executable program from a Cython module. |
+ |
+ Returns the name of the executable file. |
+ """ |
+ basename = os.path.splitext(input_file)[0] |
+ exe_file = basename + EXE_EXT |
+ if not force and os.path.abspath(exe_file) == os.path.abspath(input_file): |
+ raise ValueError("Input and output file names are the same, refusing to overwrite") |
+ if (not force and os.path.exists(exe_file) and os.path.exists(input_file) |
+ and os.path.getmtime(input_file) <= os.path.getmtime(exe_file)): |
+ _debug("File is up to date, not regenerating %s", exe_file) |
+ return exe_file |
+ cycompile(input_file, compiler_args) |
+ ccompile(basename) |
+ clink(basename) |
+ return exe_file |
+ |
+def build_and_run(args): |
+ """ |
+ Build an executable program from a Cython module and runs it. |
+ |
+ Arguments after the module name will be passed verbatimely to the |
+ program. |
+ """ |
+ cy_args = [] |
+ last_arg = None |
+ for i, arg in enumerate(args): |
+ if arg.startswith('-'): |
+ cy_args.append(arg) |
+ elif last_arg in ('-X', '--directive'): |
+ cy_args.append(arg) |
+ else: |
+ input_file = arg |
+ args = args[i+1:] |
+ break |
+ last_arg = arg |
+ else: |
+ raise ValueError('no input file provided') |
+ |
+ program_name = build(input_file, cy_args) |
+ exec_file(program_name, args) |
+ |
+if __name__ == '__main__': |
+ build_and_run(sys.argv[1:]) |