【问题标题】:Which paths does python ctypes module search for libraries on Mac OS?python ctypes 模块在 Mac OS 上搜索库的路径有哪些?
【发布时间】:2015-06-30 20:58:30
【问题描述】:

Python 文档(我检查了 2.7 和 3.4)指出:

在 OS X 上,find_library() 会尝试几种预定义的命名方案和路径来定位库,如果成功则返回完整的路径名:

然后给出来自两个文件夹的示例:/usr/lib/System/Library。我想这不是完整的列表,因为我有使用来自/usr/local/lib 的 python 查找库的经验。 python ctypes find_library 在 Mac OS X 上搜索的完整路径列表是什么?

【问题讨论】:

    标签: python macos


    【解决方案1】:

    源中的函数定义列出了可能的路径:

    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",
    ]
    

    【讨论】:

    • 这显示了命名方案,但没有回答有关路径(即文件夹)python 搜索的问题。
    • @EriksDobelis,这一切都在源代码中
    猜你喜欢
    • 2012-06-12
    • 2011-04-01
    • 2015-03-12
    • 1970-01-01
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    • 2015-02-03
    • 2018-04-09
    相关资源
    最近更新 更多