Warning, /pim/trojita/packaging/mingw-bundledlls is written in an unsupported language. File is not indexed.
0001 #!/usr/bin/python3 0002 0003 # The MIT License (MIT) 0004 # 0005 # Copyright (c) 2015 Martin Preisler 0006 # 0007 # Permission is hereby granted, free of charge, to any person obtaining a copy 0008 # of this software and associated documentation files (the "Software"), to deal 0009 # in the Software without restriction, including without limitation the rights 0010 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 0011 # copies of the Software, and to permit persons to whom the Software is 0012 # furnished to do so, subject to the following conditions: 0013 # 0014 # The above copyright notice and this permission notice shall be included in all 0015 # copies or substantial portions of the Software. 0016 # 0017 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 0018 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 0019 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 0020 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 0021 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 0022 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 0023 # SOFTWARE. 0024 0025 0026 import subprocess 0027 import os.path 0028 import argparse 0029 import shutil 0030 0031 # The mingw path matches where Fedora 21 installs mingw32 0032 default_path_prefixes = [ 0033 "", "/usr/bin", "/usr/i686-w64-mingw32/sys-root/mingw/bin", "/mingw64/bin", 0034 ] 0035 0036 # This blacklist may need extending 0037 blacklist = [ 0038 "advapi32.dll", "kernel32.dll", "msvcrt.dll", "ole32.dll", "user32.dll", 0039 "ws2_32.dll", "comdlg32.dll", "gdi32.dll", "imm32.dll", "oleaut32.dll", 0040 "shell32.dll", "winmm.dll", "winspool.drv", "wldap32.dll", 0041 "ntdll.dll", "d3d9.dll", "mpr.dll", "crypt32.dll", "dnsapi.dll", 0042 "shlwapi.dll", "version.dll", "iphlpapi.dll", 0043 ] 0044 0045 0046 def find_full_path(filename, path_prefixes): 0047 path = None 0048 0049 for path_prefix in path_prefixes: 0050 path_candidate = os.path.join(path_prefix, filename) 0051 0052 if os.path.exists(path_candidate): 0053 path = path_candidate 0054 break 0055 0056 if path is None: 0057 raise RuntimeError( 0058 "Can't find " + filename + ". If it is an inbuilt Windows DLL, " 0059 "please add it to the blacklist variable in the script and send " 0060 "a pull request!" 0061 ) 0062 0063 return path 0064 0065 0066 def gather_deps(path, path_prefixes, seen): 0067 ret = [path] 0068 output = subprocess.check_output(["objdump", "-p", path]).decode('utf-8').split("\n") 0069 for line in output: 0070 if not line.startswith("\tDLL Name: "): 0071 continue 0072 0073 dep = line.split("DLL Name: ")[1].strip() 0074 ldep = dep.lower() 0075 0076 if ldep in blacklist: 0077 continue 0078 0079 if ldep in seen: 0080 continue 0081 0082 dep_path = find_full_path(dep, path_prefixes) 0083 seen.extend([ldep]) 0084 subdeps = gather_deps(dep_path, path_prefixes, seen) 0085 ret.extend(subdeps) 0086 0087 return ret 0088 0089 0090 def main(): 0091 parser = argparse.ArgumentParser() 0092 parser.add_argument( 0093 "exe_file", 0094 nargs='+', 0095 help="EXE or DLL file that you need to bundle dependencies for" 0096 ) 0097 parser.add_argument( 0098 "--copy", 0099 action="store_true", 0100 help="In addition to printing out the dependencies, also copy them next to the exe_file" 0101 ) 0102 parser.add_argument( 0103 "--upx", 0104 action="store_true", 0105 help="Only valid if --copy is provided. Run UPX on all the DLLs and EXE." 0106 ) 0107 args = parser.parse_args() 0108 0109 if args.upx and not args.copy: 0110 raise RuntimeError("Can't run UPX if --copy hasn't been provided.") 0111 0112 seen = [] 0113 all_deps = [] 0114 for exe in args.exe_file: 0115 all_deps.extend(set(gather_deps(exe, default_path_prefixes, seen))) 0116 for exe in args.exe_file: 0117 all_deps.remove(exe) 0118 0119 print("\n".join(all_deps)) 0120 0121 if args.copy: 0122 print("Copying enabled, will now copy all dependencies next to the exe_file.\n") 0123 0124 parent_dir = os.path.dirname(os.path.abspath(args.exe_file)) 0125 0126 for dep in all_deps: 0127 target = os.path.join(parent_dir, os.path.basename(dep)) 0128 print("Copying '%s' to '%s'" % (dep, target)) 0129 shutil.copy(dep, parent_dir) 0130 0131 if args.upx: 0132 subprocess.call(["upx", target]) 0133 0134 0135 if __name__ == "__main__": 0136 main()