blob: d66e1e2708e758de448e1d31923294272761fdc0 [file] [log] [blame]
Benjamin Peterson90f5ba52010-03-11 22:53:45 +00001#! /usr/bin/env python3
Guido van Rossumdbaf3321994-10-03 10:25:54 +00002
Guido van Rossum96c4dd91996-08-26 05:14:20 +00003"""Freeze a Python script into a binary.
Guido van Rossumdbaf3321994-10-03 10:25:54 +00004
Guido van Rossum1e074031998-03-05 04:05:38 +00005usage: freeze [options...] script [module]...
Guido van Rossum00ff4331994-10-03 16:33:08 +00006
Guido van Rossum96c4dd91996-08-26 05:14:20 +00007Options:
Guido van Rossum9a6e8551997-08-10 16:47:17 +00008-p prefix: This is the prefix used when you ran ``make install''
Guido van Rossum96c4dd91996-08-26 05:14:20 +00009 in the Python build directory.
Guido van Rossumd8336c21994-10-05 16:13:01 +000010 (If you never ran this, freeze won't work.)
Guido van Rossum96c4dd91996-08-26 05:14:20 +000011 The default is whatever sys.prefix evaluates to.
Guido van Rossum0b4b8a21997-08-10 16:56:48 +000012 It can also be the top directory of the Python source
13 tree; then -P must point to the build tree.
Guido van Rossumd8336c21994-10-05 16:13:01 +000014
Guido van Rossum150316e1995-08-08 14:21:07 +000015-P exec_prefix: Like -p but this is the 'exec_prefix', used to
Guido van Rossum0b4b8a21997-08-10 16:56:48 +000016 install objects etc. The default is whatever sys.exec_prefix
17 evaluates to, or the -p argument if given.
18 If -p points to the Python source tree, -P must point
19 to the build tree, if different.
Guido van Rossum150316e1995-08-08 14:21:07 +000020
Guido van Rossumd8336c21994-10-05 16:13:01 +000021-e extension: A directory containing additional .o files that
22 may be used to resolve modules. This directory
23 should also have a Setup file describing the .o files.
Guido van Rossumbaf06031998-08-25 14:06:55 +000024 On Windows, the name of a .INI file describing one
25 or more extensions is passed.
Guido van Rossumd8336c21994-10-05 16:13:01 +000026 More than one -e option may be given.
27
Guido van Rossum96c4dd91996-08-26 05:14:20 +000028-o dir: Directory where the output files are created; default '.'.
29
Guido van Rossum75dc4961998-03-05 03:42:00 +000030-m: Additional arguments are module names instead of filenames.
31
Guido van Rossume35c6011998-05-18 20:25:54 +000032-a package=dir: Additional directories to be added to the package's
33 __path__. Used to simulate directories added by the
34 package at runtime (eg, by OpenGL and win32com).
35 More than one -a option may be given for each package.
36
Guido van Rossum78fc3631998-03-20 17:37:24 +000037-l file: Pass the file to the linker (windows only)
38
Guido van Rossum75dc4961998-03-05 03:42:00 +000039-d: Debugging mode for the module finder.
40
41-q: Make the module finder totally quiet.
42
Guido van Rossum9a6e8551997-08-10 16:47:17 +000043-h: Print this help message.
44
Guido van Rossum03f7f082001-10-18 19:15:32 +000045-x module Exclude the specified module. It will still be imported
46 by the frozen binary if it exists on the host system.
47
48-X module Like -x, except the module can never be imported by
49 the frozen binary.
50
51-E: Freeze will fail if any modules can't be found (that
52 were not excluded using -x or -X).
Guido van Rossum78fc3631998-03-20 17:37:24 +000053
Guido van Rossumbaf06031998-08-25 14:06:55 +000054-i filename: Include a file with additional command line options. Used
55 to prevent command lines growing beyond the capabilities of
56 the shell/OS. All arguments specified in filename
57 are read and the -i option replaced with the parsed
58 params (note - quoting args in this file is NOT supported)
59
Tim Peters182b5ac2004-07-18 06:16:08 +000060-s subsystem: Specify the subsystem (For Windows only.);
Guido van Rossum78fc3631998-03-20 17:37:24 +000061 'console' (default), 'windows', 'service' or 'com_dll'
Tim Peters182b5ac2004-07-18 06:16:08 +000062
Guido van Rossumbaf06031998-08-25 14:06:55 +000063-w: Toggle Windows (NT or 95) behavior.
Thomas Wouters7e474022000-07-16 12:04:32 +000064 (For debugging only -- on a win32 platform, win32 behavior
Guido van Rossumbaf06031998-08-25 14:06:55 +000065 is automatic.)
Guido van Rossum58a59481997-08-14 01:45:33 +000066
Guido van Rossum6b767ac2001-03-20 20:43:34 +000067-r prefix=f: Replace path prefix.
Tim Peters182b5ac2004-07-18 06:16:08 +000068 Replace prefix with f in the source path references
Guido van Rossum6b767ac2001-03-20 20:43:34 +000069 contained in the resulting binary.
70
Guido van Rossum96c4dd91996-08-26 05:14:20 +000071Arguments:
72
Guido van Rossum1e074031998-03-05 04:05:38 +000073script: The Python script to be executed by the resulting binary.
Guido van Rossumd8336c21994-10-05 16:13:01 +000074
75module ...: Additional Python modules (referenced by pathname)
76 that will be included in the resulting binary. These
Guido van Rossum75dc4961998-03-05 03:42:00 +000077 may be .py or .pyc files. If -m is specified, these are
78 module names that are search in the path instead.
Guido van Rossum150316e1995-08-08 14:21:07 +000079
80NOTES:
81
82In order to use freeze successfully, you must have built Python and
Guido van Rossumd4cc04c1996-06-17 17:49:13 +000083installed it ("make install").
Guido van Rossum150316e1995-08-08 14:21:07 +000084
Guido van Rossum96c4dd91996-08-26 05:14:20 +000085The script should not use modules provided only as shared libraries;
86if it does, the resulting binary is not self-contained.
Guido van Rossumd8336c21994-10-05 16:13:01 +000087"""
Guido van Rossum00ff4331994-10-03 16:33:08 +000088
89
Guido van Rossum00ff4331994-10-03 16:33:08 +000090# Import standard modules
91
Gustavo Niemeyer7b4abbb2003-05-26 23:52:30 +000092import modulefinder
Guido van Rossumdbaf3321994-10-03 10:25:54 +000093import getopt
Guido van Rossum00ff4331994-10-03 16:33:08 +000094import os
Guido van Rossum00ff4331994-10-03 16:33:08 +000095import sys
Victor Stinner1c653f12020-12-16 12:12:36 +010096import sysconfig
Guido van Rossumdbaf3321994-10-03 10:25:54 +000097
Guido van Rossumdbaf3321994-10-03 10:25:54 +000098
Guido van Rossum00ff4331994-10-03 16:33:08 +000099# Import the freeze-private modules
100
Guido van Rossumd8336c21994-10-05 16:13:01 +0000101import checkextensions
Guido van Rossum00ff4331994-10-03 16:33:08 +0000102import makeconfig
103import makefreeze
104import makemakefile
105import parsesetup
Guido van Rossumbaf06031998-08-25 14:06:55 +0000106import bkfile
Guido van Rossum00ff4331994-10-03 16:33:08 +0000107
Guido van Rossum00ff4331994-10-03 16:33:08 +0000108
109# Main program
110
Guido van Rossumdbaf3321994-10-03 10:25:54 +0000111def main():
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000112 # overridable context
113 prefix = None # settable with -p option
114 exec_prefix = None # settable with -P option
115 extensions = []
Guido van Rossum78fc3631998-03-20 17:37:24 +0000116 exclude = [] # settable with -x option
Guido van Rossume35c6011998-05-18 20:25:54 +0000117 addn_link = [] # settable with -l, but only honored under Windows.
Guido van Rossum1e074031998-03-05 04:05:38 +0000118 path = sys.path[:]
Guido van Rossum75dc4961998-03-05 03:42:00 +0000119 modargs = 0
120 debug = 1
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000121 odir = ''
Guido van Rossum58a59481997-08-14 01:45:33 +0000122 win = sys.platform[:3] == 'win'
Guido van Rossum6b767ac2001-03-20 20:43:34 +0000123 replace_paths = [] # settable with -r option
Guido van Rossum03f7f082001-10-18 19:15:32 +0000124 error_if_any_missing = 0
Guido van Rossum00ff4331994-10-03 16:33:08 +0000125
Guido van Rossum78fc3631998-03-20 17:37:24 +0000126 # default the exclude list for each platform
Guido van Rossumbaf06031998-08-25 14:06:55 +0000127 if win: exclude = exclude + [
Victor Stinnerd7538dd2018-12-14 13:37:26 +0100128 'dos', 'dospath', 'mac', 'macfs', 'MACFS', 'posix', ]
Guido van Rossum03f7f082001-10-18 19:15:32 +0000129
130 fail_import = exclude[:]
Guido van Rossum78fc3631998-03-20 17:37:24 +0000131
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000132 # output files
133 frozen_c = 'frozen.c'
134 config_c = 'config.c'
135 target = 'a.out' # normally derived from script name
136 makefile = 'Makefile'
Guido van Rossum58a59481997-08-14 01:45:33 +0000137 subsystem = 'console'
Guido van Rossum00ff4331994-10-03 16:33:08 +0000138
Guido van Rossum03f7f082001-10-18 19:15:32 +0000139 # parse command line by first replacing any "-i" options with the
140 # file contents.
Guido van Rossumbaf06031998-08-25 14:06:55 +0000141 pos = 1
Guido van Rossum03f7f082001-10-18 19:15:32 +0000142 while pos < len(sys.argv)-1:
143 # last option can not be "-i", so this ensures "pos+1" is in range!
Guido van Rossumbaf06031998-08-25 14:06:55 +0000144 if sys.argv[pos] == '-i':
145 try:
Serhiy Storchaka172bb392019-03-30 08:33:02 +0200146 with open(sys.argv[pos+1]) as infp:
147 options = infp.read().split()
Guido van Rossumb940e112007-01-10 16:19:56 +0000148 except IOError as why:
Guido van Rossum03f7f082001-10-18 19:15:32 +0000149 usage("File name '%s' specified with the -i option "
150 "can not be read - %s" % (sys.argv[pos+1], why) )
Guido van Rossumbaf06031998-08-25 14:06:55 +0000151 # Replace the '-i' and the filename with the read params.
152 sys.argv[pos:pos+2] = options
153 pos = pos + len(options) - 1 # Skip the name and the included args.
154 pos = pos + 1
155
156 # Now parse the command line with the extras inserted.
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000157 try:
Guido van Rossum03f7f082001-10-18 19:15:32 +0000158 opts, args = getopt.getopt(sys.argv[1:], 'r:a:dEe:hmo:p:P:qs:wX:x:l:')
Guido van Rossumb940e112007-01-10 16:19:56 +0000159 except getopt.error as msg:
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000160 usage('getopt error: ' + str(msg))
Guido van Rossum00ff4331994-10-03 16:33:08 +0000161
Martin Pantereb995702016-07-28 01:11:04 +0000162 # process option arguments
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000163 for o, a in opts:
164 if o == '-h':
Guido van Rossum96bf7e82007-02-09 23:27:01 +0000165 print(__doc__)
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000166 return
Guido van Rossum75dc4961998-03-05 03:42:00 +0000167 if o == '-d':
168 debug = debug + 1
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000169 if o == '-e':
170 extensions.append(a)
Guido van Rossum75dc4961998-03-05 03:42:00 +0000171 if o == '-m':
172 modargs = 1
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000173 if o == '-o':
174 odir = a
175 if o == '-p':
176 prefix = a
177 if o == '-P':
178 exec_prefix = a
Guido van Rossum75dc4961998-03-05 03:42:00 +0000179 if o == '-q':
180 debug = 0
Guido van Rossum58a59481997-08-14 01:45:33 +0000181 if o == '-w':
182 win = not win
183 if o == '-s':
184 if not win:
185 usage("-s subsystem option only on Windows")
186 subsystem = a
Guido van Rossum78fc3631998-03-20 17:37:24 +0000187 if o == '-x':
188 exclude.append(a)
Guido van Rossum03f7f082001-10-18 19:15:32 +0000189 if o == '-X':
190 exclude.append(a)
191 fail_import.append(a)
192 if o == '-E':
193 error_if_any_missing = 1
Guido van Rossum78fc3631998-03-20 17:37:24 +0000194 if o == '-l':
195 addn_link.append(a)
Guido van Rossume35c6011998-05-18 20:25:54 +0000196 if o == '-a':
Neal Norwitzd9108552006-03-17 08:00:19 +0000197 modulefinder.AddPackagePath(*a.split("=", 2))
Guido van Rossum6b767ac2001-03-20 20:43:34 +0000198 if o == '-r':
Walter Dörwaldaaab30e2002-09-11 20:36:02 +0000199 f,r = a.split("=", 2)
Guido van Rossum6b767ac2001-03-20 20:43:34 +0000200 replace_paths.append( (f,r) )
Guido van Rossumdbaf3321994-10-03 10:25:54 +0000201
Just van Rossume9e20a92003-03-08 19:50:38 +0000202 # modules that are imported by the Python runtime
203 implicits = []
Georg Brandl00639582010-08-02 22:25:16 +0000204 for module in ('site', 'warnings', 'encodings.utf_8', 'encodings.latin_1'):
Just van Rossume9e20a92003-03-08 19:50:38 +0000205 if module not in exclude:
206 implicits.append(module)
207
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000208 # default prefix and exec_prefix
209 if not exec_prefix:
210 if prefix:
211 exec_prefix = prefix
212 else:
213 exec_prefix = sys.exec_prefix
214 if not prefix:
215 prefix = sys.prefix
Guido van Rossum9a6e8551997-08-10 16:47:17 +0000216
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000217 # determine whether -p points to the Python source tree
Guido van Rossume0394251998-03-05 05:39:50 +0000218 ishome = os.path.exists(os.path.join(prefix, 'Python', 'ceval.c'))
Guido van Rossumdbaf3321994-10-03 10:25:54 +0000219
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000220 # locations derived from options
Serhiy Storchaka885bdc42016-02-11 13:10:36 +0200221 version = '%d.%d' % sys.version_info[:2]
AraHaana7987e72019-03-23 12:29:49 -0400222 if hasattr(sys, 'abiflags'):
223 flagged_version = version + sys.abiflags
224 else:
225 flagged_version = version
Guido van Rossum5e32a771998-07-07 22:47:38 +0000226 if win:
227 extensions_c = 'frozen_extensions.c'
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000228 if ishome:
Guido van Rossum96bf7e82007-02-09 23:27:01 +0000229 print("(Using Python source directory)")
Victor Stinner1c653f12020-12-16 12:12:36 +0100230 configdir = exec_prefix
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000231 incldir = os.path.join(prefix, 'Include')
Guido van Rossum590fc2c1998-06-12 14:09:03 +0000232 config_h_dir = exec_prefix
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000233 config_c_in = os.path.join(prefix, 'Modules', 'config.c.in')
Guido van Rossum58a59481997-08-14 01:45:33 +0000234 frozenmain_c = os.path.join(prefix, 'Python', 'frozenmain.c')
Gustavo Niemeyerffa5a502004-05-08 17:59:43 +0000235 makefile_in = os.path.join(exec_prefix, 'Makefile')
Guido van Rossume35c6011998-05-18 20:25:54 +0000236 if win:
237 frozendllmain_c = os.path.join(exec_prefix, 'Pc\\frozen_dllmain.c')
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000238 else:
Victor Stinner1c653f12020-12-16 12:12:36 +0100239 configdir = sysconfig.get_config_var('LIBPL')
Martin v. Löwisa7fcd922014-03-30 20:28:52 +0200240 incldir = os.path.join(prefix, 'include', 'python%s' % flagged_version)
Guido van Rossum590fc2c1998-06-12 14:09:03 +0000241 config_h_dir = os.path.join(exec_prefix, 'include',
Martin v. Löwisa7fcd922014-03-30 20:28:52 +0200242 'python%s' % flagged_version)
Victor Stinner1c653f12020-12-16 12:12:36 +0100243 config_c_in = os.path.join(configdir, 'config.c.in')
244 frozenmain_c = os.path.join(configdir, 'frozenmain.c')
245 makefile_in = os.path.join(configdir, 'Makefile')
246 frozendllmain_c = os.path.join(configdir, 'frozen_dllmain.c')
247 libdir = sysconfig.get_config_var('LIBDIR')
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000248 supp_sources = []
249 defines = []
Guido van Rossum590fc2c1998-06-12 14:09:03 +0000250 includes = ['-I' + incldir, '-I' + config_h_dir]
Guido van Rossumd8336c21994-10-05 16:13:01 +0000251
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000252 # sanity check of directories and files
Victor Stinner1c653f12020-12-16 12:12:36 +0100253 check_dirs = [prefix, exec_prefix, configdir, incldir]
Guido van Rossum03f7f082001-10-18 19:15:32 +0000254 if not win:
255 # These are not directories on Windows.
256 check_dirs = check_dirs + extensions
Guido van Rossumbaf06031998-08-25 14:06:55 +0000257 for dir in check_dirs:
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000258 if not os.path.exists(dir):
259 usage('needed directory %s not found' % dir)
260 if not os.path.isdir(dir):
261 usage('%s: not a directory' % dir)
Guido van Rossum58a59481997-08-14 01:45:33 +0000262 if win:
Guido van Rossumbaf06031998-08-25 14:06:55 +0000263 files = supp_sources + extensions # extensions are files on Windows.
Guido van Rossum58a59481997-08-14 01:45:33 +0000264 else:
265 files = [config_c_in, makefile_in] + supp_sources
266 for file in supp_sources:
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000267 if not os.path.exists(file):
268 usage('needed file %s not found' % file)
269 if not os.path.isfile(file):
270 usage('%s: not a plain file' % file)
Guido van Rossum58a59481997-08-14 01:45:33 +0000271 if not win:
272 for dir in extensions:
273 setup = os.path.join(dir, 'Setup')
274 if not os.path.exists(setup):
275 usage('needed file %s not found' % setup)
276 if not os.path.isfile(setup):
277 usage('%s: not a plain file' % setup)
Guido van Rossum00ff4331994-10-03 16:33:08 +0000278
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000279 # check that enough arguments are passed
280 if not args:
281 usage('at least one filename argument required')
Guido van Rossumd4cc04c1996-06-17 17:49:13 +0000282
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000283 # check that file arguments exist
284 for arg in args:
Guido van Rossum1e074031998-03-05 04:05:38 +0000285 if arg == '-m':
286 break
Guido van Rossum78fc3631998-03-20 17:37:24 +0000287 # if user specified -m on the command line before _any_
288 # file names, then nothing should be checked (as the
289 # very first file should be a module name)
290 if modargs:
291 break
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000292 if not os.path.exists(arg):
293 usage('argument %s not found' % arg)
294 if not os.path.isfile(arg):
295 usage('%s: not a plain file' % arg)
Guido van Rossum00ff4331994-10-03 16:33:08 +0000296
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000297 # process non-option arguments
298 scriptfile = args[0]
299 modules = args[1:]
Guido van Rossum00ff4331994-10-03 16:33:08 +0000300
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000301 # derive target name from script name
302 base = os.path.basename(scriptfile)
303 base, ext = os.path.splitext(base)
304 if base:
305 if base != scriptfile:
306 target = base
307 else:
308 target = base + '.bin'
Guido van Rossum00ff4331994-10-03 16:33:08 +0000309
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000310 # handle -o option
311 base_frozen_c = frozen_c
312 base_config_c = config_c
313 base_target = target
314 if odir and not os.path.isdir(odir):
315 try:
316 os.mkdir(odir)
Guido van Rossum96bf7e82007-02-09 23:27:01 +0000317 print("Created output directory", odir)
Andrew Svetlov8b33dd82012-12-24 19:58:48 +0200318 except OSError as msg:
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000319 usage('%s: mkdir failed (%s)' % (odir, str(msg)))
Guido van Rossumbaf06031998-08-25 14:06:55 +0000320 base = ''
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000321 if odir:
Guido van Rossumbaf06031998-08-25 14:06:55 +0000322 base = os.path.join(odir, '')
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000323 frozen_c = os.path.join(odir, frozen_c)
324 config_c = os.path.join(odir, config_c)
325 target = os.path.join(odir, target)
326 makefile = os.path.join(odir, makefile)
Guido van Rossume35c6011998-05-18 20:25:54 +0000327 if win: extensions_c = os.path.join(odir, extensions_c)
Guido van Rossum00ff4331994-10-03 16:33:08 +0000328
Guido van Rossum78fc3631998-03-20 17:37:24 +0000329 # Handle special entry point requirements
330 # (on Windows, some frozen programs do not use __main__, but
331 # import the module directly. Eg, DLLs, Services, etc
332 custom_entry_point = None # Currently only used on Windows
333 python_entry_is_main = 1 # Is the entry point called __main__?
334 # handle -s option on Windows
335 if win:
336 import winmakemakefile
337 try:
Guido van Rossume35c6011998-05-18 20:25:54 +0000338 custom_entry_point, python_entry_is_main = \
339 winmakemakefile.get_custom_entry_point(subsystem)
Guido van Rossumb940e112007-01-10 16:19:56 +0000340 except ValueError as why:
Guido van Rossum78fc3631998-03-20 17:37:24 +0000341 usage(why)
Tim Peters182b5ac2004-07-18 06:16:08 +0000342
Guido van Rossum78fc3631998-03-20 17:37:24 +0000343
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000344 # Actual work starts here...
Guido van Rossumd8336c21994-10-05 16:13:01 +0000345
Guido van Rossum75dc4961998-03-05 03:42:00 +0000346 # collect all modules of the program
Guido van Rossum1e074031998-03-05 04:05:38 +0000347 dir = os.path.dirname(scriptfile)
348 path[0] = dir
Guido van Rossum6b767ac2001-03-20 20:43:34 +0000349 mf = modulefinder.ModuleFinder(path, debug, exclude, replace_paths)
Tim Peters182b5ac2004-07-18 06:16:08 +0000350
Guido van Rossum78fc3631998-03-20 17:37:24 +0000351 if win and subsystem=='service':
352 # If a Windows service, then add the "built-in" module.
353 mod = mf.add_module("servicemanager")
354 mod.__file__="dummy.pyd" # really built-in to the resulting EXE
355
Guido van Rossum75dc4961998-03-05 03:42:00 +0000356 for mod in implicits:
357 mf.import_hook(mod)
358 for mod in modules:
359 if mod == '-m':
360 modargs = 1
361 continue
362 if modargs:
363 if mod[-2:] == '.*':
364 mf.import_hook(mod[:-2], None, ["*"])
365 else:
366 mf.import_hook(mod)
367 else:
368 mf.load_file(mod)
Guido van Rossum78fc3631998-03-20 17:37:24 +0000369
Martin v. Löwisc00d39e2014-03-30 21:07:25 +0200370 # Alias "importlib._bootstrap" to "_frozen_importlib" so that the
Eric Snow32439d62015-05-02 19:15:18 -0600371 # import machinery can bootstrap. Do the same for
372 # importlib._bootstrap_external.
Martin v. Löwisc00d39e2014-03-30 21:07:25 +0200373 mf.modules["_frozen_importlib"] = mf.modules["importlib._bootstrap"]
Eric Snow32439d62015-05-02 19:15:18 -0600374 mf.modules["_frozen_importlib_external"] = mf.modules["importlib._bootstrap_external"]
Martin v. Löwisc00d39e2014-03-30 21:07:25 +0200375
Guido van Rossum78fc3631998-03-20 17:37:24 +0000376 # Add the main script as either __main__, or the actual module name.
377 if python_entry_is_main:
378 mf.run_script(scriptfile)
379 else:
Guido van Rossum4b1235c2000-05-06 03:18:08 +0000380 mf.load_file(scriptfile)
Guido van Rossum78fc3631998-03-20 17:37:24 +0000381
Guido van Rossum75dc4961998-03-05 03:42:00 +0000382 if debug > 0:
383 mf.report()
Guido van Rossum96bf7e82007-02-09 23:27:01 +0000384 print()
Guido van Rossum75dc4961998-03-05 03:42:00 +0000385 dict = mf.modules
Guido van Rossumdbaf3321994-10-03 10:25:54 +0000386
Guido van Rossum03f7f082001-10-18 19:15:32 +0000387 if error_if_any_missing:
388 missing = mf.any_missing()
389 if missing:
390 sys.exit("There are some missing modules: %r" % missing)
391
Guido van Rossum75dc4961998-03-05 03:42:00 +0000392 # generate output for frozen modules
Guido van Rossum03f7f082001-10-18 19:15:32 +0000393 files = makefreeze.makefreeze(base, dict, debug, custom_entry_point,
394 fail_import)
Guido van Rossumdbaf3321994-10-03 10:25:54 +0000395
Guido van Rossuma0e18351998-03-07 04:51:03 +0000396 # look for unfrozen modules (builtin and of unknown origin)
397 builtins = []
398 unknown = []
Guido van Rossum53970392007-06-12 00:28:30 +0000399 mods = sorted(dict.keys())
Guido van Rossuma0e18351998-03-07 04:51:03 +0000400 for mod in mods:
401 if dict[mod].__code__:
402 continue
403 if not dict[mod].__file__:
404 builtins.append(mod)
405 else:
406 unknown.append(mod)
407
408 # search for unknown modules in extensions directories (not on Windows)
409 addfiles = []
Guido van Rossume35c6011998-05-18 20:25:54 +0000410 frozen_extensions = [] # Windows list of modules.
Guido van Rossuma937afd1998-04-23 14:39:24 +0000411 if unknown or (not win and builtins):
Guido van Rossum78fc3631998-03-20 17:37:24 +0000412 if not win:
413 addfiles, addmods = \
Guido van Rossuma937afd1998-04-23 14:39:24 +0000414 checkextensions.checkextensions(unknown+builtins,
415 extensions)
Guido van Rossum78fc3631998-03-20 17:37:24 +0000416 for mod in addmods:
Guido van Rossuma937afd1998-04-23 14:39:24 +0000417 if mod in unknown:
418 unknown.remove(mod)
419 builtins.append(mod)
Guido van Rossum78fc3631998-03-20 17:37:24 +0000420 else:
421 # Do the windows thang...
422 import checkextensions_win32
Tim Peters182b5ac2004-07-18 06:16:08 +0000423 # Get a list of CExtension instances, each describing a module
Guido van Rossum78fc3631998-03-20 17:37:24 +0000424 # (including its source files)
Guido van Rossume35c6011998-05-18 20:25:54 +0000425 frozen_extensions = checkextensions_win32.checkextensions(
Guido van Rossumf67c2382000-07-13 15:45:17 +0000426 unknown, extensions, prefix)
Guido van Rossume35c6011998-05-18 20:25:54 +0000427 for mod in frozen_extensions:
Guido van Rossum78fc3631998-03-20 17:37:24 +0000428 unknown.remove(mod.name)
Guido van Rossuma0e18351998-03-07 04:51:03 +0000429
430 # report unknown modules
431 if unknown:
432 sys.stderr.write('Warning: unknown modules remain: %s\n' %
Walter Dörwaldaaab30e2002-09-11 20:36:02 +0000433 ' '.join(unknown))
Guido van Rossuma0e18351998-03-07 04:51:03 +0000434
Guido van Rossum75dc4961998-03-05 03:42:00 +0000435 # windows gets different treatment
Guido van Rossum58a59481997-08-14 01:45:33 +0000436 if win:
437 # Taking a shortcut here...
Guido van Rossume35c6011998-05-18 20:25:54 +0000438 import winmakemakefile, checkextensions_win32
439 checkextensions_win32.write_extension_table(extensions_c,
440 frozen_extensions)
441 # Create a module definition for the bootstrap C code.
442 xtras = [frozenmain_c, os.path.basename(frozen_c),
Guido van Rossum7039f501999-03-12 22:07:05 +0000443 frozendllmain_c, os.path.basename(extensions_c)] + files
Guido van Rossume35c6011998-05-18 20:25:54 +0000444 maindefn = checkextensions_win32.CExtension( '__main__', xtras )
445 frozen_extensions.append( maindefn )
Serhiy Storchaka53c3fb12015-03-20 09:21:59 +0200446 with open(makefile, 'w') as outfp:
Guido van Rossum58a59481997-08-14 01:45:33 +0000447 winmakemakefile.makemakefile(outfp,
448 locals(),
Guido van Rossume35c6011998-05-18 20:25:54 +0000449 frozen_extensions,
Guido van Rossum31d53ed1998-03-07 04:08:04 +0000450 os.path.basename(target))
Guido van Rossum58a59481997-08-14 01:45:33 +0000451 return
452
Guido van Rossum75dc4961998-03-05 03:42:00 +0000453 # generate config.c and Makefile
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000454 builtins.sort()
Serhiy Storchaka53c3fb12015-03-20 09:21:59 +0200455 with open(config_c_in) as infp, bkfile.open(config_c, 'w') as outfp:
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000456 makeconfig.makeconfig(infp, outfp, builtins)
Guido van Rossumdbaf3321994-10-03 10:25:54 +0000457
Neil Schemenauer89e90d62001-06-02 06:16:02 +0000458 cflags = ['$(OPT)']
459 cppflags = defines + includes
Victor Stinner1c653f12020-12-16 12:12:36 +0100460 libs = [os.path.join(libdir, '$(LDLIBRARY)')]
Guido van Rossum00ff4331994-10-03 16:33:08 +0000461
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000462 somevars = {}
Guido van Rossum345df171997-11-22 22:10:01 +0000463 if os.path.exists(makefile_in):
464 makevars = parsesetup.getmakevars(makefile_in)
Georg Brandlbf82e372008-05-16 17:02:34 +0000465 for key in makevars:
Gustavo Niemeyerffa5a502004-05-08 17:59:43 +0000466 somevars[key] = makevars[key]
Guido van Rossum00ff4331994-10-03 16:33:08 +0000467
Walter Dörwaldaaab30e2002-09-11 20:36:02 +0000468 somevars['CFLAGS'] = ' '.join(cflags) # override
469 somevars['CPPFLAGS'] = ' '.join(cppflags) # override
Marc-André Lemburg64b4f272002-04-04 16:15:41 +0000470 files = [base_config_c, base_frozen_c] + \
Guido van Rossumbaf06031998-08-25 14:06:55 +0000471 files + supp_sources + addfiles + libs + \
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000472 ['$(MODLIBS)', '$(LIBS)', '$(SYSLIBS)']
Guido van Rossum00ff4331994-10-03 16:33:08 +0000473
Serhiy Storchaka53c3fb12015-03-20 09:21:59 +0200474 with bkfile.open(makefile, 'w') as outfp:
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000475 makemakefile.makemakefile(outfp, somevars, files, base_target)
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000476
477 # Done!
478
479 if odir:
Guido van Rossum96bf7e82007-02-09 23:27:01 +0000480 print('Now run "make" in', odir, end=' ')
481 print('to build the target:', base_target)
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000482 else:
Guido van Rossum96bf7e82007-02-09 23:27:01 +0000483 print('Now run "make" to build the target:', base_target)
Guido van Rossum00ff4331994-10-03 16:33:08 +0000484
Guido van Rossumd8336c21994-10-05 16:13:01 +0000485
486# Print usage message and exit
487
Guido van Rossum9a6e8551997-08-10 16:47:17 +0000488def usage(msg):
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000489 sys.stdout = sys.stderr
Guido van Rossum96bf7e82007-02-09 23:27:01 +0000490 print("Error:", msg)
491 print("Use ``%s -h'' for help" % sys.argv[0])
Guido van Rossum0b4b8a21997-08-10 16:56:48 +0000492 sys.exit(2)
Guido van Rossumd8336c21994-10-05 16:13:01 +0000493
494
Guido van Rossumdbaf3321994-10-03 10:25:54 +0000495main()