打包 (numpy.distutils
)#
警告
numpy.distutils
已被弃用,并且将在 Python >= 3.12 中移除.更多详情,请参见 numpy.distutils 的状态和迁移建议
警告
请注意,``setuptools`` 经常进行重大发布,这些发布可能包含破坏 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
中的模块#
- distutils.misc_util
all_strings
allpath
appendpath
as_list
blue_text
cyan_text
cyg2win32
default_config_dict
dict_append
dot_join
exec_mod_from_location
filter_sources
generate_config_py
get_build_architecture
get_cmd
get_data_files
get_dependencies
get_ext_source_files
get_frame
get_info
get_language
get_lib_source_files
get_mathlibs
get_num_build_jobs
get_numpy_include_dirs
get_pkg_info
get_script_files
gpaths
green_text
has_cxx_sources
has_f_sources
is_local_src_dir
is_sequence
is_string
mingw32
minrelpath
njoin
red_text
sanitize_cxx_flags
terminal_has_colors
yellow_text
提供 CCompilerOpt 类,用于处理 CPU/硬件优化,从解析命令参数开始,到管理 CPU 基线和可分发特性之间的关系,还包括生成所需的 C 头文件,并以使用适当的编译器标志编译源文件结束. |
|
|
|
exec_command |
|
|
|
|
notfound_action: |
返回一个名为 'fname' 的文件列表,从 1) 系统范围目录(此模块的目录位置)2) 用户 HOME 目录(os.environ['HOME'])3) 本地目录 |
配置类#
- class numpy.distutils.misc_util.Configuration(package_name=None, parent_name=None, top_path=None, package_path=None, **attrs)[源代码][源代码]#
为给定的包名构造一个配置实例.如果 parent_name 不是 None,则将该包构造为 parent_name 包的子包.如果 top_path 和 package_path 是 None,则它们被假定为创建此实例的文件的路径.numpy 分发中的 setup.py 文件是使用
Configuration
实例的好例子.- get_subpackage(subpackage_name, subpackage_path=None, parent_name=None, caller_level=1)[源代码][源代码]#
返回子包配置列表.
- 参数:
- subpackage_namestr 或 None
获取配置的子包名称.子包名称中的 ‘*’ 作为通配符处理.
- subpackage_pathstr
如果为 None,则假定路径为本地路径加上子包名称.如果在子包路径中找不到 setup.py 文件,则使用默认配置.
- parent_namestr
父名称.
- add_subpackage(subpackage_name, subpackage_path=None, standalone=False)[源代码][源代码]#
将一个子包添加到当前配置实例.
这在为一个包添加子包的setup.py脚本中非常有用.
- 参数:
- subpackage_namestr
子包的名称
- subpackage_pathstr
如果给出,子包路径如子包位于 subpackage_path / subpackage_name.如果为 None,则假定子包位于本地路径 / subpackage_name.
- standalonebool
- add_data_files(*files)[源代码][源代码]#
将数据文件添加到配置数据 data_files.
- 参数:
- filessequence
参数可以是
2-序列 (<数据目录前缀>,<数据文件路径>)
数据文件的路径,其中python datadir前缀默认为包目录.
备注
files 序列中每个元素的形式非常灵活,允许许多从包中获取文件并最终安装到系统中的组合.最基本的用法是 files 参数序列的元素为一个简单的文件名.这将导致从本地路径安装该文件到 self.name 包的安装路径(包路径).文件参数也可以是相对路径,在这种情况下,整个相对路径将被安装到包目录中.最后,文件可以是绝对路径名,在这种情况下,文件将在绝对路径名中找到,但安装到包路径.
这种基本行为可以通过传递一个2元组作为文件参数来增强.元组的第一个元素应指定剩余文件序列应安装到的相对路径(在包安装目录下)(这与源分发中的文件名无关).元组的第二个元素是要安装的文件序列.这个序列中的文件可以是文件名、相对路径或绝对路径.对于绝对路径,文件将安装在顶级包安装目录中(无论第一个参数是什么).文件名和相对路径名将安装在包安装目录下,路径名为元组的第一个元素.
安装路径的规则:
file.txt -> (., file.txt)-> parent/file.txt
foo/file.txt -> (foo, foo/file.txt) -> parent/foo/file.txt
/foo/bar/file.txt -> (., /foo/bar/file.txt) -> parent/file.txt
*
.txt -> parent/a.txt, parent/b.txtfoo/
*
.txt`` -> parent/foo/a.txt, parent/foo/b.txt*/*.txt
-> (*
,*
/*
.txt) -> parent/c/a.txt, parent/d/b.txt(sun, file.txt) -> parent/sun/file.txt
(sun, bar/file.txt) -> parent/sun/file.txt
(sun, /foo/bar/file.txt) -> parent/sun/file.txt
(sun,
*
.txt) -> parent/sun/a.txt, parent/sun/b.txt(sun, bar/
*
.txt) -> parent/sun/a.txt, parent/sun/b.txt(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)[源代码][源代码]#
递归地将 data_path 下的文件添加到 data_files 列表中.
递归地将 data_path 下的文件添加到要安装(和分发)的 data_files 列表中.data_path 可以是相对路径名、绝对路径名,或者是包含两个元素的元组,其中第一个元素表示数据目录应安装到安装目录中的位置.
- 参数:
- data_pathseq 或 str
参数可以是
2-序列 (<数据目录后缀>, <数据目录路径>)
数据目录的路径,其中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_headers(*files)[源代码][源代码]#
将可安装的头文件添加到配置中.
将给定的文件序列添加到头文件列表的开头.默认情况下,头文件将安装在 <python-include>/<self.name.replace(‘.’,’/’)>/ 目录下.如果文件项是一个元组,那么它的第一个参数指定实际安装位置相对于 <python-include> 路径.
- 参数:
- filesstr 或 seq
参数可以是以下之一:
2-序列 (<includedir 后缀>,<头文件路径>)
头文件路径,其中python includedir 后缀将默认为包名.
- add_extension(name, sources, **kw)[源代码][源代码]#
添加扩展到配置.
创建并添加一个 Extension 实例到 ext_modules 列表.此方法还接受以下可选的关键字参数,这些参数会传递给 Extension 构造函数.
- 参数:
- namestr
扩展的名称
- sourcesseq
源列表.源列表可能包含函数(称为源生成器),这些函数必须以扩展实例和构建目录作为输入,并返回一个源文件或源文件列表或 None.如果返回 None,则不会生成源文件.如果在处理所有源生成器后扩展实例没有源文件,则不会构建扩展模块.
- 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_info字典或列表
要附加到关键词的 dict 或 dict 列表.
备注
self.paths(…) 方法应用于所有可能包含路径的列表.
- add_library(name, sources, **build_info)[源代码][源代码]#
将库添加到配置中.
- 参数:
- namestr
扩展的名称.
- sourcessequence
源列表.源列表可能包含函数(称为源生成器),这些函数必须以扩展实例和构建目录作为输入,并返回一个源文件或源文件列表或None.如果返回None,则不会生成源文件.如果在处理所有源生成器后扩展实例没有源文件,则不会构建扩展模块.
- build_info字典, 可选
以下键是允许的:
取决于
宏
include_dirs
extra_compiler_args
extra_f77_compile_args
extra_f90_compile_args
f2py_options
language
- add_installed_library(name, sources, install_dir, build_info=None)[源代码][源代码]#
类似于 add_library,但指定的库是已安装的.
大多数与
distutils
一起使用的 C 库仅用于构建 python 扩展,但通过此方法构建的库将被安装,以便第三方包可以重用它们.- 参数:
- namestr
已安装库的名称.
- sourcessequence
库的源文件列表.详情请参见 add_library.
- install_dirstr
安装库的路径,相对于当前子包.
- build_info字典, 可选
以下键是允许的:
取决于
宏
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)[源代码][源代码]#
从模板生成并安装一个 npy-pkg 配置文件.
从 template 生成的配置文件安装在给定的安装目录中,使用 subst_dict 进行变量替换.
- 参数:
- templatestr
模板的路径,相对于当前包路径.
- install_dirstr
相对于当前包路径,npy-pkg 配置文件应安装在何处.
- subst_dict字典, 可选
如果在模板文件中给出,任何形式的字符串
@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=
并将作为 foo.ini 安装在 ‘lib’ 子路径中.
在使用 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)[源代码][源代码]#
如果需要,对路径应用 glob 并在前面加上 local_path.
对序列中的每个路径(如果需要)应用 glob.glob(…) 并在需要时在前面加上 local_path.因为这会在所有源列表上调用,这允许在扩展模块、库和脚本的源列表中指定通配符字符,并允许路径名相对于源目录.
- have_f77c()[源代码][源代码]#
检查Fortran 77编译器的可用性.
在源生成函数内部使用它,以确保已初始化设置分发实例.
备注
如果一个 Fortran 77 编译器可用(因为一个简单的 Fortran 77 代码能够成功编译),则为真.
- have_f90c()[源代码][源代码]#
检查Fortran 90编译器的可用性.
在源生成函数内部使用它,以确保已初始化设置分发实例.
备注
如果一个 Fortran 90 编译器可用(因为一个简单的 Fortran 90 代码能够成功编译),则为真
- get_version(version_file=None, version_variable=None)[源代码][源代码]#
尝试获取一个包的版本字符串.
返回当前包的版本字符串,如果无法检测到版本信息,则返回 None.
备注
此方法扫描名为 __version__.py、<packagename>_version.py、version.py 和 __svn_version__.py 的文件,查找字符串变量 version、__version__ 和 <packagename>_version,直到找到版本号.
- make_svn_version_py(delete=True)[源代码][源代码]#
将一个数据函数附加到 data_files 列表中,该函数将在当前包目录中生成 __svn_version__.py 文件.
从SVN修订号生成包 __svn_version__.py 文件,它将在python退出后被删除,但在执行sdist等命令时将可用.
备注
如果 __svn_version__.py 之前存在,则什么也不做.
这是用于处理位于 SVN 仓库中的源目录.
构建可安装的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库#
信息可以很容易地从 numpy.distutils.misc_util
中的 get_info
函数中检索到:
>>> 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 文件.