1""" 2dyld emulation 3""" 4 5__all__ = [ 6 'dyld_framework', 'dyld_library', 'dyld_find', 'pathForFramework', 7 'infoForFramework', 8] 9 10import os, sys 11from objc._framework import infoForFramework 12 13 14# These are the defaults as per man dyld(1) 15# 16DEFAULT_FRAMEWORK_FALLBACK = ':'.join([ 17 os.path.expanduser("~/Library/Frameworks"), 18 "/Library/Frameworks", 19 "/Network/Library/Frameworks", 20 "/System/Library/Frameworks", 21]) 22 23DEFAULT_LIBRARY_FALLBACK = ':'.join([ 24 os.path.expanduser("~/lib"), 25 "/usr/local/lib", 26 "/lib", 27 "/usr/lib", 28]) 29 30def ensure_unicode(s): 31 """Not all of PyObjC understands unicode paths very well yet""" 32 if isinstance(s, bytes): 33 return s.decode('utf-8') 34 return s 35 36def inject_suffixes(iterator): 37 suffix = ensure_unicode(os.environ.get('DYLD_IMAGE_SUFFIX', None)) 38 if suffix is None: 39 return iterator 40 def _inject(iterator=iterator,suffix=suffix): 41 for path in iterator: 42 if path.endswith('.dylib'): 43 yield path[:-6] + suffix + '.dylib' 44 else: 45 yield path + suffix 46 yield path 47 return _inject() 48 49def dyld_framework(filename, framework_name, version=None): 50 """Find a framework using dyld semantics""" 51 filename = ensure_unicode(filename) 52 framework_name = ensure_unicode(framework_name) 53 version = ensure_unicode(version) 54 55 def _search(): 56 spath = ensure_unicode(os.environ.get('DYLD_FRAMEWORK_PATH', None)) 57 if spath is not None: 58 for path in spath.split(':'): 59 if version: 60 yield os.path.join( 61 path, framework_name + '.framework', 62 'Versions', version, framework_name 63 ) 64 else: 65 yield os.path.join( 66 path, framework_name + '.framework', framework_name 67 ) 68 yield filename 69 spath = ensure_unicode(os.environ.get( 70 'DYLD_FALLBACK_FRAMEWORK_PATH', DEFAULT_FRAMEWORK_FALLBACK 71 )) 72 for path in spath.split(':'): 73 if version: 74 yield os.path.join( 75 path, framework_name + '.framework', 'Versions', 76 version, framework_name 77 ) 78 else: 79 yield os.path.join( 80 path, framework_name + '.framework', framework_name 81 ) 82 83 84 for f in inject_suffixes(_search()): 85 if os.path.exists(f): 86 return f 87 # raise .. 88 raise ImportError("Framework %s could not be found" % (framework_name,)) 89 90def dyld_library(filename, libname): 91 """Find a dylib using dyld semantics""" 92 filename = ensure_unicode(filename) 93 libname = ensure_unicode(libname) 94 def _search(): 95 spath = ensure_unicode(os.environ.get('DYLD_LIBRARY_PATH', None)) 96 if spath is not None: 97 for path in spath.split(':'): 98 yield os.path.join(path, libname) 99 yield filename 100 spath = ensure_unicode(os.environ.get( 101 'DYLD_FALLBACK_LIBRARY_PATH', DEFAULT_LIBRARY_FALLBACK 102 )) 103 for path in spath.split(':'): 104 yield os.path.join(path, libname) 105 for f in inject_suffixes(_search()): 106 if os.path.exists(f): 107 return f 108 raise ValueError("dylib %s could not be found" %(filename,)) 109 110 111def dyld_find(filename): 112 """Generic way to locate a dyld framework or dyld""" 113 filename = os.path.realpath(filename) 114 res = infoForFramework(filename) 115 if res: 116 framework_loc, framework_name, version = res 117 return dyld_framework(filename, framework_name, version) 118 else: 119 return dyld_library(filename, os.path.basename(filename)) 120 121def pathForFramework(path): 122 fpath, name, version = infoForFramework(dyld_find(path)) 123 return os.path.join(fpath, name + '.framework') 124