Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
282 views
in Technique[技术] by (71.8m points)

python - Change Cython's naming rules for .so files

I'm using Cython to generate a shared object out of Python module. The compilation output is written to build/lib.linux-x86_64-3.5/<Package>/<module>.cpython-35m-x86_64-linux-gnu.so. Is there any option to change the naming rule? I want the file to be named <module>.so without the interpreter version or arch appendix.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Seems like setuptools provides no option to change or get rid of the suffix completely. The magic happens in 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

Seems like I will need to add a post-build renaming action.


Update from 08/12/2016:

Ok, I forgot to actually post the solution. Actually, I implemented a renaming action by overloading the built-in install_lib command. Here's the logic:

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]

Now all you have to do is to overload the command in the setup function:

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

Still, I'm not happy with overloading standard commands; if you find a better solution, post it and I will accept your answer.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...