def dumpActiveTraces(self): Tracing.printSeparator() Tracing.printLine("Active are:") for variable, _version in sorted(self.variable_actives.iteritems()): self.getVariableCurrentTrace(variable).dump() Tracing.printSeparator()
def createModuleTree(module, source_ref, source_code, is_main): if Options.isShowProgress(): memory_watch = Utils.MemoryWatch() try: module_body = buildParseTree( provider=module, source_code=source_code, source_ref=source_ref, is_module=True, is_main=is_main ) except RuntimeError as e: if "maximum recursion depth" in e.args[0]: raise CodeTooComplexCode(module.getFullName(), module.getCompileTimeFilename()) raise if module_body.isStatementsFrame(): module_body = makeStatementsSequenceFromStatement(statement=module_body) module.setBody(module_body) completeVariableClosures(module) if Options.isShowProgress(): memory_watch.finish() Tracing.printLine("Memory usage changed loading module '%s': %s" % (module.getFullName(), memory_watch.asStr()))
def dump(xml): value = toString(xml).rstrip() if Utils.python_version >= 300: value = value.decode("utf-8") Tracing.printLine(value)
def runScons(options, quiet): with _setupSconsEnvironment(): if Options.shallCompileWithoutBuildDirectory(): # Make sure we become non-local, by changing all paths to be # absolute, but ones that can be resolved by any program # externally, as the Python of Scons may not be good at unicode. options = copy.deepcopy(options) source_dir = options["source_dir"] options["source_dir"] = "." options["result_name"] = getExternalUsePath( options["result_name"], only_dirname=True ) options["nuitka_src"] = getExternalUsePath(options["nuitka_src"]) if "result_exe" in options: options["result_exe"] = getExternalUsePath( options["result_exe"], only_dirname=True ) if "icon_path" in options: options["icon_path"] = getExternalUsePath( options["icon_path"], only_dirname=True ) else: source_dir = None scons_command = _buildSconsCommand(quiet, options) if Options.isShowScons(): Tracing.printLine("Scons command:", " ".join(scons_command)) Tracing.flushStdout() return subprocess.call(scons_command, shell=False, cwd=source_dir) == 0
def createModuleTree(module, source_ref, source_code, is_main): if Options.isShowProgress(): memory_watch = Utils.MemoryWatch() module_body = buildParseTree( provider = module, source_code = source_code, source_ref = source_ref, is_module = True, is_main = is_main ) if module_body.isStatementsFrame(): module_body = makeStatementsSequenceFromStatement( statement = module_body, ) module.setBody(module_body) completeVariableClosures(module) if Options.isShowProgress(): memory_watch.finish() Tracing.printLine( "Memory usage changed loading module '%s': %s" % ( module.getFullName(), memory_watch.asStr() ) )
def createModuleTree(module, source_ref, source_filename, is_main): if Options.isShowProgress(): memory_watch = Utils.MemoryWatch() source_code = readSourceCodeFromFilename( source_filename ) module_body = buildParseTree( provider = module, source_code = source_code, source_ref = source_ref, is_module = True, is_main = is_main ) module.setBody( module_body ) completeVariableClosures( module ) if Options.isShowProgress(): memory_watch.finish() Tracing.printLine( "Memory usage changed loading module '%s': %s" % ( module.getFullName(), memory_watch.asStr() ) )
def createModuleTree(module, source_ref, source_filename, is_main): if Options.isShowProgress(): memory_watch = Utils.MemoryWatch() source_code = readSourceCodeFromFilename(source_filename) module_body = buildParseTree( provider = module, source_code = source_code, source_ref = source_ref, is_module = True, is_main = is_main ) module.setBody( module_body ) completeVariableClosures(module) if Options.isShowProgress(): memory_watch.finish() Tracing.printLine( "Memory usage changed loading module '%s': %s" % ( module.getFullName(), memory_watch.asStr() ) )
def runScons( options, quiet ): # For the scons file to find the static C++ files and include path. The scons file is # unable to use __file__ for the task. os.environ[ "NUITKA_SCONS" ] = getSconsDataPath() if os.name == "nt": # On Windows this Scons variable must be set by us. os.environ[ "SCONS_LIB_DIR" ] = Utils.joinpath( getSconsInlinePath(), "lib", "scons-2.0.1" ) # Also, for MinGW we can avoid the user having to add the path if he used the # default path or installed it on the same drive by appending to the PATH variable # before executing scons. os.environ[ "PATH" ] += r";\MinGW\bin;C:\MinGW\bin" scons_command = """%(python)s %(binary)s %(quiet)s -f %(scons_file)s --jobs %(job_limit)d %(options)s""" % { "python" : sys.executable if Utils.python_version < 300 else "python", "binary" : getSconsBinaryPath(), "quiet" : "--quiet" if quiet else "", "scons_file" : Utils.joinpath( getSconsDataPath(), "SingleExe.scons" ), "job_limit" : Options.getJobLimit(), "options" : " ".join( "%s=%s" % ( key, value ) for key, value in options.items() ) } if Options.isShowScons(): Tracing.printLine( "Scons command:", scons_command ) return 0 == os.system( scons_command )
def createModuleTree(module, source_ref, source_code, is_main): if Options.isShowProgress(): memory_watch = Utils.MemoryWatch() try: module_body = buildParseTree(provider=module, source_code=source_code, source_ref=source_ref, is_module=True, is_main=is_main) except RuntimeError as e: if "maximum recursion depth" in e.args[0]: raise CodeTooComplexCode(module.getFullName(), module.getCompileTimeFilename()) raise if module_body.isStatementsFrame(): module_body = makeStatementsSequenceFromStatement( statement=module_body, ) module.setBody(module_body) completeVariableClosures(module) if Options.isShowProgress(): memory_watch.finish() Tracing.printLine("Memory usage changed loading module '%s': %s" % (module.getFullName(), memory_watch.asStr()))
def runScons(options, quiet): with setupSconsEnvironment(): scons_command = buildSconsCommand(quiet, options) if Options.isShowScons(): Tracing.printLine("Scons command:", ' '.join(scons_command)) return subprocess.call(scons_command, shell = False) == 0
def runScons(options, quiet): with setupSconsEnvironment(): scons_command = buildSconsCommand(quiet, options) if Options.isShowScons(): Tracing.printLine("Scons command:", ' '.join(scons_command)) return subprocess.call(scons_command, shell=False) == 0
def runScons(options, quiet): # For the scons file to find the static C++ files and include path. The # scons file is unable to use __file__ for the task. os.environ["NUITKA_SCONS"] = getSconsDataPath() if Utils.getOS() == "Windows": # On Windows this Scons variable must be set by us. os.environ["SCONS_LIB_DIR"] = Utils.joinpath( getSconsInlinePath(), "lib", "scons-2.3.0" ) # Also, for MinGW we can avoid the user having to add the path if he # used the default path or installed it on the same drive by appending # to the PATH variable before executing scons. os.environ["PATH"] += r";\MinGW\bin;C:\MinGW\bin" scons_command = getSconsBinaryCall() if quiet: scons_command.append("--quiet") scons_command += [ # The scons file "-f", Utils.joinpath(getSconsDataPath(), "SingleExe.scons"), # Parallel compilation. "--jobs", str(Options.getJobLimit()), # Do not warn about deprecations of Scons "--warn=no-deprecated", # Don't load "site_scons" at all. "--no-site-dir", ] if Options.isShowScons(): scons_command.append("--debug=explain") # Option values to provide to scons. for key, value in options.items(): scons_command += [key + "=" + value] if Options.isShowScons(): Tracing.printLine("Scons command:", " ".join(scons_command)) return 0 == subprocess.call(scons_command)
def runScons(options, quiet): # For the scons file to find the static C++ files and include path. The scons file is # unable to use __file__ for the task. os.environ["NUITKA_SCONS"] = getSconsDataPath() if os.name == "nt": # On Windows this Scons variable must be set by us. os.environ["SCONS_LIB_DIR"] = Utils.joinpath(getSconsInlinePath(), "lib", "scons-2.0.1") # Also, for MinGW we can avoid the user having to add the path if he used the # default path or installed it on the same drive by appending to the PATH variable # before executing scons. os.environ["PATH"] += r";\MinGW\bin;C:\MinGW\bin" # Scons is Python2 only, so we need to make the system find a suitable Python binary. if Utils.python_version < 300: python_exe = sys.executable elif os.name == "nt": if os.path.exists(r"c:\Python27\python.exe"): python_exe = r"c:\Python27\python.exe" elif os.path.exists(r"c:\Python26\python.exe"): python_exe = r"c:\Python26\python.exe" else: sys.exit( """Error, need to find Python2 executable under C:\\Python26 or \ C:\\Python27 to execute scons which is not Python3 compatible.""") else: python_exe = "python" scons_command = """%(python)s %(binary)s %(quiet)s --warn=no-deprecated -f %(scons_file)s --jobs %(job_limit)d %(options)s""" % { "python": python_exe, "binary": getSconsBinaryPath(), "quiet": "--quiet" if quiet else "", "scons_file": Utils.joinpath(getSconsDataPath(), "SingleExe.scons"), "job_limit": Options.getJobLimit(), "options": " ".join("%s=%s" % (key, value) for key, value in options.items()) } if Options.isShowScons(): Tracing.printLine("Scons command:", scons_command) return 0 == os.system(scons_command)
def fromXML(provider, xml, source_ref=None): assert xml.tag == "node", xml kind, node_class, args, source_ref = extractKindAndArgsFromXML( xml, source_ref) if "constant" in args: # TODO: Try and reduce/avoid this, use marshal and/or pickle from a file # global stream instead. For now, this will do. pylint: disable=eval-used args["constant"] = eval(args["constant"]) if kind in ( "ExpressionFunctionBody", "PythonMainModule", "PythonCompiledModule", "PythonCompiledPackage", "PythonInternalModule", ): delayed = node_class.named_children if "code_flags" in args: args["future_spec"] = fromFlags(args["code_flags"]) else: delayed = () for child in xml: assert child.tag == "role", child.tag child_name = child.attrib["name"] # Might want to want until provider is updated with some # children. In these cases, we pass the XML node, rather # than a Nuitka node. if child_name not in delayed: args[child_name] = makeChild(provider, child, source_ref) else: args[child_name] = child try: return node_class.fromXML(provider=provider, source_ref=source_ref, **args) except (TypeError, AttributeError): Tracing.printLine(node_class, args, source_ref) raise
def runScons(options, quiet): # For the scons file to find the static C++ files and include path. The # scons file is unable to use __file__ for the task. os.environ["NUITKA_SCONS"] = getSconsDataPath() if Utils.getOS() == "Windows": # On Windows this Scons variable must be set by us. os.environ["SCONS_LIB_DIR"] = Utils.joinpath( getSconsInlinePath(), "lib", "scons-2.3.2" ) scons_command = getSconsBinaryCall() if quiet: scons_command.append("--quiet") scons_command += [ # The scons file "-f", Utils.joinpath(getSconsDataPath(), "SingleExe.scons"), # Parallel compilation. "--jobs", str(Options.getJobLimit()), # Do not warn about deprecations of Scons "--warn=no-deprecated", # Don't load "site_scons" at all. "--no-site-dir", ] if Options.isShowScons(): scons_command.append("--debug=explain") # Option values to provide to scons. for key, value in options.items(): scons_command += [key + "=" + value] if Options.isShowScons(): Tracing.printLine("Scons command:", " ".join(scons_command)) return 0 == subprocess.call(scons_command, shell = False)
def runScons(options, quiet, scons_filename): with _setupSconsEnvironment(): if Options.shallCompileWithoutBuildDirectory(): # Make sure we become non-local, by changing all paths to be # absolute, but ones that can be resolved by any program # externally, as the Python of Scons may not be good at unicode. options = copy.deepcopy(options) source_dir = options["source_dir"] options["source_dir"] = "." options["result_name"] = getExternalUsePath(options["result_name"], only_dirname=True) options["nuitka_src"] = getExternalUsePath(options["nuitka_src"]) if "result_exe" in options: options["result_exe"] = getExternalUsePath( options["result_exe"], only_dirname=True) if "compiled_exe" in options: options["compiled_exe"] = getExternalUsePath( options["compiled_exe"], only_dirname=True) else: source_dir = None scons_command = _buildSconsCommand(quiet=quiet, options=options, scons_filename=scons_filename) if Options.isShowScons(): Tracing.printLine("Scons command:", " ".join(scons_command)) Tracing.flushStandardOutputs() # Call scons, make sure to pass on quiet setting. with Execution.withEnvironmentVarOverridden( "NUITKA_QUIET", "1" if Tracing.is_quiet else "0"): result = subprocess.call(scons_command, shell=False, cwd=source_dir) flushSconsReports() if result == 0: checkCachingSuccess(source_dir or options["source_dir"]) return result == 0
def runScons( options, quiet ): # For the scons file to find the static C++ files and include path. The scons file is # unable to use __file__ for the task. os.environ[ "NUITKA_SCONS" ] = getSconsDataPath() if os.name == "nt": # On Windows this Scons variable must be set by us. os.environ[ "SCONS_LIB_DIR" ] = Utils.joinpath( getSconsInlinePath(), "lib", "scons-2.0.1" ) # Also, for MinGW we can avoid the user having to add the path if he used the # default path or installed it on the same drive by appending to the PATH variable # before executing scons. os.environ[ "PATH" ] += r";\MinGW\bin;C:\MinGW\bin" # Scons is Python2 only, so we need to make the system find a suitable Python binary. if Utils.python_version < 300: python_exe = sys.executable elif os.name == "nt": if os.path.exists( r"c:\Python27\python.exe" ): python_exe = r"c:\Python27\python.exe" elif os.path.exists( r"c:\Python26\python.exe" ): python_exe = r"c:\Python26\python.exe" else: sys.exit( """Error, need to find Python2 executable under C:\\Python26 or \ C:\\Python27 to execute scons which is not Python3 compatible.""" ) else: python_exe = "python" scons_command = """%(python)s %(binary)s %(quiet)s --warn=no-deprecated -f %(scons_file)s --jobs %(job_limit)d %(options)s""" % { "python" : python_exe, "binary" : getSconsBinaryPath(), "quiet" : "--quiet" if quiet else "", "scons_file" : Utils.joinpath( getSconsDataPath(), "SingleExe.scons" ), "job_limit" : Options.getJobLimit(), "options" : " ".join( "%s=%s" % ( key, value ) for key, value in options.items() ) } if Options.isShowScons(): Tracing.printLine( "Scons command:", scons_command ) return 0 == os.system( scons_command )
def dump(node): Tracing.printLine( ast.dump( node ) )
def _detectImports(command, is_late): # print(command) # Print statements for stuff to show, the modules loaded. if Utils.python_version >= 300: command += '\nimport sys\nprint("\\n".join(sorted("import " + module.__name__ + " # sourcefile " + ' \ 'module.__file__ for module in sys.modules.values() if hasattr(module, "__file__") and ' \ 'module.__file__ != "<frozen>")), file = sys.stderr)' # do not read it, pylint: disable=C0301 import tempfile with tempfile.NamedTemporaryFile(delete=False) as tmp: if Utils.python_version >= 300: command = command.encode('ascii') tmp.write(command) tmp.flush() process = subprocess.Popen( args = [sys.executable, "-s", "-S", "-v", tmp.name], stdout = subprocess.PIPE, stderr = subprocess.PIPE, ) _stdout, stderr = process.communicate() # Don't let errors here go unnoticed. if process.returncode != 0: warning("There is a problem with detecting imports, CPython said:") for line in stderr.split(b"\n"): Tracing.printLine(line) sys.exit("Error, please report the issue with above output.") result = [] debug("Detecting imports:") # bug of PyLint, pylint: disable=E1103 for line in stderr.replace(b"\r", b"").split(b"\n"): if line.startswith(b"import "): # print(line) parts = line.split(b" # ", 2) module_name = parts[0].split(b" ", 2)[1] origin = parts[1].split()[0] if Utils.python_version >= 300: module_name = module_name.decode("utf-8") if origin == b"precompiled": # This is a ".pyc" file that was imported, even before we have a # chance to do anything, we need to preserve it. filename = parts[1][len(b"precompiled from "):] _detectedPrecompiledFile( filename = filename, module_name = module_name, result = result, is_late = is_late ) elif origin == b"sourcefile": filename = parts[1][len(b"sourcefile "):] if filename.endswith(b".py"): _detectedSourceFile( filename = filename, module_name = module_name, result = result, is_late = is_late ) elif not filename.endswith(b"<frozen>"): _detectedShlibFile( filename = filename, module_name = module_name ) elif origin == b"dynamically": # Shared library in early load, happens on RPM based systems and # or self compiled Python installations. filename = parts[1][len(b"dynamically loaded from "):] _detectedShlibFile( filename = filename, module_name = module_name ) return result
def getDependsExePath(): """ Return the path of depends.exe (for Windows). Will prompt the user to download if not already cached in AppData directory for Nuitka. """ if Utils.getArchitecture() == "x86": depends_url = "http://dependencywalker.com/depends22_x86.zip" else: depends_url = "http://dependencywalker.com/depends22_x64.zip" nuitka_app_dir = getAppDir() nuitka_depends_dir = os.path.join(nuitka_app_dir, Utils.getArchitecture()) nuitka_depends_zip = os.path.join(nuitka_depends_dir, os.path.basename(depends_url)) depends_exe = os.path.join(nuitka_depends_dir, "depends.exe") makePath(nuitka_depends_dir) if not os.path.isfile(nuitka_depends_zip) and not os.path.isfile(depends_exe): if assumeYesForDownloads(): reply = "y" else: Tracing.printLine( """\ Nuitka will make use of Dependency Walker (http://dependencywalker.com) tool to analyze the dependencies of Python extension modules. Is it OK to download and put it in "%s". No installer needed, cached, one time question. Proceed and download? [Yes]/No """ % (nuitka_app_dir) ) Tracing.flushStdout() reply = raw_input() if reply.lower() in ("no", "n"): sys.exit("Nuitka does not work in --standalone on Windows without.") info("Downloading '%s'" % depends_url) try: urlretrieve(depends_url, nuitka_depends_zip) except Exception: # Any kind of error, pylint: disable=broad-except sys.exit( """Failed to download '%s'.\ Contents should manually be extracted to '%s'.""" % (depends_url, nuitka_depends_dir) ) if not os.path.isfile(depends_exe): info("Extracting to '%s'" % depends_exe) import zipfile try: depends_zip = zipfile.ZipFile(nuitka_depends_zip) depends_zip.extractall(nuitka_depends_dir) except Exception: # Catching anything zip throws, pylint:disable=W0703 info("Problem with the downloaded zip file, deleting it.") deleteFile(depends_exe, must_exist=False) deleteFile(nuitka_depends_zip, must_exist=True) sys.exit( "Error, need '%s' as extracted from '%s'." % (depends_exe, depends_url) ) assert os.path.isfile(depends_exe) return depends_exe
def getCachedDownload( url, binary, flatten, is_arch_specific, specificity, message, reject, assume_yes_for_downloads, ): # Many branches to deal with, pylint: disable=too-many-branches,too-many-statements nuitka_app_dir = getAppDir() nuitka_app_dir = os.path.join(nuitka_app_dir, os.path.basename(binary).replace(".exe", "")) if is_arch_specific: nuitka_app_dir = os.path.join(nuitka_app_dir, is_arch_specific) if specificity: nuitka_app_dir = os.path.join(nuitka_app_dir, specificity) download_path = os.path.join(nuitka_app_dir, os.path.basename(url)) exe_path = os.path.join(nuitka_app_dir, binary) makePath(nuitka_app_dir) if not os.path.isfile(download_path) and not os.path.isfile(exe_path): if assume_yes_for_downloads: reply = "y" else: Tracing.printLine("""\ %s Is it OK to download and put it in '%s'. No installer needed, cached, one time question. Proceed and download? [Yes]/No """ % (message, nuitka_app_dir)) Tracing.flushStandardOutputs() try: reply = raw_input() except EOFError: reply = "no" if reply.lower() in ("no", "n"): if reject is not None: Tracing.general.sysexit(reject) else: Tracing.general.info("Downloading '%s'." % url) try: urlretrieve(url, download_path) except Exception: # Any kind of error, pylint: disable=broad-except try: urlretrieve(url.replace("https://", "http://"), download_path) except Exception: # Any kind of error, pylint: disable=broad-except Tracing.general.sysexit( "Failed to download '%s'. Contents should manually be copied to '%s'." % (url, download_path)) if not os.path.isfile(exe_path) and os.path.isfile(download_path): Tracing.general.info("Extracting to '%s'" % exe_path) import zipfile try: # Not all Python versions support using it as a context manager, pylint: disable=consider-using-with zip_file = zipfile.ZipFile(download_path) for zip_info in zip_file.infolist(): if zip_info.filename[-1] == "/": continue if flatten: zip_info.filename = os.path.basename(zip_info.filename) zip_file.extract(zip_info, nuitka_app_dir) except Exception: # Catching anything zip throws, pylint: disable=broad-except Tracing.general.info( "Problem with the downloaded zip file, deleting it.") deleteFile(binary, must_exist=False) deleteFile(download_path, must_exist=True) Tracing.general.sysexit("Error, need %r as extracted from %r." % (binary, url)) # Check success here, and make sure it's executable. if os.path.isfile(exe_path): addFileExecutablePermission(exe_path) else: if reject: Tracing.general.sysexit(reject) exe_path = None return exe_path
def _detectImports(command, is_late): # print(command) # Print statements for stuff to show, the modules loaded. if Utils.python_version >= 300: command += '\nimport sys\nprint("\\n".join(sorted("import " + module.__name__ + " # sourcefile " + ' \ 'module.__file__ for module in sys.modules.values() if hasattr(module, "__file__") and ' \ 'module.__file__ != "<frozen>")), file = sys.stderr)' # do not read it, pylint: disable=C0301 import tempfile with tempfile.NamedTemporaryFile(delete=False) as tmp: if Utils.python_version >= 300: command = command.encode('ascii') tmp.write(command) tmp.flush() process = subprocess.Popen( args=[sys.executable, "-s", "-S", "-v", tmp.name], stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) _stdout, stderr = process.communicate() # Don't let errors here go unnoticed. if process.returncode != 0: warning("There is a problem with detecting imports, CPython said:") for line in stderr.split(b"\n"): Tracing.printLine(line) sys.exit("Error, please report the issue with above output.") result = [] debug("Detecting imports:") # bug of PyLint, pylint: disable=E1103 for line in stderr.replace(b"\r", b"").split(b"\n"): if line.startswith(b"import "): # print(line) parts = line.split(b" # ", 2) module_name = parts[0].split(b" ", 2)[1] origin = parts[1].split()[0] if Utils.python_version >= 300: module_name = module_name.decode("utf-8") if origin == b"precompiled": # This is a ".pyc" file that was imported, even before we have a # chance to do anything, we need to preserve it. filename = parts[1][len(b"precompiled from "):] _detectedPrecompiledFile(filename=filename, module_name=module_name, result=result, is_late=is_late) elif origin == b"sourcefile": filename = parts[1][len(b"sourcefile "):] if filename.endswith(b".py"): _detectedSourceFile(filename=filename, module_name=module_name, result=result, is_late=is_late) elif not filename.endswith(b"<frozen>"): _detectedShlibFile(filename=filename, module_name=module_name) elif origin == b"dynamically": # Shared library in early load, happens on RPM based systems and # or self compiled Python installations. filename = parts[1][len(b"dynamically loaded from "):] _detectedShlibFile(filename=filename, module_name=module_name) return result
def getDependsExePath(): """ Return the path of depends.exe (for Windows). Will prompt the user to download if not already cached in AppData directory for Nuitka. """ if Utils.getArchitecture() == "x86": depends_url = "http://dependencywalker.com/depends22_x86.zip" else: depends_url = "http://dependencywalker.com/depends22_x64.zip" if "APPDATA" not in os.environ: sys.exit("Error, standalone mode cannot find 'APPDATA' environment.") nuitka_app_dir = os.path.join(os.environ["APPDATA"], "nuitka") if not os.path.isdir(nuitka_app_dir): makePath(nuitka_app_dir) nuitka_depends_zip = os.path.join(nuitka_app_dir, os.path.basename(depends_url)) if not os.path.isfile(nuitka_depends_zip): Tracing.printLine("""\ Nuitka will make use of Dependency Walker (http://dependencywalker.com) tool to analyze the dependencies of Python extension modules. Is it OK to download and put it in APPDATA (no installer needed, cached, one time question).""") reply = raw_input("Proceed and download? [Yes]/No ") if reply.lower() in ("no", 'n'): sys.exit( "Nuitka does not work in --standalone on Windows without.") info("Downloading '%s'" % depends_url) urlretrieve(depends_url, nuitka_depends_zip) nuitka_depends_dir = os.path.join(nuitka_app_dir, Utils.getArchitecture()) if not os.path.isdir(nuitka_depends_dir): os.makedirs(nuitka_depends_dir) depends_exe = os.path.join(nuitka_depends_dir, "depends.exe") if not os.path.isfile(depends_exe): info("Extracting to '%s'" % depends_exe) import zipfile try: depends_zip = zipfile.ZipFile(nuitka_depends_zip) depends_zip.extractall(nuitka_depends_dir) except Exception: # Catching anything zip throws, pylint:disable=W0703 info("Problem with the downloaded zip file, deleting it.") deleteFile(depends_exe, must_exist=False) deleteFile(nuitka_depends_zip, must_exist=True) sys.exit("Error, need '%s' as extracted from '%s'." % (depends_exe, depends_url)) assert os.path.isfile(depends_exe) return depends_exe
def getDependsExePath(): """ Return the path of depends.exe (for Windows). Will prompt the user to download if not already cached in AppData directory for Nuitka. """ if Utils.getArchitecture() == "x86": depends_url = "http://dependencywalker.com/depends22_x86.zip" else: depends_url = "http://dependencywalker.com/depends22_x64.zip" if "APPDATA" not in os.environ: sys.exit("Error, standalone mode cannot find 'APPDATA' environment.") nuitka_app_dir = os.path.join(os.environ["APPDATA"], "nuitka") if not Utils.isDir(nuitka_app_dir): os.makedirs(nuitka_app_dir) nuitka_depends_zip = os.path.join( nuitka_app_dir, os.path.basename(depends_url) ) if not Utils.isFile(nuitka_depends_zip): Tracing.printLine("""\ Nuitka will make use of Dependency Walker (http://dependencywalker.com) tool to analyze the dependencies of Python extension modules. Is it OK to download and put it in APPDATA (no installer needed, cached, one time question).""") reply = raw_input("Proceed and download? [Yes]/No ") if reply.lower() in ("no", "n"): sys.exit("Nuitka does not work in --standalone on Windows without.") info("Downloading '%s'" % depends_url) urlretrieve( depends_url, nuitka_depends_zip ) nuitka_depends_dir = os.path.join( nuitka_app_dir, Utils.getArchitecture() ) if not Utils.isDir(nuitka_depends_dir): os.makedirs(nuitka_depends_dir) depends_exe = os.path.join( nuitka_depends_dir, "depends.exe" ) if not Utils.isFile(depends_exe): info("Extracting to '%s'" % depends_exe) import zipfile try: depends_zip = zipfile.ZipFile(nuitka_depends_zip) depends_zip.extractall(nuitka_depends_dir) except Exception: # Catching anything zip throws, pylint:disable=W0703 info("Problem with the downloaded zip file, deleting it.") Utils.deleteFile(depends_exe, must_exist = False) Utils.deleteFile(nuitka_depends_zip, must_exist = True) sys.exit( "Error, need '%s' as extracted from '%s'." % ( depends_exe, depends_url ) ) assert Utils.isFile(depends_exe) return depends_exe
def getDependsExePath(): """ Return the path of depends.exe (for Windows). Will prompt the user to download if not already cached in AppData directory for Nuitka. """ if Utils.getArchitecture() == "x86": depends_url = "http://dependencywalker.com/depends22_x86.zip" else: depends_url = "http://dependencywalker.com/depends22_x64.zip" nuitka_app_dir = getAppDir() nuitka_depends_dir = os.path.join(nuitka_app_dir, Utils.getArchitecture()) nuitka_depends_zip = os.path.join(nuitka_depends_dir, os.path.basename(depends_url)) depends_exe = os.path.join(nuitka_depends_dir, "depends.exe") makePath(nuitka_depends_dir) if not os.path.isfile(nuitka_depends_zip) and not os.path.isfile( depends_exe): if assumeYesForDownloads(): reply = "y" else: Tracing.printLine("""\ Nuitka will make use of Dependency Walker (http://dependencywalker.com) tool to analyze the dependencies of Python extension modules. Is it OK to download and put it in "%s". No installer needed, cached, one time question. Proceed and download? [Yes]/No """ % (nuitka_app_dir)) Tracing.flushStdout() reply = raw_input() if reply.lower() in ("no", "n"): sys.exit( "Nuitka does not work in --standalone on Windows without.") info("Downloading '%s'" % depends_url) try: urlretrieve(depends_url, nuitka_depends_zip) except Exception: # Any kind of error, pylint: disable=broad-except sys.exit("""Failed to download '%s'.\ Contents should manually be extracted to '%s'.""" % (depends_url, nuitka_depends_dir)) if not os.path.isfile(depends_exe): info("Extracting to '%s'" % depends_exe) import zipfile try: depends_zip = zipfile.ZipFile(nuitka_depends_zip) depends_zip.extractall(nuitka_depends_dir) except Exception: # Catching anything zip throws, pylint: disable=broad-except info("Problem with the downloaded zip file, deleting it.") deleteFile(depends_exe, must_exist=False) deleteFile(nuitka_depends_zip, must_exist=True) sys.exit("Error, need '%s' as extracted from '%s'." % (depends_exe, depends_url)) assert os.path.isfile(depends_exe) return depends_exe
def _detectImports(command, is_late): # This is pretty complicated stuff, with variants to deal with. # pylint: disable=R0912 # Print statements for stuff to show, the modules loaded. if Utils.python_version >= 300: command += '\nimport sys\nprint("\\n".join(sorted("import " + module.__name__ + " # sourcefile " + ' \ 'module.__file__ for module in sys.modules.values() if hasattr(module, "__file__") and ' \ 'module.__file__ != "<frozen>")), file = sys.stderr)' # do not read it # Make sure the right import path (the one Nuitka binary is running with) # is used. command = ("import sys; sys.path = %s;" % repr(sys.path)) + command import tempfile tmp_file, tmp_filename = tempfile.mkstemp() try: if Utils.python_version >= 300: command = command.encode('ascii') os.write(tmp_file, command) os.close(tmp_file) process = subprocess.Popen( args=[sys.executable, "-s", "-S", "-v", tmp_filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) _stdout, stderr = process.communicate() finally: os.unlink(tmp_filename) # Don't let errors here go unnoticed. if process.returncode != 0: warning("There is a problem with detecting imports, CPython said:") for line in stderr.split(b"\n"): Tracing.printLine(line) sys.exit("Error, please report the issue with above output.") result = [] debug("Detecting imports:") for line in stderr.replace(b"\r", b"").split(b"\n"): if line.startswith(b"import "): # print(line) parts = line.split(b" # ", 2) module_name = parts[0].split(b" ", 2)[1] origin = parts[1].split()[0] if Utils.python_version >= 300: module_name = module_name.decode("utf-8") if origin == b"precompiled": # This is a ".pyc" file that was imported, even before we have a # chance to do anything, we need to preserve it. filename = parts[1][len(b"precompiled from "):] _detectedPrecompiledFile(filename=filename, module_name=module_name, result=result, is_late=is_late) elif origin == b"sourcefile": filename = parts[1][len(b"sourcefile "):] if filename.endswith(b".py"): _detectedSourceFile(filename=filename, module_name=module_name, result=result, is_late=is_late) elif not filename.endswith(b"<frozen>"): _detectedShlibFile(filename=filename, module_name=module_name) elif origin == b"dynamically": # Shared library in early load, happens on RPM based systems and # or self compiled Python installations. filename = parts[1][len(b"dynamically loaded from "):] _detectedShlibFile(filename=filename, module_name=module_name) return result
def runScons(options, quiet): # For the scons file to find the static C++ files and include path. The # scons file is unable to use __file__ for the task. os.environ["NUITKA_SCONS"] = getSconsDataPath() if Utils.getOS() == "Windows": # On Windows this Scons variable must be set by us. os.environ["SCONS_LIB_DIR"] = Utils.joinpath( getSconsInlinePath(), "lib", "scons-2.3.2" ) scons_command = getSconsBinaryCall() if quiet: scons_command.append("--quiet") scons_command += [ # The scons file "-f", Utils.joinpath(getSconsDataPath(), "SingleExe.scons"), # Parallel compilation. "--jobs", str(Options.getJobLimit()), # Do not warn about deprecation from Scons "--warn=no-deprecated", # Don't load "site_scons" at all. "--no-site-dir", ] if Options.isShowScons(): scons_command.append("--debug=explain") # Option values to provide to scons. Find these in the caller. for key, value in options.items(): scons_command += [key + '=' + value] if Options.isShowScons(): Tracing.printLine("Scons command:", ' '.join(scons_command)) # Remove environment variables that can only harm if we have to switch # major Python versions, these cannot help Python2 to execute scons, this # is a bit of noise, but helpful, pylint: disable=R0912 if Utils.python_version >= 300: if "PYTHONPATH" in os.environ: old_pythonpath = os.environ["PYTHONPATH"] del os.environ["PYTHONPATH"] else: old_pythonpath = None if "PYTHONHOME" in os.environ: old_pythonhome = os.environ["PYTHONHOME"] del os.environ["PYTHONHOME"] else: old_pythonhome = None result = 0 == subprocess.call(scons_command, shell = False) if Utils.python_version >= 300: if old_pythonpath is not None: os.environ["PYTHONPATH"] = old_pythonpath if old_pythonhome is not None: os.environ["PYTHONHOME"] = old_pythonhome return result
def _detectImports(command, is_late): # This is pretty complicated stuff, with variants to deal with. # pylint: disable=R0912,R0914 # Print statements for stuff to show, the modules loaded. if Utils.python_version >= 300: command += '\nimport sys\nprint("\\n".join(sorted("import " + module.__name__ + " # sourcefile " + ' \ 'module.__file__ for module in sys.modules.values() if hasattr(module, "__file__") and ' \ 'module.__file__ != "<frozen>")), file = sys.stderr)' # do not read it reduced_path = [ path_element for path_element in sys.path if not Utils.areSamePaths( path_element, '.' ) if not Utils.areSamePaths( path_element, Utils.dirname(sys.modules["__main__"].__file__) ) ] # Make sure the right import path (the one Nuitka binary is running with) # is used. command = ("import sys; sys.path = %s;" % repr(reduced_path)) + command import tempfile tmp_file, tmp_filename = tempfile.mkstemp() try: if Utils.python_version >= 300: command = command.encode("ascii") os.write(tmp_file, command) os.close(tmp_file) process = subprocess.Popen( args = [sys.executable, "-s", "-S", "-v", tmp_filename], stdout = subprocess.PIPE, stderr = subprocess.PIPE, ) _stdout, stderr = process.communicate() finally: os.unlink(tmp_filename) # Don't let errors here go unnoticed. if process.returncode != 0: warning("There is a problem with detecting imports, CPython said:") for line in stderr.split(b"\n"): Tracing.printLine(line) sys.exit("Error, please report the issue with above output.") result = [] debug("Detecting imports:") for line in stderr.replace(b"\r", b"").split(b"\n"): if line.startswith(b"import "): # print(line) parts = line.split(b" # ", 2) module_name = parts[0].split(b" ", 2)[1] origin = parts[1].split()[0] if Utils.python_version >= 300: module_name = module_name.decode("utf-8") if origin == b"precompiled": # This is a ".pyc" file that was imported, even before we have a # chance to do anything, we need to preserve it. filename = parts[1][len(b"precompiled from "):] _detectedPrecompiledFile( filename = filename, module_name = module_name, result = result, is_late = is_late ) elif origin == b"sourcefile": filename = parts[1][len(b"sourcefile "):] if filename.endswith(b".py"): _detectedSourceFile( filename = filename, module_name = module_name, result = result, is_late = is_late ) elif not filename.endswith(b"<frozen>"): _detectedShlibFile( filename = filename, module_name = module_name ) elif origin == b"dynamically": # Shared library in early load, happens on RPM based systems and # or self compiled Python installations. filename = parts[1][len(b"dynamically loaded from "):] _detectedShlibFile( filename = filename, module_name = module_name ) return result
def _detectImports(command, user_provided, technical): # This is pretty complicated stuff, with variants to deal with. # pylint: disable=R0912,R0914,R0915 # Print statements for stuff to show, the modules loaded. if python_version >= 300: command += '\nimport sys\nprint("\\n".join(sorted("import " + module.__name__ + " # sourcefile " + ' \ 'module.__file__ for module in sys.modules.values() if hasattr(module, "__file__") and ' \ 'module.__file__ != "<frozen>")), file = sys.stderr)' # do not read it reduced_path = [ path_element for path_element in sys.path if not Utils.areSamePaths( path_element, '.' ) if not Utils.areSamePaths( path_element, Utils.dirname(sys.modules["__main__"].__file__) ) ] # Make sure the right import path (the one Nuitka binary is running with) # is used. command = ("import sys; sys.path = %s;" % repr(reduced_path)) + command import tempfile tmp_file, tmp_filename = tempfile.mkstemp() try: if python_version >= 300: command = command.encode("ascii") os.write(tmp_file, command) os.close(tmp_file) process = subprocess.Popen( args = [sys.executable, "-s", "-S", "-v", tmp_filename], stdout = subprocess.PIPE, stderr = subprocess.PIPE, ) _stdout, stderr = process.communicate() finally: os.unlink(tmp_filename) # Don't let errors here go unnoticed. if process.returncode != 0: warning("There is a problem with detecting imports, CPython said:") for line in stderr.split(b"\n"): Tracing.printLine(line) sys.exit("Error, please report the issue with above output.") result = [] debug("Detecting imports:") for line in stderr.replace(b"\r", b"").split(b"\n"): if line.startswith(b"import "): # print(line) parts = line.split(b" # ", 2) module_name = parts[0].split(b" ", 2)[1] origin = parts[1].split()[0] if python_version >= 300: module_name = module_name.decode("utf-8") if origin == b"precompiled": # This is a ".pyc" file that was imported, even before we have a # chance to do anything, we need to preserve it. filename = parts[1][len(b"precompiled from "):] if python_version >= 300: filename = filename.decode("utf-8") # Do not leave standard library when freezing. if not isStandardLibraryPath(filename): continue _detectedPrecompiledFile( filename = filename, module_name = module_name, result = result, user_provided = user_provided, technical = technical ) elif origin == b"sourcefile": filename = parts[1][len(b"sourcefile "):] if python_version >= 300: filename = filename.decode("utf-8") # Do not leave standard library when freezing. if not isStandardLibraryPath(filename): continue if filename.endswith(".py"): _detectedSourceFile( filename = filename, module_name = module_name, result = result, user_provided = user_provided, technical = technical ) elif not filename.endswith("<frozen>"): # Python3 started lying in "__name__" for the "_decimal" # calls itself "decimal", which then is wrong and also # clashes with "decimal" proper if python_version >= 300: if module_name == "decimal": module_name = "_decimal" _detectedShlibFile( filename = filename, module_name = module_name ) elif origin == b"dynamically": # Shared library in early load, happens on RPM based systems and # or self compiled Python installations. filename = parts[1][len(b"dynamically loaded from "):] if python_version >= 300: filename = filename.decode("utf-8") # Do not leave standard library when freezing. if not isStandardLibraryPath(filename): continue _detectedShlibFile( filename = filename, module_name = module_name ) return result
def dump(node): Tracing.printLine(ast.dump(node))
def runScons(options, quiet): # For the scons file to find the static C++ files and include path. The # scons file is unable to use __file__ for the task. os.environ["NUITKA_SCONS"] = getSconsDataPath() if Utils.getOS() == "Windows": # On Windows this Scons variable must be set by us. os.environ["SCONS_LIB_DIR"] = Utils.joinpath(getSconsInlinePath(), "lib", "scons-2.3.2") scons_command = getSconsBinaryCall() if quiet: scons_command.append("--quiet") scons_command += [ # The scons file "-f", Utils.joinpath(getSconsDataPath(), "SingleExe.scons"), # Parallel compilation. "--jobs", str(Options.getJobLimit()), # Do not warn about deprecation from Scons "--warn=no-deprecated", # Don't load "site_scons" at all. "--no-site-dir", ] if Options.isShowScons(): scons_command.append("--debug=explain") # Option values to provide to scons. Find these in the caller. for key, value in options.items(): scons_command += [key + '=' + value] if Options.isShowScons(): Tracing.printLine("Scons command:", ' '.join(scons_command)) # Remove environment variables that can only harm if we have to switch # major Python versions, these cannot help Python2 to execute scons, this # is a bit of noise, but helpful, pylint: disable=R0912 if Utils.python_version >= 300: if "PYTHONPATH" in os.environ: old_pythonpath = os.environ["PYTHONPATH"] del os.environ["PYTHONPATH"] else: old_pythonpath = None if "PYTHONHOME" in os.environ: old_pythonhome = os.environ["PYTHONHOME"] del os.environ["PYTHONHOME"] else: old_pythonhome = None result = 0 == subprocess.call(scons_command, shell=False) if Utils.python_version >= 300: if old_pythonpath is not None: os.environ["PYTHONPATH"] = old_pythonpath if old_pythonhome is not None: os.environ["PYTHONHOME"] = old_pythonhome return result