我正在尝试从SLES12 SP2上的Python应用程序创建RPM。这是我的setup.py文件:
import setuptools
setuptools.setup(name='MyApp',
version='1.2.3',
options={'bdist_rpm': {'post_install': 'post_install.sh',
'post_uninstall': 'post_uninstall.sh'}})
没什么特别的。
正在运行python setup.py bdist_rpm
。但是,运行python3 setup.py bdist_rpm
会执行以下操作:
running bdist_rpm
running egg_info
writing top-level names to MyApp.egg-info/top_level.txt
...
byte-compiling /home/pedro/MyApp/build/bdist.linux-x86_64/rpm/BUILDROOT/MyApp-1.2.3-1.x86_64/usr/lib/python3.4/site-packages/MyApp/my_file.py to my_file.cpython-34.pyc
...
Processing files: MyApp-1.2.3-1.noarch
error: File not found: /home/pedro/MyApp/build/bdist.linux-x86_64/rpm/BUILDROOT/MyApp-1.2.3-1.x86_64/usr/lib/python3.4/site-packages/MyApp/my_file.py
RPM build errors:
File not found: /home/pedro/MyApp/build/bdist.linux-x86_64/rpm/BUILDROOT/MyApp-1.2.3-1.x86_64/usr/lib/python3.4/site-packages/MyApp/my_file.py
error: command 'rpmbuild' failed with exit status 1
问题似乎是setuptools生成的文件以.cpython-34.pyc
结尾,后来查找的文件没有.cpython-34
但无法找到。
Python 3上的RPM生成过程经历distutils.util.byte_compile()
,后者又调用importlib.util.cache_from_source(path)
,其中path
是要进行字节编译的文件。 cache_from_source()
看起来像这样(缩写):
def cache_from_source(path, debug_override=None, *, optimization=None):
path = _os.fspath(path)
head, tail = _path_split(path)
base, sep, rest = tail.rpartition('.')
tag = sys.implementation.cache_tag
if tag is None:
raise NotImplementedError('sys.implementation.cache_tag is None')
almost_filename = ''.join([(base if base else rest), sep, tag])
optimization = str(optimization)
if optimization != '':
almost_filename = '{}.{}{}'.format(almost_filename, _OPT, optimization)
return _path_join(head, _PYCACHE, almost_filename + BYTECODE_SUFFIXES[0])
sys.implementation.cache_tag
的值为'cpython-34'
。 Python {2}中不存在sys
的这个属性。所以看起来setuptools
在字节编译期间将此标记注入到文件名中,但后来忘记它修改了文件名而失败了,因为它是寻找原来的名字。
我怎么能:
setuptools
(或rpmbuild
;不确定哪个人正在搜索原始文件名)在搜索的文件名中是否一致? This question建议在spec文件中完全禁用字节编译,但我正在寻找一种只用直接python3 setup.py bdist_rpm --maybe-some-other-parameters
命令生成RPM的方法。