打包 (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) 用户 HOME 目录 (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]#

返回自身的 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]#

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

参数:
filessequence

参数可以是:

  • 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

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

示例

将文件添加到要与包一起包含的 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

其中 `<包安装目录>` 是包(或子包)目录,例如 `/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 或 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` 列表的开头。默认情况下,头文件将安装在 `/` 目录下。如果 files 的一个项目是元组,则其第一个参数指定相对于 `` 路径的实际安装位置。

参数:
filesstr 或 seq

参数可以是:

  • 2 元组(``,`<头文件路径>`)

  • 头文件的路径,其中 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

字典或字典列表,用于附加到关键字。

备注

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

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

将库添加到配置。

参数:
namestr

扩展的名称。

sourcessequence

源列表。源列表可能包含函数(称为源生成器),这些函数必须以扩展实例和构建目录作为输入,并返回源文件或源文件列表或 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` 列表的开头。脚本将安装在 `/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,可选

允许以下键:

  • 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配置文件。

使用subst_dict进行变量替换,将从template生成的配置文件安装到指定的安装目录。

参数:
templatestr

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

install_dirstr

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

subst_dictdict, optional

如果给出,则在安装时,任何形式为@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配置命令实例。

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,它采用相同的参数,除了一个额外的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 文件