diff options
Diffstat (limited to 'Cython/Build/BuildExecutable.py')
-rw-r--r-- | Cython/Build/BuildExecutable.py | 73 |
1 files changed, 44 insertions, 29 deletions
diff --git a/Cython/Build/BuildExecutable.py b/Cython/Build/BuildExecutable.py index 2db9e5d74..334fbf069 100644 --- a/Cython/Build/BuildExecutable.py +++ b/Cython/Build/BuildExecutable.py @@ -1,10 +1,10 @@ """ -Compile a Python script into an executable that embeds CPython and run it. +Compile a Python script into an executable that embeds CPython. Requires CPython to be built as a shared library ('libpythonX.Y'). Basic usage: - python cythonrun somefile.py [ARGS] + python -m Cython.Build.BuildExecutable [ARGS] somefile.py """ from __future__ import absolute_import @@ -28,7 +28,7 @@ if PYLIB_DYN == PYLIB: # no shared library PYLIB_DYN = '' else: - PYLIB_DYN = os.path.splitext(PYLIB_DYN[3:])[0] # 'lib(XYZ).so' -> XYZ + 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', '') @@ -38,12 +38,14 @@ 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) @@ -58,6 +60,26 @@ def dump_config(): _debug('SYSLIBS: %s', SYSLIBS) _debug('EXE_EXT: %s', EXE_EXT) + +def _parse_args(args): + 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') + + return input_file, cy_args, args + + def runcmd(cmd, shell=True): if shell: cmd = ' '.join(cmd) @@ -65,24 +87,23 @@ def runcmd(cmd, shell=True): else: _debug(' '.join(cmd)) - try: - import subprocess - except ImportError: # Python 2.3 ... - returncode = os.system(cmd) - else: - returncode = subprocess.call(cmd, shell=shell) + import subprocess + 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 ..Compiler import Version, CmdLine, Main options, sources = CmdLine.parse_command_line(list(options or ()) + ['--embed', input_file]) @@ -91,9 +112,11 @@ def cycompile(input_file, 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. @@ -105,7 +128,7 @@ def build(input_file, compiler_args=(), force=False): 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)): + 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) @@ -113,30 +136,22 @@ def build(input_file, compiler_args=(), force=False): clink(basename) return exe_file + def build_and_run(args): """ - Build an executable program from a Cython module and runs it. + Build an executable program from a Cython module and run it. - Arguments after the module name will be passed verbatimely to the - program. + Arguments after the module name will be passed verbatimly 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, args = _build(args) + exec_file(program_name, args) + +def _build(args): + input_file, cy_args, args = _parse_args(args) program_name = build(input_file, cy_args) - exec_file(program_name, args) + return program_name, args + if __name__ == '__main__': - build_and_run(sys.argv[1:]) + _build(sys.argv[1:]) |