this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at fixPythonPipStalling 303 lines 10 kB view raw
1#!/usr/bin/env python3 2 3import sys, os, subprocess, re, getpass, datetime 4 5# Data 6library = False 7iossupport_system = False 8framework = False 9private_framework = False 10 11# Constants 12library_prefix = "/usr/lib/" 13iossupport_system_prefix = "/System/iOSSupport" 14framework_prefix = "/System/Library/Frameworks/" 15private_framework_prefix = "/System/Library/PrivateFrameworks/" 16 17####################################################### 18##### SET THIS TO WHERE YOUR class-dump BINARY IS ##### 19####################################################### 20username = getpass.getuser() 21class_dump = "/Users/" + username + "/bin/class-dump" 22 23copyright_template = """/* 24 This file is part of Darling. 25 26 Copyright (C) {} Darling Developers 27 28 Darling is free software: you can redistribute it and/or modify 29 it under the terms of the GNU General Public License as published by 30 the Free Software Foundation, either version 3 of the License, or 31 (at your option) any later version. 32 33 Darling is distributed in the hope that it will be useful, 34 but WITHOUT ANY WARRANTY; without even the implied warranty of 35 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 36 GNU General Public License for more details. 37 38 You should have received a copy of the GNU General Public License 39 along with Darling. If not, see <http://www.gnu.org/licenses/>. 40*/ 41 42""" 43copyright = copyright_template.format(datetime.datetime.now(datetime.timezone.utc).year) 44 45c_func_impl_stub = """ 46void* %s(void) 47{ 48 if (verbose) puts("STUB: %s called"); 49 return NULL; 50} 51""" 52 53msg_handling = """- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector 54{ 55 return [NSMethodSignature signatureWithObjCTypes: \"v@:\"]; 56} 57 58- (void)forwardInvocation:(NSInvocation *)anInvocation 59{ 60 NSLog(@\"Stub called: %@ in %@\", NSStringFromSelector([anInvocation selector]), [self class]); 61} 62 63""" 64 65# Utility functions 66def usage(): 67 print("Usage: " + sys.argv[0] + " <Mach-O> <output directory>") 68 exit(1) 69 70 71def extract_library_name(name): 72 name = re.search("/lib([A-Za-z0-9]+)\.dylib$", name).group(1) 73 print(name) 74 return name 75 76def extract_framework_name(name): 77 return name[name.rfind("/") + 1:] 78 79def write_objc_source_file_locs(cmake_file, classes, num_spaces): 80 for cls in classes: 81 cmake_file.write(" " * num_spaces + "src/%s.m\n" % cls) 82 83 84# Main program start 85if len(sys.argv) != 3: 86 usage() 87 88full_path = sys.argv[1] 89output_dir = sys.argv[2] 90validate_path = full_path 91 92try: 93 os.makedirs(output_dir) 94except FileExistsError: 95 pass 96 97if full_path.startswith(iossupport_system_prefix): 98 iossupport_system = True 99 validate_path = full_path[len(iossupport_system_prefix):] 100 101if validate_path.endswith(".dylib"): 102 library = True 103 target_name = extract_library_name(validate_path) 104elif len(validate_path) > len(framework_prefix) and validate_path[:len(framework_prefix)] == framework_prefix: 105 framework = True 106 target_name = extract_framework_name(validate_path) 107elif len(validate_path) > len(private_framework_prefix) and validate_path[ 108 :len(private_framework_prefix)] == private_framework_prefix: 109 private_framework = True 110 target_name = extract_framework_name(validate_path) 111else: 112 print("Failed to recognize Mach-O location") 113 target_name = None 114 exit(1) 115 116header_dir = output_dir + "/include/" + target_name + "/" 117source_dir = output_dir + "/src/" 118 119try: 120 os.makedirs(header_dir) 121except FileExistsError: 122 pass 123 124try: 125 os.makedirs(source_dir) 126except FileExistsError: 127 pass 128 129# Get C functions 130 131c_func_out = subprocess.check_output(["nm", "-Ug", full_path]) 132c_func_out = c_func_out.decode('utf8').strip() 133 134functions = [] 135for line in c_func_out.splitlines(): 136 137 if line == "": 138 continue 139 140 print(line) 141 if len(line.split(" ")) == 3: 142 address, id, name = line.split(" ") 143 # Remove the underscore 144 name = name[1:] 145 146 if id == "T": 147 functions.append(name) 148 else: 149 print("Skipping c function output line") 150 151class_dump_output = subprocess.check_output([class_dump, full_path]).decode('utf8').strip() 152uses_objc = "This file does not contain any Objective-C runtime information." not in class_dump_output 153 154c_header = open(header_dir + target_name + ".h", "w") 155c_source = open(source_dir + target_name + ".m", "w") if uses_objc else open(source_dir + target_name + ".c", "w") 156 157c_header.write(copyright) 158c_source.write(copyright) 159 160c_source.write(""" 161#include <%s/%s.h> 162#include <stdlib.h> 163#include <stdio.h> 164 165static int verbose = 0; 166 167__attribute__((constructor)) 168static void initme(void) { 169 verbose = getenv("STUB_VERBOSE") != NULL; 170} 171""" % (target_name, target_name)) 172 173cmake = open(output_dir + "/CMakeLists.txt", "w") 174 175cmake.write("project(%s)\n\n" % target_name) 176 177# Get current and compat versions 178 179otool_out = subprocess.check_output(["otool", "-L", full_path]) 180otool_out = otool_out.decode('utf8').strip() 181version_line = otool_out.splitlines()[1] 182 183get_versions = re.compile("\\(compatibility version (.*?), current version (.*?)\\)") 184 185compat, current = get_versions.search(version_line).groups() 186 187if library: 188 cmake.write("set(DYLIB_INSTALL_NAME \"%s\")\n" % full_path) 189cmake.write("set(DYLIB_COMPAT_VERSION \"%s\")\n" % compat) 190cmake.write("set(DYLIB_CURRENT_VERSION \"%s\")\n" % current) 191cmake.write("set(FRAMEWORK_VERSION \"A\")\n\n") 192 193c_header.write("\n#ifndef _%s_H_\n#define _%s_H_\n\n" % (target_name, target_name)) 194 195if uses_objc: 196 c_header.write("#import <Foundation/Foundation.h>\n\n") 197 198 # typedef_void_regex = re.compile("(typedef void.+?;)", re.DOTALL | re.MULTILINE) 199 # for typedef_void_def in typedef_void_regex.finditer(class_dump_output): 200 # c_header.write(typedef_void_def.groups()[0]) 201 # c_header.write("\n\n") 202 # 203 # blacklisted_structs = ["_NSRange"] 204 # structs_regex = re.compile("(struct (.+?) {.+?};)", re.DOTALL | re.MULTILINE) 205 # for struct_def in structs_regex.finditer(class_dump_output): 206 # struct_contents, struct_name = struct_def.groups() 207 # if struct_name in blacklisted_structs: 208 # continue 209 # c_header.write(struct_contents) 210 # c_header.write("\n\n") 211 # 212 # typedef_struct_regex = re.compile("(typedef struct {.+?}.+?;)", re.DOTALL | re.MULTILINE) 213 # for typedef_struct_def in typedef_struct_regex.finditer(class_dump_output): 214 # c_header.write(typedef_struct_def.groups()[0]) 215 # c_header.write("\n\n") 216 217 classes = [] 218 219 protocols_regex = re.compile("(@protocol (.+?)[\n ].+?@end)", re.DOTALL | re.MULTILINE) 220 classes_regex = re.compile("(@interface (.+?) :.+?@end)", re.DOTALL | re.MULTILINE) 221 222 blacklisted_protocols = ["NSObject", "NSSecureCoding", "NSCoding", "NSCopying", "NSFastEnumeration", "NSMutableCopying", 223 "NSURLConnectionDataDelegate", "NSURLSessionTaskDelegate", "NSURLConnectionDelegate", "NSLocking" 224 ] 225 for protocol_def in protocols_regex.finditer(class_dump_output): 226 protocol_contents, protocol_name = protocol_def.groups() 227 if protocol_name in blacklisted_protocols: 228 continue 229 proto_header = open(header_dir + protocol_name + ".h", "w") 230 proto_header.write(copyright) 231 proto_header.write("#include <Foundation/Foundation.h>\n\n") 232 # proto_header.write(protocol_contents) 233 proto_header.write("@protocol %s\n\n@end\n" % protocol_name) 234 proto_header.close() 235 c_header.write("#import <%s/%s.h>\n" % (target_name, protocol_name)) 236 237 for class_def in classes_regex.finditer(class_dump_output): 238 class_contents, class_name = class_def.groups() 239 classes.append(class_name) 240 class_header = open(header_dir + class_name + ".h", "w") 241 class_header.write(copyright) 242 class_header.write("#include <Foundation/Foundation.h>\n\n") 243 # class_header.write(class_contents) 244 class_header.write("@interface %s : NSObject\n\n@end\n" % class_name) 245 class_header.close() 246 c_header.write("#import <%s/%s.h>\n" % (target_name, class_name)) 247 248 class_impl = open(source_dir + class_name + ".m", "w") 249 class_impl.write(copyright) 250 class_impl.write("#import <%s/%s.h>\n\n" % (target_name, class_name)) 251 class_impl.write("@implementation " + class_name + "\n\n") 252 class_impl.write(msg_handling) 253 class_impl.write("@end\n") 254 255 c_header.write("\n") 256 257for funcname in functions: 258 c_header.write("void* %s(void);\n" % funcname) 259 c_source.write(c_func_impl_stub % (funcname, funcname)) 260 261if library: 262 cmake.write("add_darling_library(%s SHARED\n" % target_name) 263 cmake.write(" src/%s." % target_name + ("m" if uses_objc else "c") + "\n") 264 if uses_objc: 265 write_objc_source_file_locs(cmake, classes, 4) 266 cmake.write(")\n") 267 cmake.write("make_fat(%s)\n" % target_name) 268 libraries = "system objc Foundation" if uses_objc else "system" 269 cmake.write("target_link_libraries(%s %s)\n" % (target_name, libraries)) 270 cmake.write("install(TARGETS %s DESTINATION libexec/darling/usr/lib)\n" % target_name) 271else: 272 cmake.write("remove_sdk_framework(%s\n" % target_name) 273 if private_framework: 274 cmake.write(" PRIVATE\n") 275 cmake.write(")\n\n") 276 cmake.write("generate_sdk_framework(%s\n" % target_name) 277 cmake.write(" VERSION ${FRAMEWORK_VERSION}\n") 278 cmake.write(" HEADER \"include/%s\"\n" % target_name) 279 if private_framework: 280 cmake.write(" PRIVATE\n") 281 cmake.write(")\n\n") 282 cmake.write("add_framework(%s\n" % target_name) 283 cmake.write(" FAT\n CURRENT_VERSION\n") 284 if iossupport_system: 285 cmake.write(" IOSSUPPORT\n") 286 if private_framework: 287 cmake.write(" PRIVATE\n") 288 cmake.write(" VERSION ${FRAMEWORK_VERSION}\n\n") 289 cmake.write(" SOURCES\n") 290 cmake.write(" src/%s." % target_name + ("m" if uses_objc else "c") + "\n") 291 if uses_objc: 292 write_objc_source_file_locs(cmake, classes, 8) 293 294 cmake.write("\n") 295 296 cmake.write(" DEPENDENCIES\n") 297 cmake.write(" system\n") 298 if uses_objc: 299 cmake.write(" objc\n") 300 cmake.write(" Foundation\n") 301 cmake.write(")\n") 302 303c_header.write("\n#endif\n")