如何在pyproject.toml中声明GitHub制品BQPD为构建依赖?
问题解答
能否在pyproject.toml中声明BQPD为依赖?
不行,直接通过pyproject.toml的标准依赖字段(比如[project.dependencies])无法声明BQPD为依赖——因为BQPD不是Python包,也没有上传到PyPI,它是预编译的Fortran静态库,不符合Python包依赖的标准规范。不过你可以通过可选依赖标记配合自定义构建逻辑,实现“安装时可选启用BQPD支持”的效果。
如何处理GitHub上的BQPD预编译制品?
由于BQPD有大量对应不同系统/架构/指令集的预编译静态库,你需要在Python包的构建阶段,根据当前环境自动匹配并下载对应的制品,再链接到Uno的pybind11扩展模块。以下是具体实现方案:
1. 选择支持自定义构建逻辑的后端
推荐使用scikit-build-core(基于CMake)或setuptools配合自定义构建脚本,它们能灵活处理编译、链接和外部资源下载。比如在pyproject.toml中配置scikit-build-core作为构建后端:
[build-system] requires = ["scikit-build-core>=0.7", "pybind11>=2.10"] build-backend = "scikit_build_core.build" [project.optional-dependencies] bqpd = [] # 标记可选依赖,用户安装时用`pip install uno[bqpd]`触发
2. 在CMakeLists.txt中实现按需下载与链接
利用CMake的系统变量(如CMAKE_SYSTEM_NAME、CMAKE_SYSTEM_PROCESSOR、CMAKE_CXX_COMPILER)判断当前环境,自动下载对应版本的BQPD静态库,再链接到Uno的扩展模块:
# 启用BQPD支持的开关,可通过pip安装时的配置传递 option(UNO_USE_BQPD "Enable BQPD support" OFF) if(UNO_USE_BQPD) # 根据当前环境匹配BQPD制品URL if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") set(BQPD_URL "https://github.com/<BQPD-repo>/releases/download/<tag>/bqpd-linux-x86_64.a") elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") set(BQPD_URL "https://github.com/<BQPD-repo>/releases/download/<tag>/bqpd-macos-arm64.a") # 其他系统/架构的匹配逻辑 endif() # 下载BQPD静态库到构建目录 file(DOWNLOAD ${BQPD_URL} ${CMAKE_BINARY_DIR}/libbqpd.a STATUS BQPD_DOWNLOAD_STATUS) list(GET BQPD_DOWNLOAD_STATUS 0 BQPD_DOWNLOAD_CODE) if(NOT BQPD_DOWNLOAD_CODE EQUAL 0) message(FATAL_ERROR "Failed to download BQPD: ${BQPD_DOWNLOAD_STATUS}") endif() # 链接BQPD静态库,注意顺序:先链接Uno的目标,再链接BQPD(解决未定义符号问题) target_link_libraries(uno PRIVATE ${CMAKE_BINARY_DIR}/libbqpd.a) target_compile_definitions(uno PRIVATE UNO_USE_BQPD) endif()
3. 传递构建选项给用户
用户安装时,通过环境变量或pip的--config-settings参数启用BQPD支持:
# 方式1:通过可选依赖触发(需在构建脚本中检测是否安装了optional-dependencies) pip install uno[bqpd] # 方式2:直接传递CMake选项 pip install uno --config-settings=cmake.define.UNO_USE_BQPD=ON
4. 备选方案:允许用户手动指定BQPD路径
如果自动下载逻辑覆盖不全,可添加选项让用户手动提供已下载的BQPD静态库路径:
option(BQPD_LIBRARY_PATH "Path to pre-downloaded BQPD static library" "") if(BQPD_LIBRARY_PATH) target_link_libraries(uno PRIVATE ${BQPD_LIBRARY_PATH}) target_compile_definitions(uno PRIVATE UNO_USE_BQPD) endif()
用户安装时:
pip install uno --config-settings=cmake.define.BQPD_LIBRARY_PATH=/path/to/libbqpd.a
关键注意事项
- 符号定义顺序:由于BQPD依赖Uno定义的未定义符号,链接时必须确保Uno的目标(你的C++代码编译出的目标)先于BQPD静态库被链接,否则会出现符号未定义错误。
- 制品校验:建议在下载BQPD静态库时添加校验(如SHA256哈希),避免下载损坏或篡改的文件,CMake的
file(DOWNLOAD)支持EXPECTED_HASH参数。
内容的提问来源于stack exchange,提问作者Charlie Vanaret - the Uno guy
相关产品推荐
相关产品推荐

