17db96d56Sopenharmony_ci#! /usr/bin/env python3 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ci"""Freeze a Python script into a binary. 47db96d56Sopenharmony_ci 57db96d56Sopenharmony_ciusage: freeze [options...] script [module]... 67db96d56Sopenharmony_ci 77db96d56Sopenharmony_ciOptions: 87db96d56Sopenharmony_ci-p prefix: This is the prefix used when you ran ``make install'' 97db96d56Sopenharmony_ci in the Python build directory. 107db96d56Sopenharmony_ci (If you never ran this, freeze won't work.) 117db96d56Sopenharmony_ci The default is whatever sys.prefix evaluates to. 127db96d56Sopenharmony_ci It can also be the top directory of the Python source 137db96d56Sopenharmony_ci tree; then -P must point to the build tree. 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ci-P exec_prefix: Like -p but this is the 'exec_prefix', used to 167db96d56Sopenharmony_ci install objects etc. The default is whatever sys.exec_prefix 177db96d56Sopenharmony_ci evaluates to, or the -p argument if given. 187db96d56Sopenharmony_ci If -p points to the Python source tree, -P must point 197db96d56Sopenharmony_ci to the build tree, if different. 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ci-e extension: A directory containing additional .o files that 227db96d56Sopenharmony_ci may be used to resolve modules. This directory 237db96d56Sopenharmony_ci should also have a Setup file describing the .o files. 247db96d56Sopenharmony_ci On Windows, the name of a .INI file describing one 257db96d56Sopenharmony_ci or more extensions is passed. 267db96d56Sopenharmony_ci More than one -e option may be given. 277db96d56Sopenharmony_ci 287db96d56Sopenharmony_ci-o dir: Directory where the output files are created; default '.'. 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ci-m: Additional arguments are module names instead of filenames. 317db96d56Sopenharmony_ci 327db96d56Sopenharmony_ci-a package=dir: Additional directories to be added to the package's 337db96d56Sopenharmony_ci __path__. Used to simulate directories added by the 347db96d56Sopenharmony_ci package at runtime (eg, by OpenGL and win32com). 357db96d56Sopenharmony_ci More than one -a option may be given for each package. 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_ci-l file: Pass the file to the linker (windows only) 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_ci-d: Debugging mode for the module finder. 407db96d56Sopenharmony_ci 417db96d56Sopenharmony_ci-q: Make the module finder totally quiet. 427db96d56Sopenharmony_ci 437db96d56Sopenharmony_ci-h: Print this help message. 447db96d56Sopenharmony_ci 457db96d56Sopenharmony_ci-x module Exclude the specified module. It will still be imported 467db96d56Sopenharmony_ci by the frozen binary if it exists on the host system. 477db96d56Sopenharmony_ci 487db96d56Sopenharmony_ci-X module Like -x, except the module can never be imported by 497db96d56Sopenharmony_ci the frozen binary. 507db96d56Sopenharmony_ci 517db96d56Sopenharmony_ci-E: Freeze will fail if any modules can't be found (that 527db96d56Sopenharmony_ci were not excluded using -x or -X). 537db96d56Sopenharmony_ci 547db96d56Sopenharmony_ci-i filename: Include a file with additional command line options. Used 557db96d56Sopenharmony_ci to prevent command lines growing beyond the capabilities of 567db96d56Sopenharmony_ci the shell/OS. All arguments specified in filename 577db96d56Sopenharmony_ci are read and the -i option replaced with the parsed 587db96d56Sopenharmony_ci params (note - quoting args in this file is NOT supported) 597db96d56Sopenharmony_ci 607db96d56Sopenharmony_ci-s subsystem: Specify the subsystem (For Windows only.); 617db96d56Sopenharmony_ci 'console' (default), 'windows', 'service' or 'com_dll' 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_ci-w: Toggle Windows (NT or 95) behavior. 647db96d56Sopenharmony_ci (For debugging only -- on a win32 platform, win32 behavior 657db96d56Sopenharmony_ci is automatic.) 667db96d56Sopenharmony_ci 677db96d56Sopenharmony_ci-r prefix=f: Replace path prefix. 687db96d56Sopenharmony_ci Replace prefix with f in the source path references 697db96d56Sopenharmony_ci contained in the resulting binary. 707db96d56Sopenharmony_ci 717db96d56Sopenharmony_ciArguments: 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ciscript: The Python script to be executed by the resulting binary. 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_cimodule ...: Additional Python modules (referenced by pathname) 767db96d56Sopenharmony_ci that will be included in the resulting binary. These 777db96d56Sopenharmony_ci may be .py or .pyc files. If -m is specified, these are 787db96d56Sopenharmony_ci module names that are search in the path instead. 797db96d56Sopenharmony_ci 807db96d56Sopenharmony_ciNOTES: 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ciIn order to use freeze successfully, you must have built Python and 837db96d56Sopenharmony_ciinstalled it ("make install"). 847db96d56Sopenharmony_ci 857db96d56Sopenharmony_ciThe script should not use modules provided only as shared libraries; 867db96d56Sopenharmony_ciif it does, the resulting binary is not self-contained. 877db96d56Sopenharmony_ci""" 887db96d56Sopenharmony_ci 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_ci# Import standard modules 917db96d56Sopenharmony_ci 927db96d56Sopenharmony_ciimport modulefinder 937db96d56Sopenharmony_ciimport getopt 947db96d56Sopenharmony_ciimport os 957db96d56Sopenharmony_ciimport sys 967db96d56Sopenharmony_ciimport sysconfig 977db96d56Sopenharmony_ci 987db96d56Sopenharmony_ci 997db96d56Sopenharmony_ci# Import the freeze-private modules 1007db96d56Sopenharmony_ci 1017db96d56Sopenharmony_ciimport checkextensions 1027db96d56Sopenharmony_ciimport makeconfig 1037db96d56Sopenharmony_ciimport makefreeze 1047db96d56Sopenharmony_ciimport makemakefile 1057db96d56Sopenharmony_ciimport parsesetup 1067db96d56Sopenharmony_ciimport bkfile 1077db96d56Sopenharmony_ci 1087db96d56Sopenharmony_ci 1097db96d56Sopenharmony_ci# Main program 1107db96d56Sopenharmony_ci 1117db96d56Sopenharmony_cidef main(): 1127db96d56Sopenharmony_ci # overridable context 1137db96d56Sopenharmony_ci prefix = None # settable with -p option 1147db96d56Sopenharmony_ci exec_prefix = None # settable with -P option 1157db96d56Sopenharmony_ci extensions = [] 1167db96d56Sopenharmony_ci exclude = [] # settable with -x option 1177db96d56Sopenharmony_ci addn_link = [] # settable with -l, but only honored under Windows. 1187db96d56Sopenharmony_ci path = sys.path[:] 1197db96d56Sopenharmony_ci modargs = 0 1207db96d56Sopenharmony_ci debug = 1 1217db96d56Sopenharmony_ci odir = '' 1227db96d56Sopenharmony_ci win = sys.platform[:3] == 'win' 1237db96d56Sopenharmony_ci replace_paths = [] # settable with -r option 1247db96d56Sopenharmony_ci error_if_any_missing = 0 1257db96d56Sopenharmony_ci 1267db96d56Sopenharmony_ci # default the exclude list for each platform 1277db96d56Sopenharmony_ci if win: exclude = exclude + [ 1287db96d56Sopenharmony_ci 'dos', 'dospath', 'mac', 'macfs', 'MACFS', 'posix', ] 1297db96d56Sopenharmony_ci 1307db96d56Sopenharmony_ci fail_import = exclude[:] 1317db96d56Sopenharmony_ci 1327db96d56Sopenharmony_ci # output files 1337db96d56Sopenharmony_ci frozen_c = 'frozen.c' 1347db96d56Sopenharmony_ci config_c = 'config.c' 1357db96d56Sopenharmony_ci target = 'a.out' # normally derived from script name 1367db96d56Sopenharmony_ci makefile = 'Makefile' 1377db96d56Sopenharmony_ci subsystem = 'console' 1387db96d56Sopenharmony_ci 1397db96d56Sopenharmony_ci # parse command line by first replacing any "-i" options with the 1407db96d56Sopenharmony_ci # file contents. 1417db96d56Sopenharmony_ci pos = 1 1427db96d56Sopenharmony_ci while pos < len(sys.argv)-1: 1437db96d56Sopenharmony_ci # last option can not be "-i", so this ensures "pos+1" is in range! 1447db96d56Sopenharmony_ci if sys.argv[pos] == '-i': 1457db96d56Sopenharmony_ci try: 1467db96d56Sopenharmony_ci with open(sys.argv[pos+1]) as infp: 1477db96d56Sopenharmony_ci options = infp.read().split() 1487db96d56Sopenharmony_ci except IOError as why: 1497db96d56Sopenharmony_ci usage("File name '%s' specified with the -i option " 1507db96d56Sopenharmony_ci "can not be read - %s" % (sys.argv[pos+1], why) ) 1517db96d56Sopenharmony_ci # Replace the '-i' and the filename with the read params. 1527db96d56Sopenharmony_ci sys.argv[pos:pos+2] = options 1537db96d56Sopenharmony_ci pos = pos + len(options) - 1 # Skip the name and the included args. 1547db96d56Sopenharmony_ci pos = pos + 1 1557db96d56Sopenharmony_ci 1567db96d56Sopenharmony_ci # Now parse the command line with the extras inserted. 1577db96d56Sopenharmony_ci try: 1587db96d56Sopenharmony_ci opts, args = getopt.getopt(sys.argv[1:], 'r:a:dEe:hmo:p:P:qs:wX:x:l:') 1597db96d56Sopenharmony_ci except getopt.error as msg: 1607db96d56Sopenharmony_ci usage('getopt error: ' + str(msg)) 1617db96d56Sopenharmony_ci 1627db96d56Sopenharmony_ci # process option arguments 1637db96d56Sopenharmony_ci for o, a in opts: 1647db96d56Sopenharmony_ci if o == '-h': 1657db96d56Sopenharmony_ci print(__doc__) 1667db96d56Sopenharmony_ci return 1677db96d56Sopenharmony_ci if o == '-d': 1687db96d56Sopenharmony_ci debug = debug + 1 1697db96d56Sopenharmony_ci if o == '-e': 1707db96d56Sopenharmony_ci extensions.append(a) 1717db96d56Sopenharmony_ci if o == '-m': 1727db96d56Sopenharmony_ci modargs = 1 1737db96d56Sopenharmony_ci if o == '-o': 1747db96d56Sopenharmony_ci odir = a 1757db96d56Sopenharmony_ci if o == '-p': 1767db96d56Sopenharmony_ci prefix = a 1777db96d56Sopenharmony_ci if o == '-P': 1787db96d56Sopenharmony_ci exec_prefix = a 1797db96d56Sopenharmony_ci if o == '-q': 1807db96d56Sopenharmony_ci debug = 0 1817db96d56Sopenharmony_ci if o == '-w': 1827db96d56Sopenharmony_ci win = not win 1837db96d56Sopenharmony_ci if o == '-s': 1847db96d56Sopenharmony_ci if not win: 1857db96d56Sopenharmony_ci usage("-s subsystem option only on Windows") 1867db96d56Sopenharmony_ci subsystem = a 1877db96d56Sopenharmony_ci if o == '-x': 1887db96d56Sopenharmony_ci exclude.append(a) 1897db96d56Sopenharmony_ci if o == '-X': 1907db96d56Sopenharmony_ci exclude.append(a) 1917db96d56Sopenharmony_ci fail_import.append(a) 1927db96d56Sopenharmony_ci if o == '-E': 1937db96d56Sopenharmony_ci error_if_any_missing = 1 1947db96d56Sopenharmony_ci if o == '-l': 1957db96d56Sopenharmony_ci addn_link.append(a) 1967db96d56Sopenharmony_ci if o == '-a': 1977db96d56Sopenharmony_ci modulefinder.AddPackagePath(*a.split("=", 2)) 1987db96d56Sopenharmony_ci if o == '-r': 1997db96d56Sopenharmony_ci f,r = a.split("=", 2) 2007db96d56Sopenharmony_ci replace_paths.append( (f,r) ) 2017db96d56Sopenharmony_ci 2027db96d56Sopenharmony_ci # modules that are imported by the Python runtime 2037db96d56Sopenharmony_ci implicits = [] 2047db96d56Sopenharmony_ci for module in ('site', 'warnings', 'encodings.utf_8', 'encodings.latin_1'): 2057db96d56Sopenharmony_ci if module not in exclude: 2067db96d56Sopenharmony_ci implicits.append(module) 2077db96d56Sopenharmony_ci 2087db96d56Sopenharmony_ci # default prefix and exec_prefix 2097db96d56Sopenharmony_ci if not exec_prefix: 2107db96d56Sopenharmony_ci if prefix: 2117db96d56Sopenharmony_ci exec_prefix = prefix 2127db96d56Sopenharmony_ci else: 2137db96d56Sopenharmony_ci exec_prefix = sys.exec_prefix 2147db96d56Sopenharmony_ci if not prefix: 2157db96d56Sopenharmony_ci prefix = sys.prefix 2167db96d56Sopenharmony_ci 2177db96d56Sopenharmony_ci # determine whether -p points to the Python source tree 2187db96d56Sopenharmony_ci ishome = os.path.exists(os.path.join(prefix, 'Python', 'ceval.c')) 2197db96d56Sopenharmony_ci 2207db96d56Sopenharmony_ci # locations derived from options 2217db96d56Sopenharmony_ci version = '%d.%d' % sys.version_info[:2] 2227db96d56Sopenharmony_ci if hasattr(sys, 'abiflags'): 2237db96d56Sopenharmony_ci flagged_version = version + sys.abiflags 2247db96d56Sopenharmony_ci else: 2257db96d56Sopenharmony_ci flagged_version = version 2267db96d56Sopenharmony_ci if win: 2277db96d56Sopenharmony_ci extensions_c = 'frozen_extensions.c' 2287db96d56Sopenharmony_ci if ishome: 2297db96d56Sopenharmony_ci print("(Using Python source directory)") 2307db96d56Sopenharmony_ci configdir = exec_prefix 2317db96d56Sopenharmony_ci incldir = os.path.join(prefix, 'Include') 2327db96d56Sopenharmony_ci config_h_dir = exec_prefix 2337db96d56Sopenharmony_ci config_c_in = os.path.join(prefix, 'Modules', 'config.c.in') 2347db96d56Sopenharmony_ci frozenmain_c = os.path.join(prefix, 'Python', 'frozenmain.c') 2357db96d56Sopenharmony_ci makefile_in = os.path.join(exec_prefix, 'Makefile') 2367db96d56Sopenharmony_ci if win: 2377db96d56Sopenharmony_ci frozendllmain_c = os.path.join(exec_prefix, 'Pc\\frozen_dllmain.c') 2387db96d56Sopenharmony_ci else: 2397db96d56Sopenharmony_ci configdir = sysconfig.get_config_var('LIBPL') 2407db96d56Sopenharmony_ci incldir = os.path.join(prefix, 'include', 'python%s' % flagged_version) 2417db96d56Sopenharmony_ci config_h_dir = os.path.join(exec_prefix, 'include', 2427db96d56Sopenharmony_ci 'python%s' % flagged_version) 2437db96d56Sopenharmony_ci config_c_in = os.path.join(configdir, 'config.c.in') 2447db96d56Sopenharmony_ci frozenmain_c = os.path.join(configdir, 'frozenmain.c') 2457db96d56Sopenharmony_ci makefile_in = os.path.join(configdir, 'Makefile') 2467db96d56Sopenharmony_ci frozendllmain_c = os.path.join(configdir, 'frozen_dllmain.c') 2477db96d56Sopenharmony_ci libdir = sysconfig.get_config_var('LIBDIR') 2487db96d56Sopenharmony_ci supp_sources = [] 2497db96d56Sopenharmony_ci defines = [] 2507db96d56Sopenharmony_ci includes = ['-I' + incldir, '-I' + config_h_dir] 2517db96d56Sopenharmony_ci 2527db96d56Sopenharmony_ci # sanity check of directories and files 2537db96d56Sopenharmony_ci check_dirs = [prefix, exec_prefix, configdir, incldir] 2547db96d56Sopenharmony_ci if not win: 2557db96d56Sopenharmony_ci # These are not directories on Windows. 2567db96d56Sopenharmony_ci check_dirs = check_dirs + extensions 2577db96d56Sopenharmony_ci for dir in check_dirs: 2587db96d56Sopenharmony_ci if not os.path.exists(dir): 2597db96d56Sopenharmony_ci usage('needed directory %s not found' % dir) 2607db96d56Sopenharmony_ci if not os.path.isdir(dir): 2617db96d56Sopenharmony_ci usage('%s: not a directory' % dir) 2627db96d56Sopenharmony_ci if win: 2637db96d56Sopenharmony_ci files = supp_sources + extensions # extensions are files on Windows. 2647db96d56Sopenharmony_ci else: 2657db96d56Sopenharmony_ci files = [config_c_in, makefile_in] + supp_sources 2667db96d56Sopenharmony_ci for file in supp_sources: 2677db96d56Sopenharmony_ci if not os.path.exists(file): 2687db96d56Sopenharmony_ci usage('needed file %s not found' % file) 2697db96d56Sopenharmony_ci if not os.path.isfile(file): 2707db96d56Sopenharmony_ci usage('%s: not a plain file' % file) 2717db96d56Sopenharmony_ci if not win: 2727db96d56Sopenharmony_ci for dir in extensions: 2737db96d56Sopenharmony_ci setup = os.path.join(dir, 'Setup') 2747db96d56Sopenharmony_ci if not os.path.exists(setup): 2757db96d56Sopenharmony_ci usage('needed file %s not found' % setup) 2767db96d56Sopenharmony_ci if not os.path.isfile(setup): 2777db96d56Sopenharmony_ci usage('%s: not a plain file' % setup) 2787db96d56Sopenharmony_ci 2797db96d56Sopenharmony_ci # check that enough arguments are passed 2807db96d56Sopenharmony_ci if not args: 2817db96d56Sopenharmony_ci usage('at least one filename argument required') 2827db96d56Sopenharmony_ci 2837db96d56Sopenharmony_ci # check that file arguments exist 2847db96d56Sopenharmony_ci for arg in args: 2857db96d56Sopenharmony_ci if arg == '-m': 2867db96d56Sopenharmony_ci break 2877db96d56Sopenharmony_ci # if user specified -m on the command line before _any_ 2887db96d56Sopenharmony_ci # file names, then nothing should be checked (as the 2897db96d56Sopenharmony_ci # very first file should be a module name) 2907db96d56Sopenharmony_ci if modargs: 2917db96d56Sopenharmony_ci break 2927db96d56Sopenharmony_ci if not os.path.exists(arg): 2937db96d56Sopenharmony_ci usage('argument %s not found' % arg) 2947db96d56Sopenharmony_ci if not os.path.isfile(arg): 2957db96d56Sopenharmony_ci usage('%s: not a plain file' % arg) 2967db96d56Sopenharmony_ci 2977db96d56Sopenharmony_ci # process non-option arguments 2987db96d56Sopenharmony_ci scriptfile = args[0] 2997db96d56Sopenharmony_ci modules = args[1:] 3007db96d56Sopenharmony_ci 3017db96d56Sopenharmony_ci # derive target name from script name 3027db96d56Sopenharmony_ci base = os.path.basename(scriptfile) 3037db96d56Sopenharmony_ci base, ext = os.path.splitext(base) 3047db96d56Sopenharmony_ci if base: 3057db96d56Sopenharmony_ci if base != scriptfile: 3067db96d56Sopenharmony_ci target = base 3077db96d56Sopenharmony_ci else: 3087db96d56Sopenharmony_ci target = base + '.bin' 3097db96d56Sopenharmony_ci 3107db96d56Sopenharmony_ci # handle -o option 3117db96d56Sopenharmony_ci base_frozen_c = frozen_c 3127db96d56Sopenharmony_ci base_config_c = config_c 3137db96d56Sopenharmony_ci base_target = target 3147db96d56Sopenharmony_ci if odir and not os.path.isdir(odir): 3157db96d56Sopenharmony_ci try: 3167db96d56Sopenharmony_ci os.mkdir(odir) 3177db96d56Sopenharmony_ci print("Created output directory", odir) 3187db96d56Sopenharmony_ci except OSError as msg: 3197db96d56Sopenharmony_ci usage('%s: mkdir failed (%s)' % (odir, str(msg))) 3207db96d56Sopenharmony_ci base = '' 3217db96d56Sopenharmony_ci if odir: 3227db96d56Sopenharmony_ci base = os.path.join(odir, '') 3237db96d56Sopenharmony_ci frozen_c = os.path.join(odir, frozen_c) 3247db96d56Sopenharmony_ci config_c = os.path.join(odir, config_c) 3257db96d56Sopenharmony_ci target = os.path.join(odir, target) 3267db96d56Sopenharmony_ci makefile = os.path.join(odir, makefile) 3277db96d56Sopenharmony_ci if win: extensions_c = os.path.join(odir, extensions_c) 3287db96d56Sopenharmony_ci 3297db96d56Sopenharmony_ci # Handle special entry point requirements 3307db96d56Sopenharmony_ci # (on Windows, some frozen programs do not use __main__, but 3317db96d56Sopenharmony_ci # import the module directly. Eg, DLLs, Services, etc 3327db96d56Sopenharmony_ci custom_entry_point = None # Currently only used on Windows 3337db96d56Sopenharmony_ci python_entry_is_main = 1 # Is the entry point called __main__? 3347db96d56Sopenharmony_ci # handle -s option on Windows 3357db96d56Sopenharmony_ci if win: 3367db96d56Sopenharmony_ci import winmakemakefile 3377db96d56Sopenharmony_ci try: 3387db96d56Sopenharmony_ci custom_entry_point, python_entry_is_main = \ 3397db96d56Sopenharmony_ci winmakemakefile.get_custom_entry_point(subsystem) 3407db96d56Sopenharmony_ci except ValueError as why: 3417db96d56Sopenharmony_ci usage(why) 3427db96d56Sopenharmony_ci 3437db96d56Sopenharmony_ci 3447db96d56Sopenharmony_ci # Actual work starts here... 3457db96d56Sopenharmony_ci 3467db96d56Sopenharmony_ci # collect all modules of the program 3477db96d56Sopenharmony_ci dir = os.path.dirname(scriptfile) 3487db96d56Sopenharmony_ci path[0] = dir 3497db96d56Sopenharmony_ci mf = modulefinder.ModuleFinder(path, debug, exclude, replace_paths) 3507db96d56Sopenharmony_ci 3517db96d56Sopenharmony_ci if win and subsystem=='service': 3527db96d56Sopenharmony_ci # If a Windows service, then add the "built-in" module. 3537db96d56Sopenharmony_ci mod = mf.add_module("servicemanager") 3547db96d56Sopenharmony_ci mod.__file__="dummy.pyd" # really built-in to the resulting EXE 3557db96d56Sopenharmony_ci 3567db96d56Sopenharmony_ci for mod in implicits: 3577db96d56Sopenharmony_ci mf.import_hook(mod) 3587db96d56Sopenharmony_ci for mod in modules: 3597db96d56Sopenharmony_ci if mod == '-m': 3607db96d56Sopenharmony_ci modargs = 1 3617db96d56Sopenharmony_ci continue 3627db96d56Sopenharmony_ci if modargs: 3637db96d56Sopenharmony_ci if mod[-2:] == '.*': 3647db96d56Sopenharmony_ci mf.import_hook(mod[:-2], None, ["*"]) 3657db96d56Sopenharmony_ci else: 3667db96d56Sopenharmony_ci mf.import_hook(mod) 3677db96d56Sopenharmony_ci else: 3687db96d56Sopenharmony_ci mf.load_file(mod) 3697db96d56Sopenharmony_ci 3707db96d56Sopenharmony_ci # Add the main script as either __main__, or the actual module name. 3717db96d56Sopenharmony_ci if python_entry_is_main: 3727db96d56Sopenharmony_ci mf.run_script(scriptfile) 3737db96d56Sopenharmony_ci else: 3747db96d56Sopenharmony_ci mf.load_file(scriptfile) 3757db96d56Sopenharmony_ci 3767db96d56Sopenharmony_ci if debug > 0: 3777db96d56Sopenharmony_ci mf.report() 3787db96d56Sopenharmony_ci print() 3797db96d56Sopenharmony_ci dict = mf.modules 3807db96d56Sopenharmony_ci 3817db96d56Sopenharmony_ci if error_if_any_missing: 3827db96d56Sopenharmony_ci missing = mf.any_missing() 3837db96d56Sopenharmony_ci if missing: 3847db96d56Sopenharmony_ci sys.exit("There are some missing modules: %r" % missing) 3857db96d56Sopenharmony_ci 3867db96d56Sopenharmony_ci # generate output for frozen modules 3877db96d56Sopenharmony_ci files = makefreeze.makefreeze(base, dict, debug, custom_entry_point, 3887db96d56Sopenharmony_ci fail_import) 3897db96d56Sopenharmony_ci 3907db96d56Sopenharmony_ci # look for unfrozen modules (builtin and of unknown origin) 3917db96d56Sopenharmony_ci builtins = [] 3927db96d56Sopenharmony_ci unknown = [] 3937db96d56Sopenharmony_ci mods = sorted(dict.keys()) 3947db96d56Sopenharmony_ci for mod in mods: 3957db96d56Sopenharmony_ci if dict[mod].__code__: 3967db96d56Sopenharmony_ci continue 3977db96d56Sopenharmony_ci if not dict[mod].__file__: 3987db96d56Sopenharmony_ci builtins.append(mod) 3997db96d56Sopenharmony_ci else: 4007db96d56Sopenharmony_ci unknown.append(mod) 4017db96d56Sopenharmony_ci 4027db96d56Sopenharmony_ci # search for unknown modules in extensions directories (not on Windows) 4037db96d56Sopenharmony_ci addfiles = [] 4047db96d56Sopenharmony_ci frozen_extensions = [] # Windows list of modules. 4057db96d56Sopenharmony_ci if unknown or (not win and builtins): 4067db96d56Sopenharmony_ci if not win: 4077db96d56Sopenharmony_ci addfiles, addmods = \ 4087db96d56Sopenharmony_ci checkextensions.checkextensions(unknown+builtins, 4097db96d56Sopenharmony_ci extensions) 4107db96d56Sopenharmony_ci for mod in addmods: 4117db96d56Sopenharmony_ci if mod in unknown: 4127db96d56Sopenharmony_ci unknown.remove(mod) 4137db96d56Sopenharmony_ci builtins.append(mod) 4147db96d56Sopenharmony_ci else: 4157db96d56Sopenharmony_ci # Do the windows thang... 4167db96d56Sopenharmony_ci import checkextensions_win32 4177db96d56Sopenharmony_ci # Get a list of CExtension instances, each describing a module 4187db96d56Sopenharmony_ci # (including its source files) 4197db96d56Sopenharmony_ci frozen_extensions = checkextensions_win32.checkextensions( 4207db96d56Sopenharmony_ci unknown, extensions, prefix) 4217db96d56Sopenharmony_ci for mod in frozen_extensions: 4227db96d56Sopenharmony_ci unknown.remove(mod.name) 4237db96d56Sopenharmony_ci 4247db96d56Sopenharmony_ci # report unknown modules 4257db96d56Sopenharmony_ci if unknown: 4267db96d56Sopenharmony_ci sys.stderr.write('Warning: unknown modules remain: %s\n' % 4277db96d56Sopenharmony_ci ' '.join(unknown)) 4287db96d56Sopenharmony_ci 4297db96d56Sopenharmony_ci # windows gets different treatment 4307db96d56Sopenharmony_ci if win: 4317db96d56Sopenharmony_ci # Taking a shortcut here... 4327db96d56Sopenharmony_ci import winmakemakefile, checkextensions_win32 4337db96d56Sopenharmony_ci checkextensions_win32.write_extension_table(extensions_c, 4347db96d56Sopenharmony_ci frozen_extensions) 4357db96d56Sopenharmony_ci # Create a module definition for the bootstrap C code. 4367db96d56Sopenharmony_ci xtras = [frozenmain_c, os.path.basename(frozen_c), 4377db96d56Sopenharmony_ci frozendllmain_c, os.path.basename(extensions_c)] + files 4387db96d56Sopenharmony_ci maindefn = checkextensions_win32.CExtension( '__main__', xtras ) 4397db96d56Sopenharmony_ci frozen_extensions.append( maindefn ) 4407db96d56Sopenharmony_ci with open(makefile, 'w') as outfp: 4417db96d56Sopenharmony_ci winmakemakefile.makemakefile(outfp, 4427db96d56Sopenharmony_ci locals(), 4437db96d56Sopenharmony_ci frozen_extensions, 4447db96d56Sopenharmony_ci os.path.basename(target)) 4457db96d56Sopenharmony_ci return 4467db96d56Sopenharmony_ci 4477db96d56Sopenharmony_ci # generate config.c and Makefile 4487db96d56Sopenharmony_ci builtins.sort() 4497db96d56Sopenharmony_ci with open(config_c_in) as infp, bkfile.open(config_c, 'w') as outfp: 4507db96d56Sopenharmony_ci makeconfig.makeconfig(infp, outfp, builtins) 4517db96d56Sopenharmony_ci 4527db96d56Sopenharmony_ci cflags = ['$(OPT)'] 4537db96d56Sopenharmony_ci cppflags = defines + includes 4547db96d56Sopenharmony_ci libs = [os.path.join(libdir, '$(LDLIBRARY)')] 4557db96d56Sopenharmony_ci 4567db96d56Sopenharmony_ci somevars = {} 4577db96d56Sopenharmony_ci if os.path.exists(makefile_in): 4587db96d56Sopenharmony_ci makevars = parsesetup.getmakevars(makefile_in) 4597db96d56Sopenharmony_ci for key in makevars: 4607db96d56Sopenharmony_ci somevars[key] = makevars[key] 4617db96d56Sopenharmony_ci 4627db96d56Sopenharmony_ci somevars['CFLAGS'] = ' '.join(cflags) # override 4637db96d56Sopenharmony_ci somevars['CPPFLAGS'] = ' '.join(cppflags) # override 4647db96d56Sopenharmony_ci files = [base_config_c, base_frozen_c] + \ 4657db96d56Sopenharmony_ci files + supp_sources + addfiles + libs + \ 4667db96d56Sopenharmony_ci ['$(MODLIBS)', '$(LIBS)', '$(SYSLIBS)'] 4677db96d56Sopenharmony_ci 4687db96d56Sopenharmony_ci with bkfile.open(makefile, 'w') as outfp: 4697db96d56Sopenharmony_ci makemakefile.makemakefile(outfp, somevars, files, base_target) 4707db96d56Sopenharmony_ci 4717db96d56Sopenharmony_ci # Done! 4727db96d56Sopenharmony_ci 4737db96d56Sopenharmony_ci if odir: 4747db96d56Sopenharmony_ci print('Now run "make" in', odir, end=' ') 4757db96d56Sopenharmony_ci print('to build the target:', base_target) 4767db96d56Sopenharmony_ci else: 4777db96d56Sopenharmony_ci print('Now run "make" to build the target:', base_target) 4787db96d56Sopenharmony_ci 4797db96d56Sopenharmony_ci 4807db96d56Sopenharmony_ci# Print usage message and exit 4817db96d56Sopenharmony_ci 4827db96d56Sopenharmony_cidef usage(msg): 4837db96d56Sopenharmony_ci sys.stdout = sys.stderr 4847db96d56Sopenharmony_ci print("Error:", msg) 4857db96d56Sopenharmony_ci print("Use ``%s -h'' for help" % sys.argv[0]) 4867db96d56Sopenharmony_ci sys.exit(2) 4877db96d56Sopenharmony_ci 4887db96d56Sopenharmony_ci 4897db96d56Sopenharmony_cimain() 490