打包 (numpy.distutils)#

警告

numpy.distutils 已弃用,将在 Python >= 3.12 中移除。有关更多详细信息,请参阅 numpy.distutils 的状态和迁移建议

警告

请注意,setuptools 经常进行主要版本发布,这些版本可能包含破坏 numpy.distutils 的更改,而 numpy.distutils 将不再更新以适应新的 setuptools 版本。因此,建议在您的构建配置中设置一个上限版本,以便使用与您的构建兼容的最新已知 setuptools 版本。

NumPy 提供增强的 distutils 功能,使构建和安装子包、自动生成代码以及使用 Fortran 编译库的扩展模块变得更容易。在 numpy.distutils.misc_util 中还提供了一个有用的 Configuration 类,它可以使构建传递给 setup 函数的关键字参数变得更容易(通过传递从类的 todict() 方法获得的字典)。更多信息可在 numpy.distutils 用户指南 中找到。

BLAS 和 LAPACK 等链接库的选择和位置以及包含路径和其他此类构建选项可以在 NumPy 根存储库中的 site.cfg 文件或主目录中的 .numpy-site.cfg 文件中指定。请参阅 NumPy 存储库或 sdist 中包含的 site.cfg.example 示例文件以获取文档。

numpy.distutils 中的模块#

ccompiler

ccompiler_opt

提供 CCompilerOpt 类,用于处理 CPU/硬件优化,从解析命令参数开始,到管理 CPU 基线和可调度功能之间的关系,以及生成所需的 C 头文件,最后使用适当的编译器标志编译源代码。

cpuinfo.cpu

core.Extension(name, sources[, ...])

参数:

exec_command

exec_command

log.set_verbosity(v[, force])

system_info.get_info(name[, notfound_action])

notfound_action

system_info.get_standard_file(fname)

返回名为 'fname' 的文件列表,这些文件来自:1) 系统范围的目录(此模块的目录位置)2) 用户的主目录 (os.environ['HOME']) 3) 本地目录

Configuration 类#

class numpy.distutils.misc_util.Configuration(package_name=None, parent_name=None, top_path=None, package_path=None, **attrs)[source]#

为给定的包名称构造一个配置实例。如果 parent_name 不为 None,则将包构造为 parent_name 包的子包。如果 top_pathpackage_path 为 None,则假定它们等于创建此实例的文件的路径。numpy 发行版中的 setup.py 文件是关于如何使用 Configuration 实例的良好示例。

todict()[source]#

返回与 distutils setup 函数的关键字参数兼容的字典。

示例

>>> setup(**config.todict())                           
get_distribution()[source]#

返回 self 的 distutils 分发对象。

get_subpackage(subpackage_name, subpackage_path=None, parent_name=None, caller_level=1)[source]#

返回子包配置列表。

参数:
subpackage_namestr 或 None

要获取配置的子包名称。subpackage_name 中的 ‘*’ 将被视为通配符。

subpackage_pathstr

如果为 None,则假定路径为本地路径加上 subpackage_name。如果在 subpackage_path 中找不到 setup.py 文件,则使用默认配置。

parent_namestr

父名称。

add_subpackage(subpackage_name, subpackage_path=None, standalone=False)[source]#

将子包添加到当前 Configuration 实例。

这在 setup.py 脚本中用于将子包添加到包中很有用。

参数:
subpackage_namestr

子包名称

subpackage_pathstr

如果给出,则为子包路径,例如子包位于 subpackage_path / subpackage_name 中。如果为 None,则假定子包位于本地路径 / subpackage_name 中。

standalonebool
add_data_files(*files)[source]#

将数据文件添加到配置数据文件。

参数:
files序列

参数可以是

  • 2 元组 (<数据目录前缀>,<数据文件路径>)

  • 数据文件路径,其中 python 数据目录前缀默认为包目录。

注释

