From a0a27779ebf0312a2e179d299d5d3732b1259a80 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Fri, 15 Apr 2011 18:22:59 +0200 Subject: [PATCH] moved cythonrun implementation into Cython/Build/BuildExecutable.py to make it generally available --HG-- rename : bin/cythonrun => Cython/Build/BuildExecutable.py --- Cython/Build/BuildExecutable.py | 111 ++++++++++++++++++++++++++++++++ bin/cythonrun | 82 +---------------------- 2 files changed, 114 insertions(+), 79 deletions(-) create mode 100755 Cython/Build/BuildExecutable.py diff --git a/Cython/Build/BuildExecutable.py b/Cython/Build/BuildExecutable.py new file mode 100755 index 00000000..ab47883b --- /dev/null +++ b/Cython/Build/BuildExecutable.py @@ -0,0 +1,111 @@ +""" +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 +import subprocess +from distutils import sysconfig + +INCDIR = sysconfig.get_python_inc() +LIBDIR1 = sysconfig.get_config_var('LIBDIR') +LIBDIR2 = sysconfig.get_config_var('LIBPL') +PYLIB = sysconfig.get_config_var('LIBRARY')[3:-2] + +CC = sysconfig.get_config_var('CC') +CFLAGS = sysconfig.get_config_var('CFLAGS') + ' ' + os.environ.get('CFLAGS', '') +LINKCC = sysconfig.get_config_var('LINKCC') +LINKFORSHARED = sysconfig.get_config_var('LINKFORSHARED') +LIBS = sysconfig.get_config_var('LIBS') +SYSLIBS = sysconfig.get_config_var('SYSLIBS') + +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('CC: %s', CC) + _debug('CFLAGS: %s', CFLAGS) + _debug('LINKCC: %s', LINKCC) + _debug('LINKFORSHARED: %s', LINKFORSHARED) + _debug('LIBS: %s', LIBS) + _debug('SYSLIBS: %s', SYSLIBS) + +def runcmd(cmd, shell=True): + if shell: + cmd = ' '.join(cmd) + _debug(cmd) + else: + _debug(' '.join(cmd)) + + returncode = subprocess.call(cmd, shell=shell) + if returncode: + sys.exit(returncode) + +def clink(basename): + runcmd([LINKCC, '-o', basename, basename+'.o', '-L'+LIBDIR1, '-L'+LIBDIR2, '-l'+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(basename, args=()): + runcmd([os.path.abspath(basename)] + list(args), shell=False) + +def build(input_file, compiler_args=()): + """ + Build an executable program from a Cython module. + + Returns the name of the executable file. + """ + basename = os.path.splitext(input_file)[0] + cycompile(input_file, compiler_args) + ccompile(basename) + clink(basename) + return basename + +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) diff --git a/bin/cythonrun b/bin/cythonrun index 4bdffc06..1c619549 100755 --- a/bin/cythonrun +++ b/bin/cythonrun @@ -9,84 +9,8 @@ Basic usage: python cythonrun somefile.py [ARGS] """ -DEBUG = True - -import sys -import os -import subprocess -from distutils import sysconfig - -INCDIR = sysconfig.get_python_inc() -LIBDIR1 = sysconfig.get_config_var('LIBDIR') -LIBDIR2 = sysconfig.get_config_var('LIBPL') -PYLIB = sysconfig.get_config_var('LIBRARY')[3:-2] - -CC = sysconfig.get_config_var('CC') -CFLAGS = sysconfig.get_config_var('CFLAGS') + ' ' + os.environ.get('CFLAGS', '') -LINKCC = sysconfig.get_config_var('LINKCC') -LINKFORSHARED = sysconfig.get_config_var('LINKFORSHARED') -LIBS = sysconfig.get_config_var('LIBS') -SYSLIBS = sysconfig.get_config_var('SYSLIBS') - -if DEBUG: - def _debug(msg, *args): - if args: - msg = msg % args - sys.stderr.write(msg + '\n') -else: - def _debug(*args): - pass - -_debug('INCDIR: %s', INCDIR) -_debug('LIBDIR1: %s', LIBDIR1) -_debug('LIBDIR2: %s', LIBDIR2) -_debug('PYLIB: %s', PYLIB) - -def runcmd(cmd, shell=True): - if shell: - cmd = ' '.join(cmd) - _debug(cmd) - else: - _debug(' '.join(cmd)) - - returncode = subprocess.call(cmd, shell=shell) - if returncode: - sys.exit(returncode) - -def clink(basename): - runcmd([LINKCC, '-o', basename, basename+'.o', '-L'+LIBDIR1, '-L'+LIBDIR2, '-l'+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(basename, args=()): - runcmd([os.path.abspath(basename)] + list(args), shell=False) - -def main(args): - cy_args = [] - for i, arg in enumerate(args): - if arg.startswith('-'): - cy_args.append(arg) - else: - input_file = arg - args = args[i+1:] - break - else: - raise ValueError('no input file provided') - basename = os.path.splitext(input_file)[0] - cycompile(input_file, cy_args) - ccompile(basename) - clink(basename) - exec_file(basename, args) +from Cython.Build.BuildExecutable import build, build_and_run if __name__ == '__main__': - main(sys.argv[1:]) + import sys + build_and_run(sys.argv[1:]) -- 2.26.2