使用distutils为Python扩展构建RPM时的相对包含路径
我正在使用 Python 2.6,想要为一个 Python 的 C 扩展模块构建一个 RPM 包。
我用的 setup.py
文件大概是这样的:
from distutils.core import setup, Extension
foo_ext = Extension('foo',
sources=['foo.c', '../src/common.c'],
include_dirs=['../includes'])
setup(... , ext_modules=[foo_ext])
比如说,如果我在 /devel/foo
目录下运行 python setup.py build
,它会顺利编译和构建,没有任何错误,而且 gcc
也会用正确的路径调用,也就是:
gcc ... -I/devel/includes ...
但是当我用 python setup.py bdist_rpm
的时候,上面用的相对路径会变成相对于 RPM 构建目录的绝对路径,这样就导致 gcc
尝试用以下路径来编译:
gcc ... -I/devel/foo/build/bdist.linux-x86_64/rpm/BUILD/includes ...
结果编译失败,因为找不到一个必需的 .h
文件在包含路径中。
有没有什么建议或者解决办法呢?
2 个回答
0
我之前遇到过类似的问题,解决办法是给 distutils 提供一个合适的 MANIFEST.in
文件,这个文件列出了我想要包含的所有头文件。在我的情况下,它是这样的:
include src/_rvlm_fdtd/include/rvlm/fdtd/* –or–
recursive-include src/_rvlm_fdtd *.h
不过我觉得这个方法可能不适用于你的 ../
路径。相反,我建议你把所有的源代码放在一个包的基础目录里。
RPM 构建阶段找不到你的头文件的原因是,它首先会构建一个源代码分发包(使用 setup.py sdist
),然后把生成的压缩包解压到一个临时的构建目录里。所以你的源代码分发包里根本没有包含构建所需的所有文件。
2
通过在脚本第一次运行时设置一个环境变量,解决了这个问题。然后在构建RPM时再次读取这个变量:
import os
from distutils.core import setup, Extension
src_path = os.path.abspath('../src/common.c')
inc_path = os.path.abspath('../includes')
if 'SRC_PATH' not in os.environ:
os.environ['SRC_PATH'] = src_path
os.environ['INC_PATH'] = inc_path
else:
src_path = os.environ['SRC_PATH']
inc_path = os.environ['INC_PATH']
foo_ext = Extension('foo',
sources=['foo.c', src_path],
include_dirs=[inc_path])
setup(... , ext_modules=[foo_ext])