def copyUsedDLLs(dist_dir, binary_filename, standalone_entry_points): dll_map = [] used_dlls = detectUsedDLLs(standalone_entry_points) for dll_filename1, sources1 in iterItems(used_dlls): for dll_filename2, sources2 in iterItems(used_dlls): if dll_filename1 == dll_filename2: continue # Colliding basenames are an issue to us. if Utils.basename(dll_filename1) != Utils.basename(dll_filename2): continue dll_name = Utils.basename(dll_filename1) if Options.isShowInclusion(): info("""Colliding DLL names for %s, checking identity of \ '%s' <-> '%s'.""" % ( dll_name, dll_filename1, dll_filename2, )) # Check that if a DLL has the same name, if it's identical, # happens at least for OSC and Fedora 20. import filecmp if filecmp.cmp(dll_filename1, dll_filename2): continue sys.exit("""Error, conflicting DLLs for '%s' \ (%s used by %s different from %s used by %s).""" % (dll_name, dll_filename1, ", ".join(sources1), dll_filename2, ", ".join(sources2))) for dll_filename, sources in iterItems(used_dlls): dll_name = Utils.basename(dll_filename) target_path = Utils.joinpath(dist_dir, dll_name) shutil.copy(dll_filename, target_path) dll_map.append((dll_filename, dll_name)) if Options.isShowInclusion(): info("Included used shared library '%s' (used by %s)." % (dll_filename, ", ".join(sources))) if Utils.getOS() == "Darwin": # For MacOS, the binary needs to be changed to reflect the DLL # location in the dist folder. fixupBinaryDLLPaths(binary_filename, dll_map) if Utils.getOS() == "Linux": # For Linux, the rpath of libraries may be an issue. for _original_path, dll_filename in dll_map: removeSharedLibraryRPATH(Utils.joinpath(dist_dir, dll_filename)) for standalone_entry_point in standalone_entry_points[1:]: removeSharedLibraryRPATH(standalone_entry_point[0])
def isSameModulePath(path1, path2): if Utils.basename(path1) == "__init__.py": path1 = Utils.dirname(path1) if Utils.basename(path2) == "__init__.py": path2 = Utils.dirname(path2) return Utils.abspath(path1) == Utils.abspath(path2)
def _detectedSourceFile(filename, module_name, result, is_late): if module_name in module_names: return if module_name == "collections.abc": _detectedSourceFile(filename=filename, module_name="_collections_abc", result=result, is_late=is_late) source_code = readSourceCodeFromFilename(filename) if Utils.python_version >= 300: filename = filename.decode("utf-8") if module_name == "site": source_code = """\ __file__ = (__nuitka_binary_dir + '%s%s') if '__nuitka_binary_dir' in dict(__builtins__ ) else '<frozen>';%s""" % ( os.path.sep, Utils.basename(filename), source_code) debug("Freezing module '%s' (from '%s').", module_name, filename) result.append( (module_name, marshal.dumps(compile(source_code, filename, "exec")), Utils.basename(filename) == "__init__.py", filename, is_late)) module_names.add(module_name)
def getRunTimeFilename(self): if Options.isStandaloneMode(): filename = self.getCompileTimeFilename() full_name = self.getFullName() result = Utils.basename(filename) current = filename for _i in range(full_name.count('.')): current = Utils.dirname(current) result = Utils.joinpath(Utils.basename(current), result) return result else: return self.getCompileTimeFilename()
def _consider(self, constraint_collection, module_filename, module_package): assert module_package is None or (type(module_package) is str and module_package != "") module_filename = Utils.normpath(module_filename) if Utils.isDir(module_filename): module_name = Utils.basename(module_filename) elif module_filename.endswith(".py"): module_name = Utils.basename(module_filename)[:-3] else: module_name = None if module_name is not None: decision = self._decide(module_filename, module_name, module_package) if decision: module_relpath = Utils.relpath(module_filename) return self._recurseTo( constraint_collection=constraint_collection, module_package=module_package, module_filename=module_filename, module_relpath=module_relpath) elif decision is None: if module_package is None: module_fullpath = module_name else: module_fullpath = module_package + "." + module_name if module_filename not in self._warned_about: self._warned_about.add(module_filename) warning( # long message, but shall be like it, pylint: disable=C0301 """\ Not recursing to '%(full_path)s' (%(filename)s), please specify \ --recurse-none (do not warn), \ --recurse-all (recurse to all), \ --recurse-not-to=%(full_path)s (ignore it), \ --recurse-to=%(full_path)s (recurse to it) to change.""" % { "full_path": module_fullpath, "filename": module_filename })
def __init__(self, name, package_name, source_ref): NodeBase.__init__(self, source_ref=source_ref) PythonModuleMixin.__init__(self, name=name, package_name=package_name) assert Utils.basename(source_ref.getFilename()) != "<frozen>" # That is too likely a bug. assert name != "__main__"
def getImportedModule(module_relpath): module_name = Utils.basename(module_relpath) if module_name.endswith(".py"): module_name = module_name[:-3] key = module_relpath, module_name return imported_modules[key]
def isImportedPath( module_relpath ): module_name = Utils.basename( module_relpath ) if module_name.endswith( ".py" ): module_name = module_name[:-3] key = module_relpath, module_name return key in imported_modules
def getImportedModule( module_relpath ): module_name = Utils.basename( module_relpath ) if module_name.endswith( ".py" ): module_name = module_name[:-3] key = module_relpath, module_name return imported_modules[ key ]
def isImportedPath(module_relpath): module_name = Utils.basename(module_relpath) if module_name.endswith(".py"): module_name = module_name[:-3] key = module_relpath, module_name return key in imported_modules
def _consider( self, constraint_collection, module_filename, module_package ): assert module_package is None or ( type( module_package ) is str and module_package != "" ) module_filename = Utils.normpath( module_filename ) if Utils.isDir( module_filename ): module_name = Utils.basename( module_filename ) elif module_filename.endswith( ".py" ): module_name = Utils.basename( module_filename )[:-3] else: module_name = None if module_name is not None: decision = self._decide( module_filename, module_name, module_package ) if decision: module_relpath = Utils.relpath( module_filename ) return self._recurseTo( constraint_collection = constraint_collection, module_package = module_package, module_filename = module_filename, module_relpath = module_relpath ) elif decision is None: if module_package is None: module_fullpath = module_name else: module_fullpath = module_package + "." + module_name if module_filename not in self._warned_about: self._warned_about.add( module_filename ) warning( # long message, but shall be like it, pylint: disable=C0301 """\ Not recursing to '%(full_path)s' (%(filename)s), please specify \ --recurse-none (do not warn), \ --recurse-all (recurse to all), \ --recurse-not-to=%(full_path)s (ignore it), \ --recurse-to=%(full_path)s (recurse to it) to change.""" % { "full_path" : module_fullpath, "filename" : module_filename } )
def considerFilename( module_filename, module_package ): assert module_package is None or ( type( module_package ) is str and module_package != "" ) module_filename = Utils.normpath( module_filename ) if Utils.isDir( module_filename ): module_filename = Utils.abspath( module_filename ) module_name = Utils.basename( module_filename ) module_relpath = Utils.relpath( module_filename ) return module_filename, module_relpath, module_name elif module_filename.endswith( ".py" ): module_name = Utils.basename( module_filename )[:-3] module_relpath = Utils.relpath( module_filename ) return module_filename, module_relpath, module_name else: return None
def considerFilename(module_filename, module_package): assert module_package is None or \ ( type( module_package ) is str and module_package != "" ) module_filename = Utils.normpath( module_filename ) if Utils.isDir( module_filename ): module_filename = Utils.abspath( module_filename ) module_name = Utils.basename( module_filename ) module_relpath = Utils.relpath( module_filename ) return module_filename, module_relpath, module_name elif module_filename.endswith( ".py" ): module_name = Utils.basename( module_filename )[:-3] module_relpath = Utils.relpath( module_filename ) return module_filename, module_relpath, module_name else: return None
def __init__(self, name, package_name, source_ref): NodeBase.__init__( self, source_ref = source_ref ) PythonModuleMixin.__init__( self, name = name, package_name = package_name ) assert Utils.basename(source_ref.getFilename()) != "<frozen>"
def copyUsedDLLs(dist_dir, binary_filename, standalone_entry_points): dll_map = [] for early_dll in detectUsedDLLs(standalone_entry_points): dll_name = Utils.basename(early_dll) target_path = Utils.joinpath( dist_dir, dll_name ) # Check that if a DLL has the name name, if it's identical, # happens at least for OSC and Fedora 20. if Utils.isFile(target_path): import filecmp if filecmp.cmp(early_dll, target_path): continue else: sys.exit("Error, conflicting DLLs for '%s'." % dll_name) shutil.copy( early_dll, target_path ) dll_map.append( (early_dll, dll_name) ) if Options.isShowInclusion(): info("Included used shared library '%s'.", early_dll) if Utils.getOS() == "Darwin": # For MacOS, the binary needs to be changed to reflect the DLL # location in the dist folder. fixupBinaryDLLPaths(binary_filename, dll_map) if Utils.getOS() == "Linux": # For Linux, the rpath of libraries may be an issue. for _original_path, early_dll in dll_map: removeSharedLibraryRPATH( Utils.joinpath(dist_dir, early_dll) ) for standalone_entry_point in standalone_entry_points[1:]: removeSharedLibraryRPATH( standalone_entry_point[0] )
def __init__(self, name, package_name, source_ref): NodeBase.__init__( self, source_ref = source_ref ) PythonModuleMixin.__init__( self, name = name, package_name = package_name ) assert Utils.basename(source_ref.getFilename()) != "<frozen>" # That is too likely a bug. assert name != "__main__"
def _detectedSourceFile(filename, module_name, result, is_late): if module_name in module_names: return if module_name == "collections.abc": _detectedSourceFile( filename = filename, module_name = "_collections_abc", result = result, is_late = is_late ) source_code = open(filename,"rb").read() if Utils.python_version >= 300: source_code = source_code.decode("utf-8") filename = filename.decode("utf-8") if module_name == "site": source_code = """\ __file__ = (__nuitka_binary_dir + '%s%s') if '__nuitka_binary_dir' in dict(__builtins__ ) else '<frozen>';%s""" % ( os.path.sep, os.path.basename(filename), source_code ) debug( "Freezing module '%s' (from '%s').", module_name, filename ) result.append( ( module_name, marshal.dumps( compile(source_code, filename, "exec") ), Utils.basename(filename) == "__init__.py", filename, is_late ) ) module_names.add(module_name)
def _detectedSourceFile(filename, module_name, result, is_late): source_code = open(filename,"rb").read() if Utils.python_version >= 300: source_code = source_code.decode("utf-8") filename = filename.decode("utf-8") if module_name in module_names: return if module_name == "site": source_code = "__file__ = (__nuitka_binary_dir + '%s%s') if '__nuitka_binary_dir' in dict(__builtins__ ) else '<xxxfrozen>';%s" % ( os.path.sep, os.path.basename(filename), source_code ) debug( "Freezing module '%s' (from '%s').", module_name, filename ) result.append( ( module_name, marshal.dumps( compile(source_code, filename, "exec") ), Utils.basename(filename) == "__init__.py", filename, is_late ) ) module_names.add(module_name)
def _consider(self, constraint_collection, module_filename, module_package): assert module_package is None or \ (type(module_package) is str and module_package != "") module_filename = Utils.normpath(module_filename) if Utils.isDir(module_filename): module_name = Utils.basename(module_filename) module_kind = "py" elif module_filename.endswith(".py"): module_name = Utils.basename(module_filename)[:-3] module_kind = "py" elif module_filename.endswith(".so"): module_kind = "shlib" module_name = Utils.basename(module_filename)[:-3] elif module_filename.endswith(".pyd"): module_kind = "shlib" module_name = Utils.basename(module_filename)[:-4] else: module_kind = None module_name = None if module_kind is not None: from nuitka.tree import Recursion decision, reason = Recursion.decideRecursion( module_filename = module_filename, module_name = module_name, module_package = module_package, module_kind = module_kind ) if decision: module_relpath = Utils.relpath(module_filename) imported_module, added_flag = Recursion.recurseTo( module_package = module_package, module_filename = module_filename, module_relpath = module_relpath, module_kind = module_kind, reason = reason ) if added_flag: constraint_collection.signalChange( "new_code", imported_module.getSourceReference(), "Recursed to module." ) return imported_module elif decision is None and module_kind == "py": if module_package is None: module_fullpath = module_name else: module_fullpath = module_package + "." + module_name if module_filename not in self._warned_about and \ module_fullpath not in getModuleWhiteList(): self._warned_about.add(module_filename) warning( """\ Not recursing to '%(full_path)s' (%(filename)s), please specify \ --recurse-none (do not warn), \ --recurse-all (recurse to all), \ --recurse-not-to=%(full_path)s (ignore it), \ --recurse-to=%(full_path)s (recurse to it) to change.""" % { "full_path" : module_fullpath, "filename" : module_filename } )
def buildModuleTree( filename, package, is_top, is_main ): # Many variables, branches, due to the many cases, pylint: disable=R0912 assert package is None or type( package ) is str if is_main and Utils.isDir( filename ): source_filename = Utils.joinpath( filename, "__main__.py" ) if not Utils.isFile( source_filename ): sys.stderr.write( "%s: can't find '__main__' module in '%s'\n" % ( Utils.basename( sys.argv[0] ), filename ) ) sys.exit( 2 ) filename = source_filename main_added = True else: main_added = False if Utils.isFile( filename ): source_filename = filename source_ref = SourceCodeReferences.fromFilename( filename = filename, future_spec = FutureSpec() ) if is_main: module_name = "__main__" else: module_name = Utils.basename( filename ) if module_name.endswith( ".py" ): module_name = module_name[:-3] if "." in module_name: sys.stderr.write( "Error, '%s' is not a proper python module name.\n" % ( module_name ) ) sys.exit( 2 ) if is_main: result = PythonMainModule( source_ref = source_ref, main_added = main_added ) else: result = PythonModule( name = module_name, package = package, source_ref = source_ref ) elif Utils.isDir( filename ) and Utils.isFile( Utils.joinpath( filename, "__init__.py" ) ): source_filename = Utils.joinpath( filename, "__init__.py" ) if is_top: source_ref = SourceCodeReferences.fromFilename( filename = Utils.abspath( source_filename ), future_spec = FutureSpec() ) package_name = Utils.splitpath( filename )[-1] else: source_ref = SourceCodeReferences.fromFilename( filename = Utils.abspath( source_filename ), future_spec = FutureSpec() ) package_name = Utils.basename( filename ) result = PythonPackage( name = package_name, package = package, source_ref = source_ref ) else: sys.stderr.write( "%s: can't open file '%s'.\n" % ( Utils.basename( sys.argv[0] ), filename ) ) sys.exit( 2 ) if not Options.shallHaveStatementLines(): source_ref = source_ref.atInternal() source_code = readSourceCodeFromFilename( source_filename ) module_body = buildParseTree( provider = result, source_code = source_code, source_ref = source_ref, is_module = True ) result.setBody( module_body ) addImportedModule( Utils.relpath( filename ), result ) completeVariableClosures( result ) return result
def _detectBinaryPathDLLsWindows(binary_filename, package_name): result = set() depends_exe = getDependsExePath() # The search order by default prefers the system directory, where a # wrong "PythonXX.dll" might be living. with open(binary_filename + ".dwp", 'w') as dwp_file: dwp_file.write("""\ KnownDLLs SysPath AppDir 32BitSysDir 16BitSysDir OSDir AppPath SxS """) subprocess.call( (depends_exe, "-c", "-ot%s" % binary_filename + ".depends", "-d:%s" % binary_filename + ".dwp", "-f1", "-pa1", "-ps1", binary_filename), env=_makeBinaryPathPathDLLSearchEnv(package_name), ) inside = False for line in open(binary_filename + ".depends"): if "| Module Dependency Tree |" in line: inside = True continue if not inside: continue if "| Module List |" in line: break if ']' not in line: continue # Skip missing DLLs, apparently not needed anyway. if '?' in line[:line.find(']')]: continue dll_filename = line[line.find(']') + 2:-1] assert Utils.isFile(dll_filename), dll_filename # The executable itself is of course exempted. if Utils.normcase(dll_filename) == \ Utils.normcase(Utils.abspath(binary_filename)): continue dll_name = Utils.basename(dll_filename).upper() # Win API can be assumed. if dll_name.startswith("API-MS-WIN-") or \ dll_name.startswith("EXT-MS-WIN-"): continue if dll_name in ( "SHELL32.DLL", "USER32.DLL", "KERNEL32.DLL", "NTDLL.DLL", "NETUTILS.DLL", "LOGONCLI.DLL", "GDI32.DLL", "RPCRT4.DLL", "ADVAPI32.DLL", "SSPICLI.DLL", "SECUR32.DLL", "KERNELBASE.DLL", "WINBRAND.DLL", "DSROLE.DLL", "DNSAPI.DLL", "SAMCLI.DLL", "WKSCLI.DLL", "SAMLIB.DLL", "WLDAP32.DLL", "NTDSAPI.DLL", "CRYPTBASE.DLL", "W32TOPL", "WS2_32.DLL", "SPPC.DLL", "MSSIGN32.DLL", "CERTCLI.DLL", "WEBSERVICES.DLL", "AUTHZ.DLL", "CERTENROLL.DLL", "VAULTCLI.DLL", "REGAPI.DLL", "BROWCLI.DLL", "WINNSI.DLL", "DHCPCSVC6.DLL", "PCWUM.DLL", "CLBCATQ.DLL", "IMAGEHLP.DLL", "MSASN1.DLL", "DBGHELP.DLL", "DEVOBJ.DLL", "DRVSTORE.DLL", "CABINET.DLL", "SCECLI.DLL", "SPINF.DLL", "SPFILEQ.DLL", "GPAPI.DLL", "NETJOIN.DLL", "W32TOPL.DLL", "NETBIOS.DLL", "DXGI.DLL", "DWRITE.DLL", "D3D11.DLL", "WLANAPI.DLL", "WLANUTIL.DLL", "ONEX.DLL", "EAPPPRXY.DLL", "MFPLAT.DLL", "AVRT.DLL", "ELSCORE.DLL", "INETCOMM.DLL", "MSOERT2.DLL", "IEUI.DLL", "MSCTF.DLL", "MSFEEDS.DLL", "UIAUTOMATIONCORE.DLL", "PSAPI.DLL", "EFSADU.DLL", "MFC42U.DLL", "ODBC32.DLL", "OLEDLG.DLL", "NETAPI32.DLL", "LINKINFO.DLL", "DUI70.DLL", "ADVPACK.DLL", "NTSHRUI.DLL", "WINSPOOL.DRV", "EFSUTIL.DLL", "WINSCARD.DLL", "SHDOCVW.DLL", "IEFRAME.DLL", "D2D1.DLL", "GDIPLUS.DLL", "OCCACHE.DLL", "IEADVPACK.DLL", "MLANG.DLL", "MSI.DLL", "MSHTML.DLL", "COMDLG32.DLL", "PRINTUI.DLL", "PUIAPI.DLL", "ACLUI.DLL", "WTSAPI32.DLL", "FMS.DLL", "DFSCLI.DLL", "HLINK.DLL", "MSRATING.DLL", "PRNTVPT.DLL", "IMGUTIL.DLL", "MSLS31.DLL", "VERSION.DLL", "NORMALIZ.DLL", "IERTUTIL.DLL", "WININET.DLL", "WINTRUST.DLL", "XMLLITE.DLL", "APPHELP.DLL", "PROPSYS.DLL", "RSTRTMGR.DLL", "NCRYPT.DLL", "BCRYPT.DLL", "MMDEVAPI.DLL", "MSILTCFG.DLL", "DEVMGR.DLL", "DEVRTL.DLL", "NEWDEV.DLL", "VPNIKEAPI.DLL", "WINHTTP.DLL", "WEBIO.DLL", "NSI.DLL", "DHCPCSVC.DLL", "CRYPTUI.DLL", "ESENT.DLL", "DAVHLPR.DLL", "CSCAPI.DLL", "ATL.DLL", "OLEAUT32.DLL", "SRVCLI.DLL", "RASDLG.DLL", "MPRAPI.DLL", "RTUTILS.DLL", "RASMAN.DLL", "MPRMSG.DLL", "SLC.DLL", "CRYPTSP.DLL", "RASAPI32.DLL", "TAPI32.DLL", "EAPPCFG.DLL", "NDFAPI.DLL", "WDI.DLL", "COMCTL32.DLL", "UXTHEME.DLL", "IMM32.DLL", "OLEACC.DLL", "WINMM.DLL", "WINDOWSCODECS.DLL", "DWMAPI.DLL", "DUSER.DLL", "PROFAPI.DLL", "URLMON.DLL", "SHLWAPI.DLL", "LPK.DLL", "USP10.DLL", "CFGMGR32.DLL", "MSIMG32.DLL", "POWRPROF.DLL", "SETUPAPI.DLL", "WINSTA.DLL", "CRYPT32.DLL", "IPHLPAPI.DLL", "MPR.DLL", "CREDUI.DLL", "NETPLWIZ.DLL", "OLE32.DLL", "ACTIVEDS.DLL", "ADSLDPC.DLL", "USERENV.DLL", "APPREPAPI.DLL", "BCP47LANGS.DLL", "BCRYPTPRIMITIVES.DLL", "CERTCA.DLL", "CHARTV.DLL", "COMBASE.DLL", "DCOMP.DLL", "DPAPI.DLL", "DSPARSE.DLL", "FECLIENT.DLL", "FIREWALLAPI.DLL", "FLTLIB.DLL", "MRMCORER.DLL", "MSVCRT.DLL", "NINPUT.DLL", "NTASN1.DLL", "PCACLI.DLL", "RTWORKQ.DLL", "SECHOST.DLL", "SETTINGSYNCPOLICY.DLL", "SHCORE.DLL", "TBS.DLL", "TWINAPI.DLL", "TWINAPI.APPCORE.DLL", "VIRTDISK.DLL", "WEBSOCKET.DLL", "WEVTAPI.DLL", "WINMMBASE.DLL", "WMICLNT.DLL"): continue result.add(Utils.normcase(Utils.abspath(dll_filename))) Utils.deleteFile(binary_filename + ".depends", must_exist=True) Utils.deleteFile(binary_filename + ".dwp", must_exist=True) return result
def _consider(self, constraint_collection, module_filename, module_package): assert module_package is None or \ (type(module_package) is str and module_package != "") module_filename = Utils.normpath(module_filename) if Utils.isDir(module_filename): module_name = Utils.basename(module_filename) module_kind = "py" elif module_filename.endswith(".py"): module_name = Utils.basename(module_filename)[:-3] module_kind = "py" elif module_filename.endswith(".so"): module_kind = "shlib" module_name = Utils.basename(module_filename)[:-3] elif module_filename.endswith(".pyd"): module_kind = "shlib" module_name = Utils.basename(module_filename)[:-4] else: module_kind = None module_name = None if module_kind is not None: from nuitka.tree import Recursion decision, reason = Recursion.decideRecursion( module_filename=module_filename, module_name=module_name, module_package=module_package, module_kind=module_kind) if decision: module_relpath = Utils.relpath(module_filename) imported_module, added_flag = Recursion.recurseTo( module_package=module_package, module_filename=module_filename, module_relpath=module_relpath, module_kind=module_kind, reason=reason) if added_flag: constraint_collection.signalChange( "new_code", imported_module.getSourceReference(), "Recursed to module.") return imported_module elif decision is None and module_kind == "py": if module_package is None: module_fullpath = module_name else: module_fullpath = module_package + "." + module_name if module_filename not in self._warned_about: self._warned_about.add(module_filename) warning("""\ Not recursing to '%(full_path)s' (%(filename)s), please specify \ --recurse-none (do not warn), \ --recurse-all (recurse to all), \ --recurse-not-to=%(full_path)s (ignore it), \ --recurse-to=%(full_path)s (recurse to it) to change.""" % { "full_path": module_fullpath, "filename": module_filename })
def copyUsedDLLs(dist_dir, binary_filename, standalone_entry_points): # This is terribly complex, because we check the list of used DLLs # trying to avoid duplicates, and detecting errors with them not # being binary identical, so we can report them. And then of course # we also need to handle OS specifics, pylint: disable=R0912,R0914 dll_map = [] used_dlls = detectUsedDLLs(standalone_entry_points) for dll_filename1, sources1 in tuple(iterItems(used_dlls)): for dll_filename2, sources2 in tuple(iterItems(used_dlls)): if dll_filename1 == dll_filename2: continue # Colliding basenames are an issue to us. if Utils.basename(dll_filename1) != Utils.basename(dll_filename2): continue # May already have been removed earlier if dll_filename1 not in used_dlls: continue if dll_filename2 not in used_dlls: continue dll_name = Utils.basename(dll_filename1) if Options.isShowInclusion(): info("""Colliding DLL names for %s, checking identity of \ '%s' <-> '%s'.""" % ( dll_name, dll_filename1, dll_filename2, )) # Check that if a DLL has the same name, if it's identical, # happens at least for OSC and Fedora 20. import filecmp if filecmp.cmp(dll_filename1, dll_filename2): del used_dlls[dll_filename2] continue sys.exit("""Error, conflicting DLLs for '%s' \ (%s used by %s different from %s used by %s).""" % (dll_name, dll_filename1, ", ".join(sources1), dll_filename2, ", ".join(sources2))) for dll_filename, sources in iterItems(used_dlls): dll_name = Utils.basename(dll_filename) target_path = Utils.joinpath(dist_dir, dll_name) shutil.copy(dll_filename, target_path) dll_map.append((dll_filename, dll_name)) if Options.isShowInclusion(): info("Included used shared library '%s' (used by %s)." % (dll_filename, ", ".join(sources))) if Utils.getOS() == "Darwin": # For MacOS, the binary needs to be changed to reflect the DLL # location in the dist folder. fixupBinaryDLLPaths(binary_filename, dll_map) if Utils.getOS() == "Linux": # For Linux, the rpath of libraries may be an issue. for _original_path, dll_filename in dll_map: removeSharedLibraryRPATH(Utils.joinpath(dist_dir, dll_filename)) for standalone_entry_point in standalone_entry_points[1:]: removeSharedLibraryRPATH(standalone_entry_point[0])
def copyUsedDLLs(dist_dir, binary_filename, standalone_entry_points): # This is terribly complex, because we check the list of used DLLs # trying to avoid duplicates, and detecting errors with them not # being binary identical, so we can report them. And then of course # we also need to handle OS specifics, pylint: disable=R0912,R0914 dll_map = [] used_dlls = detectUsedDLLs(standalone_entry_points) for dll_filename1, sources1 in tuple(iterItems(used_dlls)): for dll_filename2, sources2 in tuple(iterItems(used_dlls)): if dll_filename1 == dll_filename2: continue # Colliding basenames are an issue to us. if Utils.basename(dll_filename1) != Utils.basename(dll_filename2): continue # May already have been removed earlier if dll_filename1 not in used_dlls: continue if dll_filename2 not in used_dlls: continue dll_name = Utils.basename(dll_filename1) if Options.isShowInclusion(): info( """Colliding DLL names for %s, checking identity of \ '%s' <-> '%s'.""" % ( dll_name, dll_filename1, dll_filename2, ) ) # Check that if a DLL has the same name, if it's identical, # happens at least for OSC and Fedora 20. import filecmp if filecmp.cmp(dll_filename1, dll_filename2): del used_dlls[dll_filename2] continue sys.exit( """Error, conflicting DLLs for '%s' \ (%s used by %s different from %s used by %s).""" % ( dll_name, dll_filename1, ", ".join(sources1), dll_filename2, ", ".join(sources2) ) ) for dll_filename, sources in iterItems(used_dlls): dll_name = Utils.basename(dll_filename) target_path = Utils.joinpath( dist_dir, dll_name ) shutil.copy( dll_filename, target_path ) dll_map.append( (dll_filename, dll_name) ) if Options.isShowInclusion(): info( "Included used shared library '%s' (used by %s)." % ( dll_filename, ", ".join(sources) ) ) if Utils.getOS() == "Darwin": # For MacOS, the binary needs to be changed to reflect the DLL # location in the dist folder. fixupBinaryDLLPaths(binary_filename, dll_map) if Utils.getOS() == "Linux": # For Linux, the rpath of libraries may be an issue. for _original_path, dll_filename in dll_map: removeSharedLibraryRPATH( Utils.joinpath(dist_dir, dll_filename) ) for standalone_entry_point in standalone_entry_points[1:]: removeSharedLibraryRPATH( standalone_entry_point[0] )
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 = Utils.joinpath(os.environ["APPDATA"], "nuitka") if not Utils.isDir(nuitka_app_dir): Utils.makePath(nuitka_app_dir) nuitka_depends_zip = Utils.joinpath(nuitka_app_dir, Utils.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 = Utils.joinpath(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 detectBinaryDLLs(binary_filename, package_name): result = set() if Utils.getOS() in ("Linux", "NetBSD"): # Ask "ldd" about the libraries being used by the created binary, these # are the ones that interest us. process = subprocess.Popen( args = [ "ldd", binary_filename ], stdout = subprocess.PIPE, stderr = subprocess.PIPE ) stdout, _stderr = process.communicate() for line in stdout.split(b"\n"): if not line: continue if b"=>" not in line: continue part = line.split(b" => ", 2)[1] if b"(" in part: filename = part[:part.rfind(b"(")-1] else: filename = part if not filename: continue if Utils.python_version >= 300: filename = filename.decode("utf-8") result.add(filename) elif Utils.getOS() == "Windows": depends_exe = getDependsExePath() env = os.environ.copy() path = env.get("PATH","").split(";") path += sys.path if package_name is not None: for element in sys.path: candidate = Utils.joinpath(element, package_name) if Utils.isDir(candidate): path.append(candidate) env["PATH"] = ";".join(path) subprocess.call( ( depends_exe, "-c", "-ot%s" % binary_filename + ".depends", "-f1", "-pa1", "-ps1", binary_filename ), env = env, ) inside = False for line in open(binary_filename + ".depends"): if "| Module Dependency Tree |" in line: inside = True continue if not inside: continue if "| Module List |" in line: break if "]" not in line: continue # Skip missing DLLs, apparently not needed anyway. if "?" in line[:line.find("]")]: continue dll_filename = line[line.find("]")+2:-1] assert Utils.isFile(dll_filename), dll_filename # The executable itself is of course excempted. if Utils.normcase(dll_filename) == \ Utils.normcase(Utils.abspath(binary_filename)): continue dll_name = Utils.basename(dll_filename).upper() # Win API can be assumed. if dll_name.startswith("API-MS-WIN-") or dll_name.startswith("EXT-MS-WIN-"): continue if dll_name in ("SHELL32.DLL", "USER32.DLL", "KERNEL32.DLL", "NTDLL.DLL", "NETUTILS.DLL", "LOGONCLI.DLL", "GDI32.DLL", "RPCRT4.DLL", "ADVAPI32.DLL", "SSPICLI.DLL", "SECUR32.DLL", "KERNELBASE.DLL", "WINBRAND.DLL", "DSROLE.DLL", "DNSAPI.DLL", "SAMCLI.DLL", "WKSCLI.DLL", "SAMLIB.DLL", "WLDAP32.DLL", "NTDSAPI.DLL", "CRYPTBASE.DLL", "W32TOPL", "WS2_32.DLL", "SPPC.DLL", "MSSIGN32.DLL", "CERTCLI.DLL", "WEBSERVICES.DLL", "AUTHZ.DLL", "CERTENROLL.DLL", "VAULTCLI.DLL", "REGAPI.DLL", "BROWCLI.DLL", "WINNSI.DLL", "DHCPCSVC6.DLL", "PCWUM.DLL", "CLBCATQ.DLL", "IMAGEHLP.DLL", "MSASN1.DLL", "DBGHELP.DLL", "DEVOBJ.DLL", "DRVSTORE.DLL", "CABINET.DLL", "SCECLI.DLL", "SPINF.DLL", "SPFILEQ.DLL", "GPAPI.DLL", "NETJOIN.DLL", "W32TOPL.DLL", "NETBIOS.DLL", "DXGI.DLL", "DWRITE.DLL", "D3D11.DLL", "WLANAPI.DLL", "WLANUTIL.DLL", "ONEX.DLL", "EAPPPRXY.DLL", "MFPLAT.DLL", "AVRT.DLL", "ELSCORE.DLL", "INETCOMM.DLL", "MSOERT2.DLL", "IEUI.DLL", "MSCTF.DLL", "MSFEEDS.DLL", "UIAUTOMATIONCORE.DLL", "PSAPI.DLL", "EFSADU.DLL", "MFC42U.DLL", "ODBC32.DLL", "OLEDLG.DLL", "NETAPI32.DLL", "LINKINFO.DLL", "DUI70.DLL", "ADVPACK.DLL", "NTSHRUI.DLL", "WINSPOOL.DRV", "EFSUTIL.DLL", "WINSCARD.DLL", "SHDOCVW.DLL", "IEFRAME.DLL", "D2D1.DLL", "GDIPLUS.DLL", "OCCACHE.DLL", "IEADVPACK.DLL", "MLANG.DLL", "MSI.DLL", "MSHTML.DLL", "COMDLG32.DLL", "PRINTUI.DLL", "PUIAPI.DLL", "ACLUI.DLL", "WTSAPI32.DLL", "FMS.DLL", "DFSCLI.DLL", "HLINK.DLL", "MSRATING.DLL", "PRNTVPT.DLL", "IMGUTIL.DLL", "MSLS31.DLL", "VERSION.DLL", "NORMALIZ.DLL", "IERTUTIL.DLL", "WININET.DLL", "WINTRUST.DLL", "XMLLITE.DLL", "APPHELP.DLL", "PROPSYS.DLL", "RSTRTMGR.DLL", "NCRYPT.DLL", "BCRYPT.DLL", "MMDEVAPI.DLL", "MSILTCFG.DLL", "DEVMGR.DLL", "DEVRTL.DLL", "NEWDEV.DLL", "VPNIKEAPI.DLL", "WINHTTP.DLL", "WEBIO.DLL", "NSI.DLL", "DHCPCSVC.DLL", "CRYPTUI.DLL", "ESENT.DLL", "DAVHLPR.DLL", "CSCAPI.DLL", "ATL.DLL", "OLEAUT32.DLL", "SRVCLI.DLL", "RASDLG.DLL", "MPRAPI.DLL", "RTUTILS.DLL", "RASMAN.DLL", "MPRMSG.DLL", "SLC.DLL", "CRYPTSP.DLL", "RASAPI32.DLL", "TAPI32.DLL", "EAPPCFG.DLL", "NDFAPI.DLL", "WDI.DLL", "COMCTL32.DLL", "UXTHEME.DLL", "IMM32.DLL", "OLEACC.DLL", "WINMM.DLL", "WINDOWSCODECS.DLL", "DWMAPI.DLL", "DUSER.DLL", "PROFAPI.DLL", "URLMON.DLL", "SHLWAPI.DLL", "LPK.DLL", "USP10.DLL", "CFGMGR32.DLL", "MSIMG32.DLL", "POWRPROF.DLL", "SETUPAPI.DLL", "WINSTA.DLL", "CRYPT32.DLL", "IPHLPAPI.DLL", "MPR.DLL", "CREDUI.DLL", "NETPLWIZ.DLL", "OLE32.DLL", "ACTIVEDS.DLL", "ADSLDPC.DLL", "USERENV.DLL", "APPREPAPI.DLL", "BCP47LANGS.DLL", "BCRYPTPRIMITIVES.DLL", "CERTCA.DLL", "CHARTV.DLL", "COMBASE.DLL", "DCOMP.DLL", "DPAPI.DLL", "DSPARSE.DLL", "FECLIENT.DLL", "FIREWALLAPI.DLL", "FLTLIB.DLL", "MRMCORER.DLL", "MSVCRT.DLL", "NINPUT.DLL", "NTASN1.DLL", "PCACLI.DLL", "RTWORKQ.DLL", "SECHOST.DLL", "SETTINGSYNCPOLICY.DLL", "SHCORE.DLL", "TBS.DLL", "TWINAPI.DLL", "TWINAPI.APPCORE.DLL", "VIRTDISK.DLL", "WEBSOCKET.DLL", "WEVTAPI.DLL", "WINMMBASE.DLL", "WMICLNT.DLL"): continue result.add(dll_filename) os.unlink(binary_filename + ".depends") else: # Support your platform above. assert False, Utils.getOS() return result
def buildModuleTree(filename, package, is_top, is_main): # Many variables, branches, due to the many cases, pylint: disable=R0912 assert package is None or type(package) is str if is_main and Utils.isDir(filename): source_filename = Utils.joinpath(filename, "__main__.py") if not Utils.isFile(source_filename): sys.stderr.write("%s: can't find '__main__' module in '%s'\n" % (Utils.basename(sys.argv[0]), filename)) sys.exit(2) filename = source_filename main_added = True else: main_added = False if Utils.isFile(filename): source_filename = filename source_ref = SourceCodeReferences.fromFilename( filename=filename, future_spec=FutureSpec()) if is_main: module_name = "__main__" else: module_name = Utils.basename(filename) if module_name.endswith(".py"): module_name = module_name[:-3] if "." in module_name: sys.stderr.write( "Error, '%s' is not a proper python module name.\n" % (module_name)) sys.exit(2) if is_main: result = PythonMainModule(source_ref=source_ref, main_added=main_added) else: result = PythonModule(name=module_name, package=package, source_ref=source_ref) elif Utils.isDir(filename) and Utils.isFile( Utils.joinpath(filename, "__init__.py")): source_filename = Utils.joinpath(filename, "__init__.py") if is_top: source_ref = SourceCodeReferences.fromFilename( filename=Utils.abspath(source_filename), future_spec=FutureSpec()) package_name = Utils.splitpath(filename)[-1] else: source_ref = SourceCodeReferences.fromFilename( filename=Utils.abspath(source_filename), future_spec=FutureSpec()) package_name = Utils.basename(filename) result = PythonPackage(name=package_name, package=package, source_ref=source_ref) else: sys.stderr.write("%s: can't open file '%s'.\n" % (Utils.basename(sys.argv[0]), filename)) sys.exit(2) if not Options.shallHaveStatementLines(): source_ref = source_ref.atInternal() source_code = readSourceCodeFromFilename(source_filename) buildParseTree(provider=result, source_code=source_code, source_ref=source_ref) addImportedModule(Utils.relpath(filename), result) completeVariableClosures(result) return result
def __init__(self, name, package_name, source_ref): NodeBase.__init__(self, source_ref=source_ref) PythonModuleMixin.__init__(self, name=name, package_name=package_name) assert Utils.basename(source_ref.getFilename()) != "<frozen>"
def detectBinaryDLLs(binary_filename, package_name): """ Detect the DLLs used by a binary. Using ldd (Linux), depends.exe (Windows), or otool (MacOS) the list of used DLLs is retrieved. """ result = set() if Utils.getOS() in ("Linux", "NetBSD"): # Ask "ldd" about the libraries being used by the created binary, these # are the ones that interest us. process = subprocess.Popen(args=["ldd", binary_filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, _stderr = process.communicate() for line in stdout.split(b"\n"): if not line: continue if b"=>" not in line: continue part = line.split(b" => ", 2)[1] if b"(" in part: filename = part[:part.rfind(b"(") - 1] else: filename = part if not filename: continue if Utils.python_version >= 300: filename = filename.decode("utf-8") result.add(filename) elif Utils.getOS() == "Windows": depends_exe = getDependsExePath() # Put the PYTHONPATH into the system PATH, DLLs frequently live in # the package directories. env = os.environ.copy() path = env.get("PATH", "").split(";") path += sys.path if package_name is not None: for element in sys.path: candidate = Utils.joinpath(element, package_name) if Utils.isDir(candidate): path.append(candidate) env["PATH"] = ";".join(path) subprocess.call( (depends_exe, "-c", "-ot%s" % binary_filename + ".depends", "-f1", "-pa1", "-ps1", binary_filename), env=env, ) inside = False for line in open(binary_filename + ".depends"): if "| Module Dependency Tree |" in line: inside = True continue if not inside: continue if "| Module List |" in line: break if "]" not in line: continue # Skip missing DLLs, apparently not needed anyway. if "?" in line[:line.find("]")]: continue dll_filename = line[line.find("]") + 2:-1] assert Utils.isFile(dll_filename), dll_filename # The executable itself is of course exempted. if Utils.normcase(dll_filename) == \ Utils.normcase(Utils.abspath(binary_filename)): continue dll_name = Utils.basename(dll_filename).upper() # Win API can be assumed. if dll_name.startswith("API-MS-WIN-") or \ dll_name.startswith("EXT-MS-WIN-"): continue if dll_name in ( "SHELL32.DLL", "USER32.DLL", "KERNEL32.DLL", "NTDLL.DLL", "NETUTILS.DLL", "LOGONCLI.DLL", "GDI32.DLL", "RPCRT4.DLL", "ADVAPI32.DLL", "SSPICLI.DLL", "SECUR32.DLL", "KERNELBASE.DLL", "WINBRAND.DLL", "DSROLE.DLL", "DNSAPI.DLL", "SAMCLI.DLL", "WKSCLI.DLL", "SAMLIB.DLL", "WLDAP32.DLL", "NTDSAPI.DLL", "CRYPTBASE.DLL", "W32TOPL", "WS2_32.DLL", "SPPC.DLL", "MSSIGN32.DLL", "CERTCLI.DLL", "WEBSERVICES.DLL", "AUTHZ.DLL", "CERTENROLL.DLL", "VAULTCLI.DLL", "REGAPI.DLL", "BROWCLI.DLL", "WINNSI.DLL", "DHCPCSVC6.DLL", "PCWUM.DLL", "CLBCATQ.DLL", "IMAGEHLP.DLL", "MSASN1.DLL", "DBGHELP.DLL", "DEVOBJ.DLL", "DRVSTORE.DLL", "CABINET.DLL", "SCECLI.DLL", "SPINF.DLL", "SPFILEQ.DLL", "GPAPI.DLL", "NETJOIN.DLL", "W32TOPL.DLL", "NETBIOS.DLL", "DXGI.DLL", "DWRITE.DLL", "D3D11.DLL", "WLANAPI.DLL", "WLANUTIL.DLL", "ONEX.DLL", "EAPPPRXY.DLL", "MFPLAT.DLL", "AVRT.DLL", "ELSCORE.DLL", "INETCOMM.DLL", "MSOERT2.DLL", "IEUI.DLL", "MSCTF.DLL", "MSFEEDS.DLL", "UIAUTOMATIONCORE.DLL", "PSAPI.DLL", "EFSADU.DLL", "MFC42U.DLL", "ODBC32.DLL", "OLEDLG.DLL", "NETAPI32.DLL", "LINKINFO.DLL", "DUI70.DLL", "ADVPACK.DLL", "NTSHRUI.DLL", "WINSPOOL.DRV", "EFSUTIL.DLL", "WINSCARD.DLL", "SHDOCVW.DLL", "IEFRAME.DLL", "D2D1.DLL", "GDIPLUS.DLL", "OCCACHE.DLL", "IEADVPACK.DLL", "MLANG.DLL", "MSI.DLL", "MSHTML.DLL", "COMDLG32.DLL", "PRINTUI.DLL", "PUIAPI.DLL", "ACLUI.DLL", "WTSAPI32.DLL", "FMS.DLL", "DFSCLI.DLL", "HLINK.DLL", "MSRATING.DLL", "PRNTVPT.DLL", "IMGUTIL.DLL", "MSLS31.DLL", "VERSION.DLL", "NORMALIZ.DLL", "IERTUTIL.DLL", "WININET.DLL", "WINTRUST.DLL", "XMLLITE.DLL", "APPHELP.DLL", "PROPSYS.DLL", "RSTRTMGR.DLL", "NCRYPT.DLL", "BCRYPT.DLL", "MMDEVAPI.DLL", "MSILTCFG.DLL", "DEVMGR.DLL", "DEVRTL.DLL", "NEWDEV.DLL", "VPNIKEAPI.DLL", "WINHTTP.DLL", "WEBIO.DLL", "NSI.DLL", "DHCPCSVC.DLL", "CRYPTUI.DLL", "ESENT.DLL", "DAVHLPR.DLL", "CSCAPI.DLL", "ATL.DLL", "OLEAUT32.DLL", "SRVCLI.DLL", "RASDLG.DLL", "MPRAPI.DLL", "RTUTILS.DLL", "RASMAN.DLL", "MPRMSG.DLL", "SLC.DLL", "CRYPTSP.DLL", "RASAPI32.DLL", "TAPI32.DLL", "EAPPCFG.DLL", "NDFAPI.DLL", "WDI.DLL", "COMCTL32.DLL", "UXTHEME.DLL", "IMM32.DLL", "OLEACC.DLL", "WINMM.DLL", "WINDOWSCODECS.DLL", "DWMAPI.DLL", "DUSER.DLL", "PROFAPI.DLL", "URLMON.DLL", "SHLWAPI.DLL", "LPK.DLL", "USP10.DLL", "CFGMGR32.DLL", "MSIMG32.DLL", "POWRPROF.DLL", "SETUPAPI.DLL", "WINSTA.DLL", "CRYPT32.DLL", "IPHLPAPI.DLL", "MPR.DLL", "CREDUI.DLL", "NETPLWIZ.DLL", "OLE32.DLL", "ACTIVEDS.DLL", "ADSLDPC.DLL", "USERENV.DLL", "APPREPAPI.DLL", "BCP47LANGS.DLL", "BCRYPTPRIMITIVES.DLL", "CERTCA.DLL", "CHARTV.DLL", "COMBASE.DLL", "DCOMP.DLL", "DPAPI.DLL", "DSPARSE.DLL", "FECLIENT.DLL", "FIREWALLAPI.DLL", "FLTLIB.DLL", "MRMCORER.DLL", "MSVCRT.DLL", "NINPUT.DLL", "NTASN1.DLL", "PCACLI.DLL", "RTWORKQ.DLL", "SECHOST.DLL", "SETTINGSYNCPOLICY.DLL", "SHCORE.DLL", "TBS.DLL", "TWINAPI.DLL", "TWINAPI.APPCORE.DLL", "VIRTDISK.DLL", "WEBSOCKET.DLL", "WEVTAPI.DLL", "WINMMBASE.DLL", "WMICLNT.DLL"): continue result.add(Utils.normcase(Utils.abspath(dll_filename))) os.unlink(binary_filename + ".depends") elif Utils.getOS() == "Darwin": # print "Darwin", binary_filename process = subprocess.Popen(args=["otool", "-L", binary_filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, _stderr = process.communicate() sysstops = [b"/usr/lib/", b"/System/Library/Frameworks/"] for line in stdout.split(b"\n"): if not line: continue if line.startswith(b"\t"): filename = line.split(b" (")[0].strip() stop = False for w in sysstops: if filename.startswith(w): stop = True break if not stop: if Utils.python_version >= 300: filename = filename.decode("utf-8") # print "adding", filename result.add(filename) else: # Support your platform above. assert False, Utils.getOS() return result
def decideModuleTree(filename, package, is_shlib, is_top, is_main): # Many variables, branches, due to the many cases, pylint: disable=R0912 assert package is None or type( package ) is str if is_main and Utils.isDir( filename ): source_filename = Utils.joinpath( filename, "__main__.py" ) if not Utils.isFile( source_filename ): sys.stderr.write( "%s: can't find '__main__' module in '%s'\n" % ( Utils.basename( sys.argv[0] ), filename ) ) sys.exit( 2 ) filename = source_filename main_added = True else: main_added = False if Utils.isFile( filename ): source_filename = filename source_ref = SourceCodeReferences.fromFilename( filename = filename, future_spec = FutureSpec() ) if is_main: module_name = "__main__" else: module_name = Utils.basename( filename ) if module_name.endswith( ".py" ): module_name = module_name[:-3] if is_shlib: module_name = module_name.split(".")[0] if "." in module_name: sys.stderr.write( "Error, '%s' is not a proper python module name.\n" % ( module_name ) ) sys.exit( 2 ) if is_shlib: result = PythonShlibModule( name = module_name, source_ref = source_ref, package_name = package, ) elif is_main: result = PythonMainModule( source_ref = source_ref, main_added = main_added ) else: result = PythonModule( name = module_name, package_name = package, source_ref = source_ref ) elif Importing.isPackageDir(filename): if is_top: package_name = Utils.splitpath(filename)[-1] else: package_name = Utils.basename(filename) source_filename = Utils.joinpath(filename, "__init__.py") if not Utils.isFile( source_filename ): assert Utils.python_version >= 330, source_filename source_ref, result = createNamespacePackage( package_name = package_name, module_relpath = filename ) source_filename = None else: source_ref = SourceCodeReferences.fromFilename( filename = Utils.abspath( source_filename ), future_spec = FutureSpec() ) result = PythonPackage( name = package_name, package_name = package, source_ref = source_ref ) else: sys.stderr.write( "%s: can't open file '%s'.\n" % ( Utils.basename( sys.argv[0] ), filename ) ) sys.exit( 2 ) if not Options.shallHaveStatementLines(): source_ref = source_ref.atInternal() return result, source_ref, source_filename
def _detectBinaryPathDLLsWindows(binary_filename, package_name): result = set() depends_exe = getDependsExePath() # Put the PYTHONPATH into the system PATH, DLLs frequently live in # the package directories. env = os.environ.copy() path = env.get("PATH", "").split(";") path += sys.path if package_name is not None: for element in sys.path: candidate = Utils.joinpath(element, package_name) if Utils.isDir(candidate): path.append(candidate) env["PATH"] = ";".join(path) subprocess.call( (depends_exe, "-c", "-ot%s" % binary_filename + ".depends", "-f1", "-pa1", "-ps1", binary_filename), env=env, ) inside = False for line in open(binary_filename + ".depends"): if "| Module Dependency Tree |" in line: inside = True continue if not inside: continue if "| Module List |" in line: break if "]" not in line: continue # Skip missing DLLs, apparently not needed anyway. if "?" in line[:line.find("]")]: continue dll_filename = line[line.find("]") + 2:-1] assert Utils.isFile(dll_filename), dll_filename # The executable itself is of course exempted. if Utils.normcase(dll_filename) == \ Utils.normcase(Utils.abspath(binary_filename)): continue dll_name = Utils.basename(dll_filename).upper() # Win API can be assumed. if dll_name.startswith("API-MS-WIN-") or \ dll_name.startswith("EXT-MS-WIN-"): continue if dll_name in ( "SHELL32.DLL", "USER32.DLL", "KERNEL32.DLL", "NTDLL.DLL", "NETUTILS.DLL", "LOGONCLI.DLL", "GDI32.DLL", "RPCRT4.DLL", "ADVAPI32.DLL", "SSPICLI.DLL", "SECUR32.DLL", "KERNELBASE.DLL", "WINBRAND.DLL", "DSROLE.DLL", "DNSAPI.DLL", "SAMCLI.DLL", "WKSCLI.DLL", "SAMLIB.DLL", "WLDAP32.DLL", "NTDSAPI.DLL", "CRYPTBASE.DLL", "W32TOPL", "WS2_32.DLL", "SPPC.DLL", "MSSIGN32.DLL", "CERTCLI.DLL", "WEBSERVICES.DLL", "AUTHZ.DLL", "CERTENROLL.DLL", "VAULTCLI.DLL", "REGAPI.DLL", "BROWCLI.DLL", "WINNSI.DLL", "DHCPCSVC6.DLL", "PCWUM.DLL", "CLBCATQ.DLL", "IMAGEHLP.DLL", "MSASN1.DLL", "DBGHELP.DLL", "DEVOBJ.DLL", "DRVSTORE.DLL", "CABINET.DLL", "SCECLI.DLL", "SPINF.DLL", "SPFILEQ.DLL", "GPAPI.DLL", "NETJOIN.DLL", "W32TOPL.DLL", "NETBIOS.DLL", "DXGI.DLL", "DWRITE.DLL", "D3D11.DLL", "WLANAPI.DLL", "WLANUTIL.DLL", "ONEX.DLL", "EAPPPRXY.DLL", "MFPLAT.DLL", "AVRT.DLL", "ELSCORE.DLL", "INETCOMM.DLL", "MSOERT2.DLL", "IEUI.DLL", "MSCTF.DLL", "MSFEEDS.DLL", "UIAUTOMATIONCORE.DLL", "PSAPI.DLL", "EFSADU.DLL", "MFC42U.DLL", "ODBC32.DLL", "OLEDLG.DLL", "NETAPI32.DLL", "LINKINFO.DLL", "DUI70.DLL", "ADVPACK.DLL", "NTSHRUI.DLL", "WINSPOOL.DRV", "EFSUTIL.DLL", "WINSCARD.DLL", "SHDOCVW.DLL", "IEFRAME.DLL", "D2D1.DLL", "GDIPLUS.DLL", "OCCACHE.DLL", "IEADVPACK.DLL", "MLANG.DLL", "MSI.DLL", "MSHTML.DLL", "COMDLG32.DLL", "PRINTUI.DLL", "PUIAPI.DLL", "ACLUI.DLL", "WTSAPI32.DLL", "FMS.DLL", "DFSCLI.DLL", "HLINK.DLL", "MSRATING.DLL", "PRNTVPT.DLL", "IMGUTIL.DLL", "MSLS31.DLL", "VERSION.DLL", "NORMALIZ.DLL", "IERTUTIL.DLL", "WININET.DLL", "WINTRUST.DLL", "XMLLITE.DLL", "APPHELP.DLL", "PROPSYS.DLL", "RSTRTMGR.DLL", "NCRYPT.DLL", "BCRYPT.DLL", "MMDEVAPI.DLL", "MSILTCFG.DLL", "DEVMGR.DLL", "DEVRTL.DLL", "NEWDEV.DLL", "VPNIKEAPI.DLL", "WINHTTP.DLL", "WEBIO.DLL", "NSI.DLL", "DHCPCSVC.DLL", "CRYPTUI.DLL", "ESENT.DLL", "DAVHLPR.DLL", "CSCAPI.DLL", "ATL.DLL", "OLEAUT32.DLL", "SRVCLI.DLL", "RASDLG.DLL", "MPRAPI.DLL", "RTUTILS.DLL", "RASMAN.DLL", "MPRMSG.DLL", "SLC.DLL", "CRYPTSP.DLL", "RASAPI32.DLL", "TAPI32.DLL", "EAPPCFG.DLL", "NDFAPI.DLL", "WDI.DLL", "COMCTL32.DLL", "UXTHEME.DLL", "IMM32.DLL", "OLEACC.DLL", "WINMM.DLL", "WINDOWSCODECS.DLL", "DWMAPI.DLL", "DUSER.DLL", "PROFAPI.DLL", "URLMON.DLL", "SHLWAPI.DLL", "LPK.DLL", "USP10.DLL", "CFGMGR32.DLL", "MSIMG32.DLL", "POWRPROF.DLL", "SETUPAPI.DLL", "WINSTA.DLL", "CRYPT32.DLL", "IPHLPAPI.DLL", "MPR.DLL", "CREDUI.DLL", "NETPLWIZ.DLL", "OLE32.DLL", "ACTIVEDS.DLL", "ADSLDPC.DLL", "USERENV.DLL", "APPREPAPI.DLL", "BCP47LANGS.DLL", "BCRYPTPRIMITIVES.DLL", "CERTCA.DLL", "CHARTV.DLL", "COMBASE.DLL", "DCOMP.DLL", "DPAPI.DLL", "DSPARSE.DLL", "FECLIENT.DLL", "FIREWALLAPI.DLL", "FLTLIB.DLL", "MRMCORER.DLL", "MSVCRT.DLL", "NINPUT.DLL", "NTASN1.DLL", "PCACLI.DLL", "RTWORKQ.DLL", "SECHOST.DLL", "SETTINGSYNCPOLICY.DLL", "SHCORE.DLL", "TBS.DLL", "TWINAPI.DLL", "TWINAPI.APPCORE.DLL", "VIRTDISK.DLL", "WEBSOCKET.DLL", "WEVTAPI.DLL", "WINMMBASE.DLL", "WMICLNT.DLL"): continue result.add(Utils.normcase(Utils.abspath(dll_filename))) os.unlink(binary_filename + ".depends") return result
def decideModuleTree(filename, package, is_shlib, is_top, is_main): # Many variables, branches, due to the many cases, pylint: disable=R0912 assert package is None or type(package) is str if is_main and Utils.isDir(filename): source_filename = Utils.joinpath(filename, "__main__.py") if not Utils.isFile(source_filename): sys.stderr.write( "%s: can't find '__main__' module in '%s'\n" % ( Utils.basename(sys.argv[0]), filename ) ) sys.exit(2) filename = source_filename main_added = True else: main_added = False if Utils.isFile(filename): source_filename = filename source_ref = SourceCodeReferences.fromFilename( filename = filename, future_spec = FutureSpec() ) if is_main: module_name = "__main__" else: module_name = Utils.basename(filename) if module_name.endswith(".py"): module_name = module_name[:-3] if is_shlib: module_name = module_name.split('.')[0] if '.' in module_name: sys.stderr.write( "Error, '%s' is not a proper python module name.\n" % ( module_name ) ) sys.exit(2) if is_shlib: result = PythonShlibModule( name = module_name, source_ref = source_ref, package_name = package, ) elif is_main: result = PythonMainModule( source_ref = source_ref, main_added = main_added ) else: result = PythonModule( name = module_name, package_name = package, source_ref = source_ref ) elif Importing.isPackageDir(filename): if is_top: package_name = Utils.splitpath(filename)[-1] else: package_name = Utils.basename(filename) source_filename = Utils.joinpath(filename, "__init__.py") if not Utils.isFile(source_filename): assert Utils.python_version >= 330, source_filename source_ref, result = createNamespacePackage( package_name = package_name, module_relpath = filename ) source_filename = None else: source_ref = SourceCodeReferences.fromFilename( filename = Utils.abspath(source_filename), future_spec = FutureSpec() ) result = PythonPackage( name = package_name, package_name = package, source_ref = source_ref ) else: sys.stderr.write( "%s: can't open file '%s'.\n" % ( Utils.basename(sys.argv[0]), filename ) ) sys.exit(2) if not Options.shallHaveStatementLines(): source_ref = source_ref.atInternal() return result, source_ref, source_filename