build 1.6.0 在 Windows 报 DLL 缺失,检查隔离解释器是否改成符号链接
build 1.6.0 改变 Windows 隔离解释器的布局后,部分环境会报 DLL 加载失败。采用恢复复制方式的版本,保留隔离构建并验收完整产物。
Windows CI 在创建构建隔离环境后,安装依赖时报 _ssl 或 _ctypes 的 DLL 加载失败;日志还可能夹着 pip 模块缺失和控制台报错。若同一构建从 build 1.5.0 升到 1.6.0 后才出现这组变化,先核对隔离解释器是否由复制变成了符号链接。
build 1.6.0 修正了 Windows 上检测符号链接能力的探测。此前探测在该平台实际失败,隔离环境使用复制的解释器;探测修正后,有权限创建链接的 Windows runner 会改用符号链接。能够建立链接,却不能证明这份 Python 发行在链接后的布局中仍能找到全部 DLL。
已确认的原路径包含 Windows CI 与 Conda 解释器。它不表示所有 Conda、所有 Python 3.8 之后版本或所有 DLL 缺失都由这项探测造成。尤其要区分:外层解释器本来就无法导入标准库,还是只在新建的隔离解释器中失败。
build 1.6.1 的正式代码去掉了该探测选择,在 Windows 上按 venv 命令的默认方式使用复制。修的是隔离解释器布局,不要求重新给项目配一组无关 DLL,也没有取消构建隔离。
可以先在原构建环境中确认入口,再采用包含修补的版本。以下命令用于 Windows PowerShell:
python -c "import sys; print(sys.executable)"
python -m pip install "build==1.6.1"
python -c "from importlib.metadata import version; print(version('build'))"
python -c "import ssl, ctypes; print('outer interpreter imports ok')"
python -m build --verbose
前面的标准库导入只检查外层解释器,不能代替隔离环境验收。最后一条仍需经过原构建依赖安装、源码包及 wheel 生成。保留 CI 原来的解释器来源与项目配置,避免同时换掉 Python 发行后无法比较。
如果构建流程在多个环境中分别安装 build,要核对真正执行 python -m build 的那一份。只修改其中一个安装步骤,下一步仍可能解析到旧版本;普通终端查到 1.6.1,也不证明 CI 的命令使用了它。
日志中 _ssl、_ctypes 的最早加载失败更接近这条路径,后续 pip 模块缺失可能只是预导入失败继续传播的结果。恢复构建后再检查这些后续错误是否一起消失,不应仅针对最后一个模块名字重复安装包。
验收确认新隔离环境中的依赖安装完成,原构建入口成功产生预期 sdist 和 wheel,再通过项目原来的安装与测试流程检查产物。外层能导入 ssl,或某一次已有缓存的构建完成,都不足以覆盖原来的新建环境故障。
这份版本选择只针对符号链接探测改变解释器布局的回归。无法复制解释器启动器、打包时把绝对符号链接带进 sdist、外部程序搜索不到可执行文件,属于其他阶段。保留完整堆栈和实际版本,按最早有效错误判断,不能见到 Windows 或 DLL 字样就统一应用这项结论。


