[英]Packaging executable, shared library, and Python bindings not finding library
我有一個項目cloudgen ,我想為 Python 添加綁定,這樣我就可以訪問一些底層函數。 我已經在一個分支上完成了最初的工作。 因為主要的可執行文件是用 cmake 構建的,所以我決定使用scikit-build來管理構建並使用pybind11來處理綁定(遵循這個示例 repo )。
當我運行pip install.
在虛擬環境中,一切似乎都按預期工作。 我發現可執行文件安裝到<prefix>/bin
,庫進入<prefix>/lib
,模塊進入<prefix>/lib/pythonX.Y/site-packages/cloudgen
。 事實上,如果我運行pip uninstall cloudgen
,所有正確的文件都會被卸載。 然而,當我開始測試 Python 綁定時,我的問題就出現了。 我發現了兩個獨立但相關的問題。
python -m venv
安裝到虛擬環境中,則模塊和可執行文件都無法解析共享庫的路徑。 環顧四周,我遇到了這個問題,其中指出我可以操縱LD_LIBRARY_PATH
(或等效於 macOS 上的DYLD_LIBRARY_PATH
或 Windows 上的PATH
),但這通常是不贊成的。 該問題引用了一個未解決的問題,該問題涉及包括其他構建產品(正如我所說,這似乎不是我的問題),但沒有解決庫路徑解析。 我還遇到了這個問題,詢問有關使用 scikit-build 分發構建產品的問題,以及直接使用 setuptools 的問題。 這些問題或答案都沒有解決庫路徑解析問題。
我的問題是:分發包含可執行文件、共享庫和 Python 綁定模塊並具有路徑解析 Just Work™ 的 package 的正確方法是什么?
一個最小的工作示例有點多,但我創建了一個要點來演示該行為。
經過更多的挖掘(並仔細閱讀RPATH
上的 CMake 文檔),正確的答案似乎是在安裝時明確設置RPATH
。 對鏈接要點的相關更改是在創建目標后將以下內容添加到 CMakeLists.txt(改編自鏈接的 Wiki):
if (SKBUILD)
find_package(PythonExtensions REQUIRED)
set(lib_path "${PYTHON_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
else()
set(lib_path "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
endif()
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()
這確實需要遵循 rest 的有關設置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_PATH
或DYLD_LIBRARY_PATH
)的動態搜索。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.