2016-07-22 49 views
5

Używam Cythona do generowania obiektu współdzielonego z modułu Pythona. Dane wyjściowe kompilacji są zapisywane pod numerem build/lib.linux-x86_64-3.5/<Package>/<module>.cpython-35m-x86_64-linux-gnu.so. Czy jest jakaś możliwość zmiany reguły nazewnictwa? Chcę plik o nazwie <module>.so bez wersji tłumacza lub dodatku arch.Zmiana zasad nazewnictwa Cythona dla plików .so

+0

powinien być taki sam jak setuptools budować opcji, można znajdź go w python setup.py --help – YOU

+0

@YO U: Dzięki, zdołałem przesłonić katalogi kompilacji/lib/temp, ale nie widzę niczego związanego z sufiksem platformy itp. – hoefling

+0

'python setup.py build --build-platlib.' – YOU

Odpowiedz

4

Wygląda na to, że setuptools nie daje żadnej możliwości zmiany lub całkowitego usunięcia sufiksu. Magia dzieje się w 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 

Wygląda na to będę musiał dodać post-build zmiana nazwy działania.


Aktualizacja z 08/12/2016:

Ok, zapomniałem faktycznie zakładać rozwiązanie. W rzeczywistości zaimplementowałem operację zmiany nazwy przez przeciążenie wbudowanego polecenia install_lib. Oto logika:

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] 

Teraz wszystko co musisz zrobić, to do przeciążenia komendy w funkcji setup:

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

Mimo, że nie jestem zadowolony z przeciążenia standardowych poleceń; jeśli znajdziesz lepsze rozwiązanie, opublikuj to, a ja przyjmuję twoją odpowiedź.

2

To zachowanie zostało zdefiniowane w pakiecie distutils. distutils wykorzystuje sysconfig i "EXT_SUFFIX" config zmiennej:

# 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 

zaczynające Pythonie 3.5 "EXT_SUFFIX" zmienna zawiera informacje platformy, na przykład”.cp35-win_amd64" .

Pisałem następującą funkcję:

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 

i niestandardowe build_ext polecenia:

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) 

Zastosowanie:

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

Twój kod pomógł mi. Dziękuję Ci! – q0987