conda 包的平台独立构建



我正在尝试构建一个包含单个 Python 包的 conda 包,该包在导入时读取静态文件。虽然包本身工作正常,但包的位置最终取决于用于构建包的平台,因此最终无法将包导入与用于构建包的平台不同的平台上。

由于根本没有平台依赖性,并且由于 conda 允许通过noarch进行跨平台包,因此似乎应该可以在单个平台上构建包,而不是每个平台一次。

下面是一个最小示例:

/setup.py

from setuptools import setup, find_packages

setup(
name='mypackage',
description='My platform independent package',
packages=find_packages(),
data_files=[('mypackage', ['mypackage/myfile.txt'])]
)

/conda_recipe/meta.yaml

{% set data = load_setup_py_data() %}
build:
noarch: python
package:
name: mypackage
source:
path: ..
requirements:
build:
- python
- setuptools
about:
summary: {{ data.get('description') }}

/mypackage/myfile.txt

foo

/mypackage/__init__.py

import os
# Print contents of myfile.txt when the package is imported
with open(os.path.join(os.path.dirname(__file__), 'myfile.txt')) as f:
print(f.read())

通过删除meta.yamlnoarch: python部分,我可以构建在构建它们的平台上工作的软件包。但是,如果我在 Windows 上使用conda build构建noarch包,并在任一平台上conda install它,Python 模块和数据文件最终会变成{conda-env}/Lib/site-packages,而如果我在 Linux 上构建它,并在任一平台上conda install它,它们最终会变成{conda-env}/lib/python3.7/site-packages(注意小写l(。

这是一个问题,因为确定包含路径的环境变量在两个平台上不同。因此,在 Windows 上构建的软件包在 Windows 上运行良好,在 Linux 上构建的软件包在 Linux 上运行良好,但在一个平台上构建的软件包无法在另一个平台上运行;特别是,Linux上的Miniconda默认包含后一条路径sys.path,因此它将无法找到在Windows上构建的软件包,安装在Linux上。

也就是说,我不能简单地在一个平台上构建包,将其转储到我的频道noarch,然后感到高兴,即使包内容本身是独立于平台的。当然,静态数据文件不是这里的罪魁祸首,但无论如何,我已经把它包含在我的问题中,仅仅是因为确保它们最终出现在正确的位置本身就不是一件容易的事。

在 Windows 和 WSL 上使用最新版本的 Miniconda 时会出现此问题。

所以我的问题变成了:

如果我想构建一个只包含简单文件的 conda 包,并且在导入包时读取此文件的__init__.py,我可以在单个平台上构建包吗?

在Windows和Linux上更新conda-build和Python后,我无法再重现我的问题;安装后,软件包仍然会在不同的目录中结束:Linux上的lib/python3.8/site-packages和Windows上的lib/site-packages;奇怪的是,l现在在Windows上是小写的,由于Windows是Windows,最终无关紧要。

不幸的是,这几乎没有提供对原始问题的见解,但至少这应该足以开始。

特别是,以下步骤适用于我原始问题中包含的最小示例,使用 WSL 测试在 Windows 上构建的包:

  1. 创建一个新环境,mypackage-build,激活它,然后运行conda install python conda-build
  2. 在 Windows 上,使用conda build conda_recipe生成包。
  3. 在不指定任何其他内容的情况下,构建的包最终会在我的机器上C:UsersusernameAppDataLocalContinuumminiconda3envsmypackage-buildconda-bld
  4. 停用构建环境,创建一个名为mypackage-test的新环境,激活它,安装 Python,然后使用conda install -c C:UsersusernameAppDataLocalContinuumminiconda3envsmypackage-buildconda-bld mypackage安装上面构建的包。
  5. 运行where python以确保从mypackage-test环境中获取python.exe,运行 Python,调用import mypackage,并注意包确实已导入。
  6. 在 WSL 上,创建一个名为mypackage-test-wsl的新环境,激活它,安装 Python,然后运行conda install -c /mnt/c/Users/username/AppData/Local/Continuum/miniconda3/envs/mypackage-build/conda-bld mypackage(如果以不同的方式装载驱动器,则相应地修改(。
  7. 运行 Python,import mypackage,并注意一切正常(这是我最初遇到问题的地方(。
  8. 镜像该过程,在 WSL 上生成包,将其安装在 Windows 上,并注意一切正常。

在测试上述内容时,我确实遇到了一个问题,所以为了完整起见,让我在这里注意这一点:第一次创建mypackage-test时,我是从mypackage-build环境中这样做的。结果,即使包将安装在mypackage-test中,父环境中的 Python 运行时也会优先(我认为这很奇怪,但没关系(,这将导致上面的"步骤 5"失败;

>where python
C:UsersusernameAppDataLocalContinuumminiconda3envsmypackage-buildpython.exe
C:UsersusernameAppDataLocalContinuumminiconda3envsmypackage-buildenvsmypackage-testpython.exe
C:UsersusernameAppDataLocalContinuumminiconda3python.exe

最新更新