问题描述
我有一个Python模块,它是用C编写的本机扩展构建的。此扩展包括使用GNU Bison和(不是GNU)Flex工具生成的代码。这意味着我的C扩展程序的构建过程包括调用这些工具,然后将其输出(C源文件)包括在扩展程序源中。
为使此功能在调用python setup.py install
时起作用,我扩展了setuptools.command.build_ext
类以同时调用Flex和Bison,然后在调用超类run方法之前将生成的源添加到Extension源。 / p>
这意味着我的setup.py如下:
import os
from setuptools import setup,Extension
from setuptools.command.build_ext import build_ext
c_extension = Extension('_mymod',include_dirs = ['inc'],sources = [
os.path.join('src','lib.c'),os.path.join('src','etc.c')
])
class MyBuild(build_ext):
def run(self):
parser_dir = os.path.join(self.build_temp,'parser')
# add the parser directory to include_dirs
self.include_dirs.append(parser_dir)
# add the source files to the sources
self.extensions[0].sources.extend([os.path.join(parser_dir,'lex.yy.c'),os.path.join(parser_dir,'parse.tab.c')])
# honor the --dry-run flag
if not self.dry_run:
self.mkpath(parser_dir)
os.system('flex -o ' + os.path.join(parser_dir,'lex.yy.c') + ' ' + os.path.join('src','lex.l'))
os.system('bison -d -o ' + os.path.join(parser_dir,'parse.tab.c') + ' ' + os.path.join('src','parse.y'))
# call the super class method
return build_ext.run(self)
setup (name = 'MyMod',version = '0.1',description = 'A module that uses external code generation tools',author = 'Sean Kauffman',packages = ['MyMod'],ext_modules = [c_extension],cmdclass={'build_ext': MyBuild},python_requires='>=3',zip_safe=False)
但是,现在,我正在尝试打包此模块以进行分发,但是我遇到了问题。想要安装我的软件包的用户需要安装Bison和Flex,或者在构建源发行版时需要运行这些工具。我看到两种可能的解决方案:
- 我确认flex和bison位于系统执行路径中。这将使定制构建器保持原样。我没有找到任何文件可以暗示我可以验证系统文件是否像bison和flex一样存在。最接近的是使用扩展程序的
libraries
字段,但是似乎我需要真正的黑客才能检查整个PATH以查找可执行文件。我还没有尝试过,因为我的第一选择是选项2。 - 我将代码生成移到创建源分发时发生。这意味着源代码发行版将包含bison和flex的输出文件,因此安装该软件包的人员不需要这些工具。这似乎是更清洁的选择。我已经尝试扩展
sdist
命令而不是像上面的build_ext
扩展,但是目前尚不清楚如何将生成的文件添加到清单中,以便将它们包括在内。此外,我想确保它仍然可以使用python setup.py install
进行构建,但是我认为该命令在构建之前不会运行sdist。
任何解决方案都只能在Linux和OS X上运行是很好的。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)