【问题标题】:Packaging executable, shared library, and Python bindings not finding library打包可执行文件、共享库和未找到库的 Python 绑定
【发布时间】:2021-11-20 08:12:34
【问题描述】:

我有一个项目cloudgen,我想为 Python 添加绑定,以便可以访问一些底层函数。我已经完成了最初的工作on a branch。因为主要的可执行文件是用cmake构建的,所以我决定使用scikit-build来管理构建并使用pybind11来处理绑定(following this example repo)。

当我在虚拟环境中运行pip install . 时,一切似乎都按预期工作。我发现可执行文件安装到<prefix>/bin,库进入<prefix>/lib,模块进入<prefix>/lib/pythonX.Y/site-packages/cloudgen。事实上,如果我运行pip uninstall cloudgen,所有正确的文件都会被卸载。但是,当我开始测试 Python 绑定时,我的问题就出现了。我发现了两个独立但相关的问题。

  • 如果我安装到 Anaconda 环境中,模块能够解析到共享库的路径并通过测试,但可执行文件无法解析到库的路径。
  • 另一方面,如果我使用python -m venv 安装到虚拟环境中,模块和可执行文件都无法解析到共享库的路径。

四处搜索,我发现了this question,其中指出我可以操纵LD_LIBRARY_PATH(或在macOS 上相当于DYLD_LIBRARY_PATH,在Windows 上相当于PATH),但is normally frowned upon。该问题引用了an open issue,它指的是包括其他构建产品(正如我所说,这似乎不是我的问题),但没有解决库路径解析问题。我还遇到了this question 询问有关使用 scikit-build 分发构建产品和this question 直接使用 setuptools 的问题。这些问题或答案都没有解决库路径解析问题。

我的问题是:分发包含可执行文件、共享库和 Python 绑定模块并具有路径解析 Just Work™ 的包的正确方法是什么?

一个最小的工作示例有点多,但我created a gist 来演示该行为。

【问题讨论】:

    标签: python virtualenv conda scikit-build


    【解决方案1】:

    经过更多挖掘(并仔细阅读CMake documentation on RPATH),正确答案似乎是在安装时明确设置RPATHlinked gist 的相关更改是在创建目标后将以下内容添加到 CMakeLists.txt(改编自链接的 Wiki):

    set(lib_path "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
    list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${lib_path}" is_system)
    if ("${is_system}" STREQUAL "-1")
        set_target_properties(mwe.exe PROPERTIES
            INSTALL_RPATH_USE_LINK_PATH TRUE
            INSTALL_RPATH "${lib_path}")
        # The following is necessary for installation in a virtual
        # environment `python -m pip venv env`
        set_target_properties(_mwe PROPERTIES
            INSTALL_RPATH_USE_LINK_PATH TRUE
            INSTALL_RPATH "${lib_path}")
    endif()
    

    这确实需要遵循有关设置 RPATH 的其余详细信息,例如包括(字面上来自链接的 CMake Wiki):

    # use, i.e. don't skip the full RPATH for the build tree
    set(CMAKE_SKIP_BUILD_RPATH FALSE)
    
    # when building, don't use the install RPATH already
    # (but later on when installing)
    set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
    
    set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
    
    # add the automatically determined parts of the RPATH
    # which point to directories outside the build tree to the install RPATH
    set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
    

    在 CMakeLists.txt 的前面部分。最终结果是这应该禁用对已安装可执行文件和 Python 模块的库路径的动态搜索(LD_LIBRARY_PATHDYLD_LIBRARY_PATH)。

    【讨论】:

      猜你喜欢
      • 2011-12-14
      • 2012-08-13
      • 2020-06-06
      • 2017-06-18
      • 1970-01-01
      • 2018-10-10
      • 1970-01-01
      • 2023-03-15
      • 2021-12-07
      相关资源
      最近更新 更多