2 Compile a Python script into an executable that embeds CPython and run it.
3 Requires CPython to be built as a shared library ('libpythonX.Y').
7 python cythonrun somefile.py [ARGS]
14 from distutils import sysconfig
16 def get_config_var(name):
17 return sysconfig.get_config_var(name) or ''
19 INCDIR = sysconfig.get_python_inc()
20 LIBDIR1 = get_config_var('LIBDIR')
21 LIBDIR2 = get_config_var('LIBPL')
22 PYLIB = get_config_var('LIBRARY')
24 CC = get_config_var('CC')
25 CFLAGS = get_config_var('CFLAGS') + ' ' + os.environ.get('CFLAGS', '')
26 LINKCC = get_config_var('LINKCC')
27 LINKFORSHARED = get_config_var('LINKFORSHARED')
28 LIBS = get_config_var('LIBS')
29 SYSLIBS = get_config_var('SYSLIBS')
31 def _debug(msg, *args):
35 sys.stderr.write(msg + '\n')
38 _debug('INCDIR: %s', INCDIR)
39 _debug('LIBDIR1: %s', LIBDIR1)
40 _debug('LIBDIR2: %s', LIBDIR2)
41 _debug('PYLIB: %s', PYLIB)
43 _debug('CFLAGS: %s', CFLAGS)
44 _debug('LINKCC: %s', LINKCC)
45 _debug('LINKFORSHARED: %s', LINKFORSHARED)
46 _debug('LIBS: %s', LIBS)
47 _debug('SYSLIBS: %s', SYSLIBS)
49 def runcmd(cmd, shell=True):
58 except ImportError: # Python 2.3 ...
59 returncode = os.system(cmd)
61 returncode = subprocess.call(cmd, shell=shell)
67 runcmd([LINKCC, '-o', basename, basename+'.o', '-L'+LIBDIR1, '-L'+LIBDIR2,
68 os.path.join(LIBDIR1, PYLIB)]
69 + LIBS.split() + SYSLIBS.split() + LINKFORSHARED.split())
71 def ccompile(basename):
72 runcmd([CC, '-c', '-o', basename+'.o', basename+'.c', '-I' + INCDIR] + CFLAGS.split())
74 def cycompile(input_file, options=()):
75 from Cython.Compiler import Version, CmdLine, Main
76 options, sources = CmdLine.parse_command_line(list(options or ()) + ['--embed', input_file])
77 _debug('Using Cython %s to compile %s', Version.version, input_file)
78 result = Main.compile(sources, options)
79 if result.num_errors > 0:
82 def exec_file(basename, args=()):
83 runcmd([os.path.abspath(basename)] + list(args), shell=False)
85 def build(input_file, compiler_args=()):
87 Build an executable program from a Cython module.
89 Returns the name of the executable file.
91 basename = os.path.splitext(input_file)[0]
92 cycompile(input_file, compiler_args)
97 def build_and_run(args):
99 Build an executable program from a Cython module and runs it.
101 Arguments after the module name will be passed verbatimely to the
106 for i, arg in enumerate(args):
107 if arg.startswith('-'):
109 elif last_arg in ('-X', '--directive'):
117 raise ValueError('no input file provided')
119 program_name = build(input_file, cy_args)
120 exec_file(program_name, args)
122 if __name__ == '__main__':
123 build_and_run(sys.argv[1:])