files 序列中每个元素的形式非常灵活,允许从包中获取文件以及最终应将其安装到系统上的位置的多种组合。最基本的用法是 files 参数序列的元素为简单文件名。这将导致本地路径中的该文件安装到 self.name 包的安装路径(包路径)。文件参数也可以是相对路径,在这种情况下,整个相对路径将安装到包目录中。最后,文件可以是绝对路径名,在这种情况下,将在绝对路径名处找到文件,但安装到包路径中。

可以通过将 2 元组作为文件参数传递来增强此基本行为。元组的第一个元素应指定在包安装目录下应将剩余文件序列安装到的相对路径(与源发行版中的文件名无关)。元组的第二个元素是应安装的文件序列。此序列中的文件可以是文件名、相对路径或绝对路径。对于绝对路径,文件将安装到顶级包安装目录(与第一个参数无关)。文件名和相对路径名将安装到包安装目录下的作为元组的第一个元素给出的路径名下。

安装路径规则

  1. file.txt -> (., file.txt)-> parent/file.txt

  2. foo/file.txt -> (foo, foo/file.txt) -> parent/foo/file.txt

  3. /foo/bar/file.txt -> (., /foo/bar/file.txt) -> parent/file.txt

  4. *.txt -> parent/a.txt, parent/b.txt

  5. foo/*.txt`` -> parent/foo/a.txt, parent/foo/b.txt

  6. */*.txt -> (*, */*.txt) -> parent/c/a.txt, parent/d/b.txt

  7. (sun, file.txt) -> parent/sun/file.txt

  8. (sun, bar/file.txt) -> parent/sun/file.txt

  9. (sun, /foo/bar/file.txt) -> parent/sun/file.txt

  10. (sun, *.txt) -> parent/sun/a.txt, parent/sun/b.txt

  11. (sun, bar/*.txt) -> parent/sun/a.txt, parent/sun/b.txt

  12. (sun/*, */*.txt) -> parent/sun/c/a.txt, parent/d/b.txt

另一个功能是,数据文件的路径实际上可以是一个不带参数并返回数据文件的实际路径的函数。当数据文件在构建包时生成时,这很有用。

示例

将文件添加到要与包一起包含的数据文件列表中。

>>> self.add_data_files('foo.dat',
...     ('fun', ['gun.dat', 'nun/pun.dat', '/tmp/sun.dat']),
...     'bar/cat.dat',
...     '/full/path/to/can.dat')                   

将安装这些数据文件到

<package install directory>/
 foo.dat
 fun/
   gun.dat
   nun/
     pun.dat
 sun.dat
 bar/
   car.dat
 can.dat

其中 <包安装目录> 是包(或子包)目录,例如 ‘/usr/lib/python2.4/site-packages/mypackage’ (‘C: Python2.4 Lib site-packages mypackage’) 或 ‘/usr/lib/python2.4/site- packages/mypackage/mysubpackage’ (‘C: Python2.4 Lib site-packages mypackage mysubpackage’)。

add_data_dir(data_path)[source]#

递归地将 data_path 下的文件添加到 data_files 列表。

递归地将 data_path 下的文件添加到要安装(和分发)的数据文件列表中。data_path 可以是相对路径名、绝对路径名或 2 元组,其中第一个参数显示应在安装目录中的哪个位置安装数据目录。

参数:
data_path序列或 str

参数可以是

  • 2 元组 (<数据目录后缀>, <数据目录路径>)

  • 数据目录路径,其中 python 数据目录后缀默认为包目录。

注释

安装路径规则

