使用 Python 安装 header-only 库
Install header-only library with Python
我有一个 header-only C++ 库用于我的 Python 扩展。我希望能够将它们安装到 Python 的包含路径,这样我就可以很容易地使用 python3 setup.py build
编译扩展。我部分能,但有两件事我无法工作(见下文):
如何使用 python3 setup.py install
安装 header 文件?目前我只得到一些 *.egg
文件,但没有安装 headers。
如何保留模块的文件结构?当前文件结构被错误地扁平化。
什么有效
与以下setup.py
from setuptools import setup
setup(
name = 'so',
description = 'Example',
headers = [
'so.h',
],
)
我可以将模块上传到 PyPi:
python3 setup.py bdist_wheel --universal
twine upload dist/*
然后使用 pip 安装:
pip3 install so
在我的系统上,然后我在此处找到 header
/usr/local/include/python3.6m/so/so.h
当我使用 Python.
编译扩展时可用
如何使用'python3 setup.py install'?
使用这个策略我不能简单地 运行
python3 setup.py install
在那种情况下,安装了一些 so*.egg
,但 header 没有存储在编译器可用的地方。
如何保留文件结构?
当模块有点复杂,并且有一些目录层次我也运行问题。对于以下 setup.py
from setuptools import setup
setup(
name = 'so',
description = 'Example',
headers = [
'so.h',
'so/implementation.h',
],
)
问题是 header 被安装到
/usr/local/include/python3.6m/so/so.h
/usr/local/include/python3.6m/so/implementation.h
从而扁平化原始文件结构。
如何解决这两个问题?
How can I use python3 setup.py install
to install the header files?
不幸的是,只要您正在使用 setuptools
,就不能。当您调用 setuptools.setup()
时,幕后会发生什么?正在构建一个 egg 安装程序(bdist_egg
命令)并安装(通过 easy_install
),bdist_egg
和 easy_install
都不支持 including/installing headers .虽然 distribution
object 携带 headers 信息,但在 install
命令期间从未请求过。这是一个从未解决的老 well-known 问题,因为显然 header 文件的安装不适合 egg build/install 过程。
因此你有三个选项(或者至少我知道的三个选项)。不推荐其中两个(都导致切换到 distutils
),仅出于完整性考虑提供:
裸 distutils
安装(不推荐)
$ sed 's/from setuptools import setup/from distutils.core import setup/' setup.py
这样,好的 ol'distutils
将在执行 python setup.py install
时负责安装,不会构建 egg 安装程序并会调用 install_headers
。但是,这也包括放弃 setuptools
的所有功能,包括 setup()
中的附加关键字参数和所有其他好东西,不用说无法卸载通过 distutils
安装的软件包pip
.
old-and-unmanageable
安装(不推荐)
运行安装
$ python setup.py install --old-and-unmanageable
如果您明确希望 运行 安装 distutils
,这是 setuptools
提供的开关。未构建 egg 安装程序,而是调用 distutils.command.install.install
。因此,安装与裸 distutils
安装相同。
这种方法的缺点:与裸机相同 distutils
安装加上:setuptools
谴责开关的使用;如果忘记提供,则以安装 egg 结束,必须重新安装。
将python setup.py install
替换为pip install
(推荐)
pip
能够从源目录安装包;刚刚发布
$ pip install dir/
假设 dir
包含 setup.py
。这样,一个 wheel 文件是从源代码构建的(与 bdist_wheel
相同;实际上,这个命令首先被 运行 执行)并安装,管理 header 文件的安装就好了。
How can I retain the module's file structure?
您需要稍微调整 install_headers
命令:
import os
from distutils.command.install_headers import install_headers as install_headers_orig
from setuptools import setup
class install_headers(install_headers_orig):
def run(self):
headers = self.distribution.headers or []
for header in headers:
dst = os.path.join(self.install_dir, os.path.dirname(header))
self.mkpath(dst)
(out, _) = self.copy_file(header, dst)
self.outfiles.append(out)
setup(
name='so',
headers=['h1.h', 'subtree/h2.h'],
cmdclass={'install_headers': install_headers},
...
)
这里最重要的是行
dst = os.path.join(self.install_dir, os.path.dirname(header))
香草install_headers
copies the header files directly to install_dir
;重载 install_headers
命令中的上述行还额外处理 header 文件名中的最终子目录。安装包时,现在要保留子目录:
$ pip show -f so | grep include
../../../include/site/python3.6/so/h1.h
../../../include/site/python3.6/so/subtree/h2.h
我有一个 header-only C++ 库用于我的 Python 扩展。我希望能够将它们安装到 Python 的包含路径,这样我就可以很容易地使用 python3 setup.py build
编译扩展。我部分能,但有两件事我无法工作(见下文):
如何使用
python3 setup.py install
安装 header 文件?目前我只得到一些*.egg
文件,但没有安装 headers。如何保留模块的文件结构?当前文件结构被错误地扁平化。
什么有效
与以下setup.py
from setuptools import setup
setup(
name = 'so',
description = 'Example',
headers = [
'so.h',
],
)
我可以将模块上传到 PyPi:
python3 setup.py bdist_wheel --universal
twine upload dist/*
然后使用 pip 安装:
pip3 install so
在我的系统上,然后我在此处找到 header
/usr/local/include/python3.6m/so/so.h
当我使用 Python.
编译扩展时可用如何使用'python3 setup.py install'?
使用这个策略我不能简单地 运行
python3 setup.py install
在那种情况下,安装了一些 so*.egg
,但 header 没有存储在编译器可用的地方。
如何保留文件结构?
当模块有点复杂,并且有一些目录层次我也运行问题。对于以下 setup.py
from setuptools import setup
setup(
name = 'so',
description = 'Example',
headers = [
'so.h',
'so/implementation.h',
],
)
问题是 header 被安装到
/usr/local/include/python3.6m/so/so.h
/usr/local/include/python3.6m/so/implementation.h
从而扁平化原始文件结构。
如何解决这两个问题?
How can I use
python3 setup.py install
to install the header files?
不幸的是,只要您正在使用 setuptools
,就不能。当您调用 setuptools.setup()
时,幕后会发生什么?正在构建一个 egg 安装程序(bdist_egg
命令)并安装(通过 easy_install
),bdist_egg
和 easy_install
都不支持 including/installing headers .虽然 distribution
object 携带 headers 信息,但在 install
命令期间从未请求过。这是一个从未解决的老 well-known 问题,因为显然 header 文件的安装不适合 egg build/install 过程。
因此你有三个选项(或者至少我知道的三个选项)。不推荐其中两个(都导致切换到 distutils
),仅出于完整性考虑提供:
裸 distutils
安装(不推荐)
$ sed 's/from setuptools import setup/from distutils.core import setup/' setup.py
这样,好的 ol'distutils
将在执行 python setup.py install
时负责安装,不会构建 egg 安装程序并会调用 install_headers
。但是,这也包括放弃 setuptools
的所有功能,包括 setup()
中的附加关键字参数和所有其他好东西,不用说无法卸载通过 distutils
安装的软件包pip
.
old-and-unmanageable
安装(不推荐)
运行安装
$ python setup.py install --old-and-unmanageable
如果您明确希望 运行 安装 distutils
,这是 setuptools
提供的开关。未构建 egg 安装程序,而是调用 distutils.command.install.install
。因此,安装与裸 distutils
安装相同。
这种方法的缺点:与裸机相同 distutils
安装加上:setuptools
谴责开关的使用;如果忘记提供,则以安装 egg 结束,必须重新安装。
将python setup.py install
替换为pip install
(推荐)
pip
能够从源目录安装包;刚刚发布
$ pip install dir/
假设 dir
包含 setup.py
。这样,一个 wheel 文件是从源代码构建的(与 bdist_wheel
相同;实际上,这个命令首先被 运行 执行)并安装,管理 header 文件的安装就好了。
How can I retain the module's file structure?
您需要稍微调整 install_headers
命令:
import os
from distutils.command.install_headers import install_headers as install_headers_orig
from setuptools import setup
class install_headers(install_headers_orig):
def run(self):
headers = self.distribution.headers or []
for header in headers:
dst = os.path.join(self.install_dir, os.path.dirname(header))
self.mkpath(dst)
(out, _) = self.copy_file(header, dst)
self.outfiles.append(out)
setup(
name='so',
headers=['h1.h', 'subtree/h2.h'],
cmdclass={'install_headers': install_headers},
...
)
这里最重要的是行
dst = os.path.join(self.install_dir, os.path.dirname(header))
香草install_headers
copies the header files directly to install_dir
;重载 install_headers
命令中的上述行还额外处理 header 文件名中的最终子目录。安装包时,现在要保留子目录:
$ pip show -f so | grep include
../../../include/site/python3.6/so/h1.h
../../../include/site/python3.6/so/subtree/h2.h