""" dyld emulation """ __all__ = [ 'dyld_framework', 'dyld_library', 'dyld_find', 'pathForFramework', 'infoForFramework', ] import os from _framework import infoForFramework # These are the defaults as per man dyld(1) # DEFAULT_FRAMEWORK_FALLBACK = u':'.join([ os.path.expanduser(u"~/Library/Frameworks"), u"/Library/Frameworks", u"/Network/Library/Frameworks", u"/System/Library/Frameworks", ]) DEFAULT_LIBRARY_FALLBACK = u':'.join([ os.path.expanduser(u"~/lib"), u"/usr/local/lib", u"/lib", u"/usr/lib", ]) def ensure_unicode(s): """Not all of PyObjC understands unicode paths very well yet""" if isinstance(s, str): return unicode(s, 'utf8') return s def injectSuffixes(iterator): suffix = ensure_unicode(os.environ.get('DYLD_IMAGE_SUFFIX', None)) if suffix is None: return iterator def _inject(iterator=iterator,suffix=suffix): for path in iterator: if path.endswith(u'.dylib'): yield path[:-6] + suffix + u'.dylib' else: yield path + suffix yield path return _inject() def dyld_framework(filename, framework_name, version=None): """Find a framework using dyld semantics""" filename = ensure_unicode(filename) framework_name = ensure_unicode(framework_name) version = ensure_unicode(version) def _search(): spath = ensure_unicode(os.environ.get('DYLD_FRAMEWORK_PATH', None)) if spath is not None: for path in spath.split(u':'): if version: yield os.path.join( path, framework_name + u'.framework', u'Versions', version, framework_name ) else: yield os.path.join( path, framework_name + u'.framework', framework_name ) yield filename spath = ensure_unicode(os.environ.get( 'DYLD_FALLBACK_FRAMEWORK_PATH', DEFAULT_FRAMEWORK_FALLBACK )) for path in spath.split(u':'): if version: yield os.path.join( path, framework_name + u'.framework', u'Versions', version, framework_name ) else: yield os.path.join( path, framework_name + u'.framework', framework_name ) for f in injectSuffixes(_search()): if os.path.exists(f): return f # raise .. raise ValueError, "Framework %s could not be found" % (framework_name,) def dyld_library(filename, libname): """Find a dylib using dyld semantics""" filename = ensure_unicode(filename) libname = ensure_unicode(libname) def _search(): spath = ensure_unicode(os.environ.get('DYLD_LIBRARY_PATH', None)) if spath is not None: for path in spath.split(u':'): yield os.path.join(path, libname) yield filename spath = ensure_unicode(os.environ.get( 'DYLD_FALLBACK_LIBRARY_PATH', DEFAULT_LIBRARY_FALLBACK )) for path in spath.split(u':'): yield os.path.join(path, libname) for f in injectSuffixes(_search()): if os.path.exists(f): return f raise ValueError, "dylib %s could not be found" % (filename,) def dyld_find(filename): """Generic way to locate a dyld framework or dyld""" # if they passed in a framework directory, not a mach-o file # then go ahead and look where one would expect to find the mach-o filename = ensure_unicode(filename) if os.path.isdir(filename): filename = os.path.join( filename, os.path.basename(filename)[:-len(os.path.splitext(filename)[-1])] ) filename = os.path.realpath(filename) res = infoForFramework(filename) if res: framework_loc, framework_name, version = res return dyld_framework(filename, framework_name, version) else: return dyld_library(filename, os.path.basename(filename)) def pathForFramework(path): fpath, name, version = infoForFramework(dyld_find(path)) return os.path.join(fpath, name + u'.framework')