foo/bar -> (foo/bar, foo/bar) -> parent/foo/bar
(gun, foo/bar) -> parent/gun
foo/* -> (foo/a, foo/a), (foo/b, foo/b) -> parent/foo/a, parent/foo/b
(gun, foo/*) -> (gun, foo/a), (gun, foo/b) -> gun
(gun/*, foo/*) -> parent/gun/a, parent/gun/b
/foo/bar -> (bar, /foo/bar) -> parent/bar
(gun, /foo/bar) -> parent/gun
(fun/*/gun/*, sun/foo/bar) -> parent/fun/foo/gun/bar

示例

例如,假设源目录包含 fun/foo.dat 和 fun/bar/car.dat

>>> self.add_data_dir('fun')                       
>>> self.add_data_dir(('sun', 'fun'))              
>>> self.add_data_dir(('gun', '/full/path/to/fun'))

将数据文件安装到以下位置

<package install directory>/
  fun/
    foo.dat
    bar/
      car.dat
  sun/
    foo.dat
    bar/
      car.dat
  gun/
    foo.dat
    car.dat
add_include_dirs(*paths)[source]#

将路径添加到配置包含目录。

将给定的路径序列添加到 include_dirs 列表的开头。此列表将对当前包的所有扩展模块可见。

add_headers(*files)[source]#

将可安装的头文件添加到配置中。

将给定的文件序列添加到 headers 列表的开头。默认情况下,头文件将安装在 <python- include>/<self.name.replace(‘.’,’/’)>/ 目录下。如果 files 的某个项目是元组,则其第一个参数指定相对于 <python-include> 路径的实际安装位置。

参数:
filesstr 或 seq

参数可以是

  • 2 元序列 (<includedir 后缀>,<头文件路径>)

  • 头文件路径,其中 python includedir 后缀将默认为包名称。

add_extension(name, sources, **kw)[source]#

将扩展添加到配置中。

创建并向 ext_modules 列表添加一个 Extension 实例。此方法还接受以下可选关键字参数,这些参数将传递给 Extension 构造函数。

参数:
namestr

扩展的名称

sourcesseq

源代码列表。源代码列表可能包含函数(称为源代码生成器),这些函数必须以扩展实例和构建目录作为输入,并返回源文件或源文件列表或 None。如果返回 None,则不会生成任何源代码。如果在处理所有源代码生成器后 Extension 实例没有源代码,则不会构建任何扩展模块。

include_dirs
define_macros
undef_macros
library_dirs
libraries
runtime_library_dirs
extra_objects
extra_compile_args
extra_link_args
extra_f77_compile_args
extra_f90_compile_args
export_symbols
swig_opts
depends

depends 列表包含扩展模块源代码依赖的文件或目录的路径。如果 depends 列表中的任何路径都比扩展模块新,则将重新构建模块。

language
f2py_options
module_dirs
extra_infodict 或 list

要附加到关键字的关键字的 dict 或 dict 列表。

注释

self.paths(…) 方法应用于所有可能包含路径的列表。

add_library(name, sources, **build_info)[source]#

将库添加到配置中。

参数:
namestr

扩展的名称。

sources序列

源代码列表。源代码列表可能包含函数(称为源代码生成器),这些函数必须以扩展实例和构建目录作为输入,并返回源文件或源文件列表或 None。如果返回 None,则不会生成任何源代码。如果在处理所有源代码生成器后 Extension 实例没有源代码,则不会构建任何扩展模块。

build_infodict,可选

允许使用以下键

  • depends

  • macros

  • include_dirs

  • extra_compiler_args

  • extra_f77_compile_args

  • extra_f90_compile_args

  • f2py_options

  • language

add_scripts(*files)[source]#

将脚本添加到配置中。

将文件序列添加到 scripts 列表的开头。脚本将安装在 <prefix>/bin/ 目录下。

add_installed_library(name, sources, install_dir, build_info=None)[source]#

类似于 add_library,但指定的库已安装。

大多数与 distutils 一起使用的 C 库仅用于构建 python 扩展,但通过此方法构建的库将被安装,以便第三方包可以重用它们。

参数:
namestr

已安装库的名称。

sources序列

库的源文件列表。有关详细信息,请参阅 add_library

install_dirstr

安装库的路径,相对于当前子包。

build_infodict,可选

允许使用以下键

  • depends

  • macros

  • include_dirs

  • extra_compiler_args

  • extra_f77_compile_args

  • extra_f90_compile_args

  • f2py_options

  • language

返回值:
None

注释

编码链接到指定 C 库所需选项的最佳方法是使用“libname.ini”文件,并使用 get_info 检索所需选项(有关更多信息,请参阅 add_npy_pkg_config)。

add_npy_pkg_config(template, install_dir, subst_dict=None)[source]#

从模板生成并安装 npy-pkg 配置文件。

template 生成的配置文件安装在给定的安装目录中,使用 subst_dict 进行变量替换。

参数:
templatestr

模板的路径,相对于当前包路径。

install_dirstr

安装 npy-pkg 配置文件的位置,相对于当前包路径。

subst_dictdict,可选

如果给出,则表单 @key@ 的任何字符串都将被 subst_dict[key] 替换,在安装时替换模板文件中的字符串。安装前缀始终可以通过变量 @prefix@ 获得,因为安装前缀不容易从 setup.py 中可靠地获取。

注释

这适用于标准安装和就地构建,即 @prefix@ 指向就地构建的源目录。

示例

config.add_npy_pkg_config('foo.ini.in', 'lib', {'foo': bar})

假设 foo.ini.in 文件具有以下内容

[meta]
Name=@foo@
Version=1.0
Description=dummy description

[default]
Cflags=-I@prefix@/include
Libs=

生成的文件将具有以下内容

[meta]
Name=bar
Version=1.0
Description=dummy description

[default]
Cflags=-Iprefix_dir/include
Libs=

并将安装为 lib 子路径中的 foo.ini。

使用 numpy distutils 交叉编译时,可能需要使用修改后的 npy-pkg-config 文件。使用默认/生成的文件将链接到主机库(即 libnpymath.a)。对于交叉编译,您当然需要链接到目标库,同时使用主机 Python 安装。

您可以复制出 numpy/_core/lib/npy-pkg-config 目录,在 .ini 文件中添加 pkgdir 值,并将 NPY_PKG_CONFIG_PATH 环境变量设置为指向包含修改后的 npy-pkg-config 文件的目录。

为交叉编译修改的 npymath.ini 示例

[meta]
Name=npymath
Description=Portable, core math library implementing C99 standard
Version=0.1

[variables]
pkgname=numpy._core
pkgdir=/build/arm-linux-gnueabi/sysroot/usr/lib/python3.7/site-packages/numpy/_core
prefix=${pkgdir}
libdir=${prefix}/lib
includedir=${prefix}/include

[default]
Libs=-L${libdir} -lnpymath
Cflags=-I${includedir}
Requires=mlib

[msvc]
Libs=/LIBPATH:${libdir} npymath.lib
Cflags=/INCLUDE:${includedir}
Requires=mlib
paths(*paths, **kws)[source]#

将 glob 应用于路径,并在需要时添加 local_path。

将 glob.glob(…) 应用于序列中的每个路径(如果需要),并在需要时添加 local_path。由于这被调用在所有源列表上,因此允许在扩展模块和库以及脚本的源列表中指定通配符字符,并允许路径名相对于源目录。

get_config_cmd()[source]#

返回 numpy.distutils config 命令实例。

get_build_temp_dir()[source]#

返回应放置临时文件的临时目录的路径。

have_f77c()[source]#

检查 Fortran 77 编译器的可用性。

在源代码生成函数内部使用它,以确保已初始化 setup 分发实例。

注释

如果 Fortran 77 编译器可用(因为能够成功编译简单的 Fortran 77 代码),则为 True。

have_f90c()[source]#

检查 Fortran 90 编译器的可用性。

在源代码生成函数内部使用它,以确保已初始化 setup 分发实例。

注释

如果 Fortran 90 编译器可用(因为能够成功编译简单的 Fortran 90 代码),则为 True。

get_version(version_file=None, version_variable=None)[source]#

尝试获取包的版本字符串。

返回当前包的版本字符串,如果无法检测到版本信息,则返回 None。

注释

此方法扫描名为 __version__.py、<packagename>_version.py、version.py 和 __svn_version__.py 的文件,查找字符串变量 version、__version__ 和 <packagename>_version,直到找到版本号。

make_svn_version_py(delete=True)[source]#

将数据函数附加到 data_files 列表,该函数将 __svn_version__.py 文件生成到当前包目录。

从 SVN 修订号生成包 __svn_version__.py 文件,它将在 python 退出后被删除,但在执行 sdist 等命令时将可用。

注释

如果 __svn_version__.py 之前存在,则不执行任何操作。

这旨在用于位于 SVN 存储库中的源目录。

make_config_py(name='__config__')[source]#

生成包含构建包期间使用的 system_info 信息的包 __config__.py 文件。

此文件安装到包安装目录。

get_info(*names)[source]#

获取资源信息。

返回参数列表中所有名称的 system_info.get_info 信息,包含在一个字典中。

构建可安装的 C 库#

传统的 C 库(通过 add_library 安装)不会被安装,仅在构建期间使用(它们是静态链接的)。可安装的 C 库是纯 C 库,不依赖于 python C 运行时,并且已安装以便第三方包可以使用它。要构建和安装 C 库,只需使用 add_installed_library 方法而不是 add_library 方法,它接受相同的参数,除了额外的 install_dir 参数。

.. hidden in a comment so as to be included in refguide but not rendered documentation
  >>> import numpy.distutils.misc_util
  >>> config = np.distutils.misc_util.Configuration(None, '', '.')
  >>> with open('foo.c', 'w') as f: pass

>>> config.add_installed_library('foo', sources=['foo.c'], install_dir='lib')

npy-pkg-config 文件#

为了使必要的构建选项可供第三方使用,您可以使用在numpy.distutils中实现的npy-pkg-config机制。此机制基于一个包含所有选项的 .ini 文件。.ini 文件与 pkg-config unix 实用程序使用的 .pc 文件非常相似。

[meta]
Name: foo
Version: 1.0
Description: foo library

[variables]
prefix = /home/user/local
libdir = ${prefix}/lib
includedir = ${prefix}/include

[default]
cflags = -I${includedir}
libs = -L${libdir} -lfoo

通常,该文件需要在构建期间生成,因为它需要一些仅在构建时才知道的信息(例如前缀)。如果使用Configuration方法add_npy_pkg_config,则此过程大多是自动的。假设我们有一个如下所示的模板文件 foo.ini.in

[meta]
Name: foo
Version: @version@
Description: foo library

[variables]
prefix = @prefix@
libdir = ${prefix}/lib
includedir = ${prefix}/include

[default]
cflags = -I${includedir}
libs = -L${libdir} -lfoo

以及 setup.py 中的以下代码

>>> config.add_installed_library('foo', sources=['foo.c'], install_dir='lib')
>>> subst = {'version': '1.0'}
>>> config.add_npy_pkg_config('foo.ini.in', 'lib', subst_dict=subst)

这将把文件 foo.ini 安装到目录 package_dir/lib 中,并且 foo.ini 文件将从 foo.ini.in 生成,其中每个@version@ 将被subst_dict['version']替换。字典会自动添加一个额外的前缀替换规则,其中包含安装前缀(因为这不容易从 setup.py 中获取)。

重用另一个包中的 C 库#

信息很容易从get_info函数(位于numpy.distutils.misc_util中)中检索。

>>> info = np.distutils.misc_util.get_info('npymath')
>>> config.add_extension('foo', sources=['foo.c'], extra_info=info)
<numpy.distutils.extension.Extension('foo') at 0x...>

可以向get_info提供一个额外的路径列表,用于查找 .ini 文件。

.src 文件的转换#

NumPy distutils 支持自动转换名为 <somefile>.src 的源文件。此功能可用于维护非常相似的代码块,这些代码块只需要在块之间进行简单的更改。在 setup 的构建阶段,如果遇到名为 <somefile>.src 的模板文件,则会从模板构建一个名为 <somefile> 的新文件,并将其放置在构建目录中以供使用。支持两种形式的模板转换。第一种形式适用于名为 <file>.ext.src 的文件,其中 ext 是识别的 Fortran 扩展名(f、f90、f95、f77、for、ftn、pyf)。第二种形式用于所有其他情况。请参阅使用模板转换 .src 文件