【问题标题】:Change Cython's naming rules for .so files更改 Cython 的 .so 文件命名规则
【发布时间】:2016-11-26 05:01:47
【问题描述】:

我正在使用 Cython 从 Python 模块中生成一个共享对象。编译输出写入build/lib.linux-x86_64-3.5/<Package>/<module>.cpython-35m-x86_64-linux-gnu.so。是否有任何选项可以更改命名规则?我希望将文件命名为<module>.so,而不需要解释器版本或拱形附录。

【问题讨论】:

  • 应该和setuptools构建选项一样,可以在python setup.py --help中找到
  • @YOU:谢谢,我设法覆盖了 build/lib/temp 目录,但我没有看到任何与平台后缀等相关的内容。
  • python setup.py build --build-platlib .
  • 好像被忽略了……
  • 我知道这已经晚了,但后缀是there for good reasons。我看不出有什么好的理由删除它,我建议人们离开它而不是遵循这些答案中的建议。提供有关如何更改后缀的信息可能很有用,但没有人会认为这是个好主意。

标签: python cython setuptools


【解决方案1】:

解决方法很简单,在build_ext.py处改一行就行了

    def get_ext_filename(self, ext_name):

        from distutils.sysconfig import get_config_var
        ext_path = ext_name.split('.')
        ext_suffix = get_config_var('EXT_SUFFIX') 
        return os.path.join(*ext_path) + ext_suffix

ext_suffix = get_config_var('EXT_SUFFIX') 更改为 ext_suffix = ".so" 或 Windows 上的 ".pyd"

就是这样,你再也不用担心输出名称了

【讨论】:

  • 我试过这个,像这样:setup(ext_modules=cythonize("my_function.pyx"), include_dirs=[numpy.get_include()], ext_suffix=".pyd")。没用。
【解决方案2】:

此行为已在 distutils 包中定义。 distutils 使用 sysconfig 和 "EXT_SUFFIX" 配置变量:

# Lib\distutils\command\build_ext.py

def get_ext_filename(self, ext_name):
    r"""Convert the name of an extension (eg. "foo.bar") into the name
    of the file from which it will be loaded (eg. "foo/bar.so", or
    "foo\bar.pyd").
    """
    from distutils.sysconfig import get_config_var
    ext_path = ext_name.split('.')
    ext_suffix = get_config_var('EXT_SUFFIX')
    return os.path.join(*ext_path) + ext_suffix

从 Python 3.5 开始“EXT_SUFFIX”变量包含平台信息,例如“.cp35-win_amd64”。

我写了以下函数:

def get_ext_filename_without_platform_suffix(filename):
    name, ext = os.path.splitext(filename)
    ext_suffix = sysconfig.get_config_var('EXT_SUFFIX')

    if ext_suffix == ext:
        return filename

    ext_suffix = ext_suffix.replace(ext, '')
    idx = name.find(ext_suffix)

    if idx == -1:
        return filename
    else:
        return name[:idx] + ext

以及自定义build_ext命令:

from Cython.Distutils import build_ext

class BuildExtWithoutPlatformSuffix(build_ext):
    def get_ext_filename(self, ext_name):
        filename = super().get_ext_filename(ext_name)
        return get_ext_filename_without_platform_suffix(filename)

用法:

setup(
    ...
    cmdclass={'build_ext': BuildExtWithoutPlatformSuffix},
    ...
)

【讨论】:

    【解决方案3】:

    似乎setuptools 没有提供完全更改或删除后缀的选项。奇迹发生在distutils/command/build_ext.py

    def get_ext_filename(self, ext_name):
        from distutils.sysconfig import get_config_var
        ext_path = ext_name.split('.')
        ext_suffix = get_config_var('EXT_SUFFIX')
        return os.path.join(*ext_path) + ext_suffix
    

    看来我需要添加构建后重命名操作。


    2016 年 8 月 12 日更新:

    好的,我忘了实际发布解决方案。实际上,我通过重载内置的install_lib 命令实现了重命名操作。逻辑如下:

    from distutils.command.install_lib import install_lib as _install_lib
    
    def batch_rename(src, dst, src_dir_fd=None, dst_dir_fd=None):
        '''Same as os.rename, but returns the renaming result.'''
        os.rename(src, dst,
                  src_dir_fd=src_dir_fd,
                  dst_dir_fd=dst_dir_fd)
        return dst
    
    class _CommandInstallCythonized(_install_lib):
        def __init__(self, *args, **kwargs):
            _install_lib.__init__(self, *args, **kwargs)
    
        def install(self):
            # let the distutils' install_lib do the hard work
            outfiles = _install_lib.install(self)
            # batch rename the outfiles:
            # for each file, match string between
            # second last and last dot and trim it
            matcher = re.compile('\.([^.]+)\.so$')
            return [batch_rename(file, re.sub(matcher, '.so', file))
                    for file in outfiles]
    

    现在你要做的就是重载setup函数中的命令:

    setup(
        ...
        cmdclass={
            'install_lib': _CommandInstallCythonized,
        },
        ...
    )
    

    不过,我对重载标准命令并不满意;如果您找到更好的解决方案,请发布,我会接受您的回答。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      • 1970-01-01
      • 2012-03-23
      • 2018-11-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多