源代码中的函数定义列出了可能的路径:
if os.name == "posix" and sys.platform == "darwin": from ctypes.macholib.dyld import dyld_find as _dyld_find def find_library(name): possible = ['lib%s.dylib' % name, '%s.dylib' % name, '%s.framework/%s' % (name, name)] for name in possible: try: return _dyld_find(name) except ValueError: continue return None
来自macholib.dyld的相关功能:
def dyld_env(env, var): if env is None: env = os.environ rval = env.get(var) if rval is None: return [] return rval.split(':')def dyld_image_suffix(env=None): if env is None: env = os.environ return env.get('DYLD_IMAGE_SUFFIX')def dyld_framework_path(env=None): return dyld_env(env, 'DYLD_frameWORK_PATH')def dyld_library_path(env=None): return dyld_env(env, 'DYLD_LIBRARY_PATH')def dyld_fallback_framework_path(env=None): return dyld_env(env, 'DYLD_FALLBACK_frameWORK_PATH')def dyld_fallback_library_path(env=None): return dyld_env(env, 'DYLD_FALLBACK_LIBRARY_PATH')def dyld_image_suffix_search(iterator, env=None): """For a potential path iterator, add DYLD_IMAGE_SUFFIX semantics""" suffix = dyld_image_suffix(env) if suffix is None: return iterator def _inject(iterator=iterator, suffix=suffix): for path in iterator: if path.endswith('.dylib'): yield path[:-len('.dylib')] + suffix + '.dylib' else: yield path + suffix yield path return _inject()def dyld_override_search(name, env=None): # If DYLD_frameWORK_PATH is set and this dylib_name is a # framework name, use the first file that exists in the framework # path if any. If there is none go on to search the DYLD_LIBRARY_PATH # if any. framework = framework_info(name) if framework is not None: for path in dyld_framework_path(env): yield os.path.join(path, framework['name']) # If DYLD_LIBRARY_PATH is set then use the first file that exists # in the path. If none use the original name. for path in dyld_library_path(env): yield os.path.join(path, os.path.basename(name))def dyld_executable_path_search(name, executable_path=None): # If we haven't done any searching and found a library and the # dylib_name starts with "@executable_path/" then construct the # library name. if name.startswith('@executable_path/') and executable_path is not None: yield os.path.join(executable_path, name[len('@executable_path/'):])def dyld_find(name, executable_path=None, env=None): """ Find a library or framework using dyld semantics """ for path in dyld_image_suffix_search(chain( dyld_override_search(name, env), dyld_executable_path_search(name, executable_path), dyld_default_search(name, env), ), env): if os.path.isfile(path): return path raise ValueError("dylib %s could not be found" % (name,))def dyld_default_search(name, env=None): yield name framework = framework_info(name) if framework is not None: fallback_framework_path = dyld_fallback_framework_path(env) for path in fallback_framework_path: yield os.path.join(path, framework['name']) fallback_library_path = dyld_fallback_library_path(env) for path in fallback_library_path: yield os.path.join(path, os.path.basename(name)) if framework is not None and not fallback_framework_path: for path in DEFAULT_frameWORK_FALLBACK: yield os.path.join(path, framework['name']) if not fallback_library_path: for path in DEFAULT_LIBRARY_FALLBACK: yield os.path.join(path, os.path.basename(name))根据 man dyld(1) 的 默认值
DEFAULT_frameWORK_FALLBACK = [ os.path.expanduser("~/Library/frameworks"), "/Library/frameworks", "/Network/Library/frameworks", "/System/Library/frameworks",]DEFAULT_LIBRARY_FALLBACK = [ os.path.expanduser("~/lib"), "/usr/local/lib", "/lib", "/usr/lib",]


