Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / third_party / cython / src / Cython / Build / BuildExecutable.py
blob6df3135ec1f00de436a4ab12aea69b94a0af3019
1 """
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').
5 Basic usage:
7 python cythonrun somefile.py [ARGS]
8 """
10 DEBUG = True
12 import sys
13 import os
14 from distutils import sysconfig
16 def get_config_var(name, default=''):
17 return sysconfig.get_config_var(name) or default
19 INCDIR = sysconfig.get_python_inc()
20 LIBDIR1 = get_config_var('LIBDIR')
21 LIBDIR2 = get_config_var('LIBPL')
22 PYLIB = get_config_var('LIBRARY')
23 PYLIB_DYN = get_config_var('LDLIBRARY')
24 if PYLIB_DYN == PYLIB:
25 # no shared library
26 PYLIB_DYN = ''
27 else:
28 PYLIB_DYN = os.path.splitext(PYLIB_DYN[3:])[0] # 'lib(XYZ).so' -> XYZ
30 CC = get_config_var('CC', os.environ.get('CC', ''))
31 CFLAGS = get_config_var('CFLAGS') + ' ' + os.environ.get('CFLAGS', '')
32 LINKCC = get_config_var('LINKCC', os.environ.get('LINKCC', CC))
33 LINKFORSHARED = get_config_var('LINKFORSHARED')
34 LIBS = get_config_var('LIBS')
35 SYSLIBS = get_config_var('SYSLIBS')
36 EXE_EXT = sysconfig.get_config_var('EXE')
38 def _debug(msg, *args):
39 if DEBUG:
40 if args:
41 msg = msg % args
42 sys.stderr.write(msg + '\n')
44 def dump_config():
45 _debug('INCDIR: %s', INCDIR)
46 _debug('LIBDIR1: %s', LIBDIR1)
47 _debug('LIBDIR2: %s', LIBDIR2)
48 _debug('PYLIB: %s', PYLIB)
49 _debug('PYLIB_DYN: %s', PYLIB_DYN)
50 _debug('CC: %s', CC)
51 _debug('CFLAGS: %s', CFLAGS)
52 _debug('LINKCC: %s', LINKCC)
53 _debug('LINKFORSHARED: %s', LINKFORSHARED)
54 _debug('LIBS: %s', LIBS)
55 _debug('SYSLIBS: %s', SYSLIBS)
56 _debug('EXE_EXT: %s', EXE_EXT)
58 def runcmd(cmd, shell=True):
59 if shell:
60 cmd = ' '.join(cmd)
61 _debug(cmd)
62 else:
63 _debug(' '.join(cmd))
65 try:
66 import subprocess
67 except ImportError: # Python 2.3 ...
68 returncode = os.system(cmd)
69 else:
70 returncode = subprocess.call(cmd, shell=shell)
72 if returncode:
73 sys.exit(returncode)
75 def clink(basename):
76 runcmd([LINKCC, '-o', basename + EXE_EXT, basename+'.o', '-L'+LIBDIR1, '-L'+LIBDIR2]
77 + [PYLIB_DYN and ('-l'+PYLIB_DYN) or os.path.join(LIBDIR1, PYLIB)]
78 + LIBS.split() + SYSLIBS.split() + LINKFORSHARED.split())
80 def ccompile(basename):
81 runcmd([CC, '-c', '-o', basename+'.o', basename+'.c', '-I' + INCDIR] + CFLAGS.split())
83 def cycompile(input_file, options=()):
84 from Cython.Compiler import Version, CmdLine, Main
85 options, sources = CmdLine.parse_command_line(list(options or ()) + ['--embed', input_file])
86 _debug('Using Cython %s to compile %s', Version.version, input_file)
87 result = Main.compile(sources, options)
88 if result.num_errors > 0:
89 sys.exit(1)
91 def exec_file(program_name, args=()):
92 runcmd([os.path.abspath(program_name)] + list(args), shell=False)
94 def build(input_file, compiler_args=(), force=False):
95 """
96 Build an executable program from a Cython module.
98 Returns the name of the executable file.
99 """
100 basename = os.path.splitext(input_file)[0]
101 exe_file = basename + EXE_EXT
102 if not force and os.path.abspath(exe_file) == os.path.abspath(input_file):
103 raise ValueError("Input and output file names are the same, refusing to overwrite")
104 if (not force and os.path.exists(exe_file) and os.path.exists(input_file)
105 and os.path.getmtime(input_file) <= os.path.getmtime(exe_file)):
106 _debug("File is up to date, not regenerating %s", exe_file)
107 return exe_file
108 cycompile(input_file, compiler_args)
109 ccompile(basename)
110 clink(basename)
111 return exe_file
113 def build_and_run(args):
115 Build an executable program from a Cython module and runs it.
117 Arguments after the module name will be passed verbatimely to the
118 program.
120 cy_args = []
121 last_arg = None
122 for i, arg in enumerate(args):
123 if arg.startswith('-'):
124 cy_args.append(arg)
125 elif last_arg in ('-X', '--directive'):
126 cy_args.append(arg)
127 else:
128 input_file = arg
129 args = args[i+1:]
130 break
131 last_arg = arg
132 else:
133 raise ValueError('no input file provided')
135 program_name = build(input_file, cy_args)
136 exec_file(program_name, args)
138 if __name__ == '__main__':
139 build_and_run(sys.argv[1:])