打包#

警告

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)

从 1) 系统范围目录(此模块的目录位置)、2) 用户主目录 (os.environ['HOME'])、3) 本地目录中返回名为 'fname' 的文件列表。

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 distribution 对象。

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

返回子包配置列表。

参数:
subpackage_namestr or None

要获取配置的子包名称。subpackage_name 中的“*”被视为通配符。

subpackage_pathstr

如果为 None,则假定路径为本地路径加上子包名。如果在 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]#

将数据文件添加到 configuration 的 data_files。

参数:
filessequence

参数可以是

  • 2-sequence (<datadir prefix>,<data file(s) 的路径>)

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

备注

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

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

示例

将文件添加到要包含在包中的 data_files 列表。

>>> 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

其中 <package install directory> 是包(或子包)目录,例如‘/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_files 列表中。data_path 可以是相对路径名、绝对路径名或 2-元组,其中第一个参数指示数据目录应安装到安装目录的哪个位置。

参数:
data_pathseq or str

参数可以是

  • 2-sequence (<datadir suffix>, <data directory 的路径>)

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

备注

安装路径规则

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 目录。

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

add_headers(*files)[source]#

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

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

参数:
filesstr or seq

参数可以是

  • 2-sequence (<includedir suffix>,<header file(s) 的路径>)

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

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

将扩展添加到配置。

创建 Extension 实例并将其添加到 ext_modules 列表。此方法还接受以下可选关键字参数,这些参数将传递给 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 or list

将被附加到关键字的关键字的字典或字典列表。

备注

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

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

将库添加到配置。

参数:
namestr

扩展的名称。

sourcessequence

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

build_infodict, optional

允许的键如下

  • 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

已安装库的名称。

sourcessequence

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

install_dirstr

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

build_infodict, optional

允许的键如下

  • 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, optional

如果给出,则模板文件中的任何形式为 @key@ 的字符串都将被 subst_dict[key] 替换。由于从 setup.py 无法可靠地获取安装前缀,因此安装前缀始终可通过变量 @prefix@ 获得。

备注

这适用于标准安装和就地构建,即 @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 distribution 实例已被初始化。

备注

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

have_f90c()[source]#

检查 Fortran 90 编译器是否可用。

在源生成函数中使用它,以确保 setup distribution 实例已被初始化。

备注

如果 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,该方法接受与 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

通常,该文件需要在构建期间生成,因为它需要一些只有在构建时才知道的信息(例如,prefix)。如果使用 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'] 替换。该字典会自动添加一个额外的 prefix 替换规则,其中包含安装前缀(因为这不容易从 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 文件