首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >更改Cython对.so文件的命名规则

更改Cython对.so文件的命名规则
EN

Stack Overflow用户
提问于 2016-07-22 10:18:51
回答 3查看 4.7K关注 0票数 17

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-07-22 11:35:47

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

代码语言:javascript
复制
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年08/12更新:

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

代码语言:javascript
复制
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函数中的命令:

代码语言:javascript
复制
setup(
    ...
    cmdclass={
        'install_lib': _CommandInstallCythonized,
    },
    ...
)

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

票数 13
EN

Stack Overflow用户

发布于 2016-10-22 14:01:00

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

代码语言:javascript
复制
# 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

从Python3.5 "EXT_SUFFIX“变量开始,包含平台信息,例如”.cp35-Win_amd64 64“。

我编写了以下函数:

代码语言:javascript
复制
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命令:

代码语言:javascript
复制
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)

用法:

代码语言:javascript
复制
setup(
    ...
    cmdclass={'build_ext': BuildExtWithoutPlatformSuffix},
    ...
)
票数 7
EN

Stack Overflow用户

发布于 2019-06-24 14:14:40

解决方案非常简单,只需将build_ext.py中的一行更改为

代码语言:javascript
复制
    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

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

仅此而已,您不必再担心输出名称了

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38523941

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档