Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use standard Python tool to build snowboy #326

Closed
hongquan opened this issue Aug 12, 2018 · 7 comments
Closed

Use standard Python tool to build snowboy #326

hongquan opened this issue Aug 12, 2018 · 7 comments
Assignees

Comments

@hongquan
Copy link
Member

This issue is to track what I'm doing to improve snowboy's setup.py.

Motivation:

  • We want to pre-build snowboy to wheel package, to simplify installation of susi_linux, and to reduce image size (won't have to install a lot of stuff for building snowboy from source).
  • snowboy's original setup.py doesn't use native Python tool (distutils, setuptools) to build the C++ source. It's setup.py instead runs make to do the job. The consequence is that the generated wheel package has wrong filename and cannot be distributed.
@hongquan hongquan self-assigned this Aug 12, 2018
@hongquan
Copy link
Member Author

I already fork snowboy to https://github.com/fossasia/snowboy and working there.

With the setup.py like this

import os
import sys
from setuptools import setup, find_packages, Extension
from distutils.command.build import build


py_dir = 'Python' if sys.version_info[0] < 3 else 'Python3'

class SnowboyBuild(build):
    # Reorder build commands such that swig generated files are also copied.
    sub_commands = [('build_ext', build.has_ext_modules),
                    ('build_py', build.has_pure_modules),
                    ('build_clib', build.has_c_libraries),
                    ('build_scripts', build.has_scripts)]

ext = Extension(
    '_snowboydetect',
    ['swig/Python3/snowboy-detect-swig.i'],
    swig_opts=['-c++'],
    include_dirs=['.'],
)

setup(
    name='snowboy',
    version='1.3.0',
    description='Snowboy is a customizable hotword detection engine',
    maintainer='KITT.AI',
    maintainer_email='[email protected]',
    license='Apache-2.0',
    url='https://snowboy.kitt.ai',
    ext_modules=[ext],
    packages=find_packages(os.path.join('examples', py_dir)),
    package_dir={'snowboy': os.path.join('examples', py_dir)},
    py_modules=['snowboy.snowboydecoder', 'snowboy.snowboydetect'],
    # include_package_data=True,
    package_data={'snowboy': ['resources/*']},
    zip_safe=False,
    long_description="",
    classifiers=[],
    install_requires=[
        'PyAudio',
    ],
    cmdclass={
        'build': SnowboyBuild
    }
)

I can make setuptools build the C++ source code, without calling make. But the problem now is, setuptools doesn't including data files under resources folder in the result package.

@hongquan hongquan changed the title Use Python tool to build snowboy Use standard Python tool to build snowboy Aug 12, 2018
@hongquan
Copy link
Member Author

hongquan commented Aug 12, 2018

Found the cause:

The project layout is like this (listing only Python files and resources folder):

+-- examples/
    +-- Python3/
         +-- snowboydecoder.py
         +-- snowboydetect.py
         +-- resources/ (symlink)
+-- swig/
+-- resources/
+-- setup.py

And with the setup() written like this:

setup(
    packages=find_packages(os.path.join('examples', py_dir)),
    package_dir={'snowboy': os.path.join('examples', py_dir)},
    py_modules=['snowboy.snowboydecoder', 'snowboy.snowboydetect'],
    package_data={'snowboy': ['resources/*']},
)

the find_packages() will not able to find the Python package under examples/Python3, and this makes the package_data parameter fail.

My discovery is that, the path passed to find_packages has to be a folder which contains a snowboy package, like this, to make it work:

path/
    +-- snowboy
        +-- __init__.py
        +-- snowboydecoder.py

@hongquan
Copy link
Member Author

Working in this branch: https://github.com/fossasia/snowboy/tree/feature/standard-Python-build

Can produce *.so file and include resources files now, but the *.so file is not not linked enough libraries yet.

@hongquan
Copy link
Member Author

hongquan commented Aug 12, 2018

This is the output of make:

swig -I../../ -c++ -python -o snowboy-detect-swig.cc snowboy-detect-swig.i
g++ -I/usr/include/python3.6m -I/usr/include/python3.6m  -Wno-unused-result -Wsign-compare -g -fdebug-prefix-map=/build/python3.6-EKG1lX/python3.6-3.6.5=. -specs=/usr/share/dpkg/no-pie-compile.specs -fstack-protector-strong -Wformat -Werror=format-security  -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I../../ -O3 -fPIC -D_GLIBCXX_USE_CXX11_ABI=0 -std=c++0x -c snowboy-detect-swig.cc
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
g++ -I../../ -O3 -fPIC -D_GLIBCXX_USE_CXX11_ABI=0 -std=c++0x  -shared snowboy-detect-swig.o \
../..//lib/ubuntu64/libsnowboy-detect.a -L/usr/lib/python3.6/config-3.6m-x86_64-linux-gnu -L/usr/lib -lpython3.6m -lpthread -ldl  -lutil -lm  -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions -lm -ldl -lf77blas -lcblas -llapack -latlas -o _snowboydetect.so

This is output of our current setup.py:

$ python3 setup.py build
running build
running build_py
creating build
creating build/lib.linux-x86_64-3.6
creating build/lib.linux-x86_64-3.6/snowboy
copying examples/Python3/snowboy/__init__.py -> build/lib.linux-x86_64-3.6/snowboy
copying examples/Python3/snowboy/snowboydecoder.py -> build/lib.linux-x86_64-3.6/snowboy
copying examples/Python3/snowboy/snowboydetect.py -> build/lib.linux-x86_64-3.6/snowboy
creating build/lib.linux-x86_64-3.6/snowboy/resources
copying examples/Python3/snowboy/resources/dong.wav -> build/lib.linux-x86_64-3.6/snowboy/resources
copying examples/Python3/snowboy/resources/common.res -> build/lib.linux-x86_64-3.6/snowboy/resources
copying examples/Python3/snowboy/resources/snowboy.raw -> build/lib.linux-x86_64-3.6/snowboy/resources
copying examples/Python3/snowboy/resources/ding.wav -> build/lib.linux-x86_64-3.6/snowboy/resources
copying examples/Python3/snowboy/resources/snowboy.wav -> build/lib.linux-x86_64-3.6/snowboy/resources
running build_ext
building '_snowboydetect' extension
swigging swig/Python3/snowboy-detect-swig.i to swig/Python3/snowboy-detect-swig_wrap.cpp
swig -python -c++ -o swig/Python3/snowboy-detect-swig_wrap.cpp swig/Python3/snowboy-detect-swig.i
creating build/temp.linux-x86_64-3.6
creating build/temp.linux-x86_64-3.6/swig
creating build/temp.linux-x86_64-3.6/swig/Python3
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fdebug-prefix-map=/build/python3.6-EKG1lX/python3.6-3.6.5=. -specs=/usr/share/dpkg/no-pie-compile.specs -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I. -I/usr/include/python3.6m -c swig/Python3/snowboy-detect-swig_wrap.cpp -o build/temp.linux-x86_64-3.6/swig/Python3/snowboy-detect-swig_wrap.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
x86_64-linux-gnu-g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -specs=/usr/share/dpkg/no-pie-link.specs -Wl,-z,relro -Wl,-Bsymbolic-functions -specs=/usr/share/dpkg/no-pie-link.specs -Wl,-z,relro -g -fdebug-prefix-map=/build/python3.6-EKG1lX/python3.6-3.6.5=. -specs=/usr/share/dpkg/no-pie-compile.specs -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 build/temp.linux-x86_64-3.6/swig/Python3/snowboy-detect-swig_wrap.o -o build/lib.linux-x86_64-3.6/_snowboydetect.cpython-36m-x86_64-linux-gnu.so

To produce correct *.so file, our script must produce compiler command with the same parameter as make.

Currently, the content of files generated by swig, from snowboy-detect-swig.i are already the same.

@hongquan
Copy link
Member Author

Successfully fix the setup.py and build wheel files for armv7, x86_64 (uploaded to https://repo.fury.io/fossasia/). Waiting for friend to test on Mac OSX before making a pull request to upstream.

@hongquan
Copy link
Member Author

Made Pull Request to upstream here: Kitt-AI/snowboy#493

@hongquan
Copy link
Member Author

I don't know when the Kiit-AI will review and accept the PR. But because it has been done and the wheel packages have been built, I'm closing this issue now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant