Added debian package
This commit is contained in:
+5
-1
@@ -71,4 +71,8 @@ etc/test/pt/original/
|
||||
etc/test/vi/2*
|
||||
|
||||
# Misc
|
||||
workbench.xmi
|
||||
workbench.xmi
|
||||
|
||||
# Debian
|
||||
site/
|
||||
debian/rhasspy-server*
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
Package: rhasspy-server
|
||||
Version: 2.4.8
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Depends: sox,alsa-utils,espeak,libstdc++6,jq,xz-utils,unzip,curl,sphinxbase-utils,sphinxtrain,flite,libatlas-base-dev,gfortran
|
||||
Architecture: ${architecture}
|
||||
Maintainer: Michael Hansen
|
||||
Description: Offline voice assistant
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [[ -z "${RHASSPY_BASE_DIR}" ]]; then
|
||||
export RHASSPY_BASE_DIR="/usr/lib/rhasspy"
|
||||
fi
|
||||
|
||||
if [[ -z "${KALDI_PREFIX}" ]]; then
|
||||
export KALDI_PREFIX="${RHASSPY_BASE_DIR}"
|
||||
fi
|
||||
|
||||
cd "${RHASSPY_BASE_DIR}" && rhasspy/rhasspy "$@"
|
||||
Executable
+177
@@ -0,0 +1,177 @@
|
||||
#!/usr/bin/env bash
|
||||
rhasspy_version="2.4.8"
|
||||
|
||||
this_dir="$( cd "$( dirname "$0" )" && pwd )"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Command-line Arguments
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
. "${this_dir}/etc/shflags"
|
||||
|
||||
DEFINE_string 'architecture' '' 'Debian architecture'
|
||||
DEFINE_string 'version' "${rhasspy_version}" 'Package version'
|
||||
DEFINE_boolean 'package' true 'Create debian package (.deb)'
|
||||
|
||||
FLAGS "$@" || exit $?
|
||||
eval set -- "${FLAGS_ARGV}"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Settings
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
export architecture="${FLAGS_architecture}"
|
||||
version="${FLAGS_version}"
|
||||
debian_dir="${this_dir}/debian"
|
||||
|
||||
set -e
|
||||
|
||||
if [[ -z "${architecture}" ]]; then
|
||||
# Guess architecture
|
||||
architecture="$(dpkg-architecture | grep 'DEB_BUILD_ARCH=' | sed 's/^[^=]\+=//')"
|
||||
fi
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Activate virtual environment
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
venv="${this_dir}/.venv"
|
||||
|
||||
if [[ ! -d "${venv}" ]]; then
|
||||
echo "Missing virtual environment at ${venv}"
|
||||
echo "Did you run create-venv.sh?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "${this_dir}"
|
||||
source "${venv}/bin/activate"
|
||||
|
||||
if [[ -z "$(which pyinstaller)" ]]; then
|
||||
echo "Missing PyInstaller"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Run PyInstaller
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
echo "Running PyInstaller"
|
||||
package_name="rhasspy-server_${version}_${architecture}"
|
||||
package_dir="${debian_dir}/${package_name}"
|
||||
output_dir="${package_dir}/usr/lib/rhasspy"
|
||||
share_dir="${package_dir}/usr/share/rhasspy"
|
||||
|
||||
pyinstaller\
|
||||
-y \
|
||||
--workpath "pyinstaller/build" \
|
||||
--distpath "${output_dir}" \
|
||||
"${this_dir}/rhasspy.spec"
|
||||
|
||||
# Remove all symbols (Liantian warning)
|
||||
strip --strip-all "${output_dir}/rhasspy"/*.so* || true
|
||||
|
||||
# Remove executable bit from shared libs (Lintian warning)
|
||||
chmod -x "${output_dir}/rhasspy"/*.so* || true
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copy Rhasspy
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# Profiles
|
||||
mkdir -p "${output_dir}/profiles"
|
||||
rsync -av \
|
||||
--delete \
|
||||
--exclude 'acoustic_model' \
|
||||
--exclude 'download' \
|
||||
--exclude 'flair' \
|
||||
--exclude 'base_dictionary.txt' \
|
||||
--exclude 'base_language_model.txt' \
|
||||
--exclude 'g2p.fst' \
|
||||
--exclude 'HCLG.fst' \
|
||||
--exclude 'final.mdl' \
|
||||
--exclude '*.umdl' \
|
||||
"${this_dir}/profiles/" \
|
||||
"${output_dir}/profiles/"
|
||||
|
||||
# Sounds
|
||||
mkdir -p "${output_dir}/etc/wav"
|
||||
rsync -av \
|
||||
--delete \
|
||||
"${this_dir}/etc/wav/" \
|
||||
"${output_dir}/etc/wav/"
|
||||
|
||||
# Web
|
||||
mkdir -p "${output_dir}/dist"
|
||||
rsync -av \
|
||||
--delete \
|
||||
"${this_dir}/dist/" \
|
||||
"${output_dir}/dist/"
|
||||
|
||||
# Documentation
|
||||
mkdocs build
|
||||
mkdir -p "${share_dir}/docs"
|
||||
rsync -av \
|
||||
--delete \
|
||||
"${this_dir}/site/" \
|
||||
"${share_dir}/docs/"
|
||||
|
||||
# Source code
|
||||
mkdir -p "${share_dir}/src"
|
||||
rsync -av \
|
||||
--delete \
|
||||
--exclude '.mypy_cache' \
|
||||
--exclude '__pycache__' \
|
||||
"${this_dir}/rhasspy/" \
|
||||
"${share_dir}/src/rhasspy/"
|
||||
|
||||
cp "${this_dir}/app.py" "${share_dir}/src/"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copy Kaldi
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
echo "Copying Kaldi"
|
||||
kaldi_src="${venv}/kaldi"
|
||||
if [[ ! -d "${kaldi_src}" ]]; then
|
||||
echo "Missing Kaldi at ${kaldi_src}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
kaldi_dest="${output_dir}/kaldi"
|
||||
mkdir -p "${kaldi_dest}"
|
||||
rsync -av --delete "${kaldi_src}/" "${kaldi_dest}/"
|
||||
|
||||
# Avoid link recursion
|
||||
rm -f "${kaldi_dest}/egs/wsj/s5/utils/utils"
|
||||
|
||||
# Turn duplicate .so files into symbolic links
|
||||
function fix_library_links() {
|
||||
lib_dir="$1"
|
||||
|
||||
for lib in "${lib_dir}"/*.so; do
|
||||
lib_base="$(basename ${lib})"
|
||||
for lib_link in "${lib_dir}/${lib_base}".*; do
|
||||
rm -f "${lib_link}"
|
||||
ln -s "${lib_base}" "${lib_link}"
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
fix_library_links "${kaldi_dest}/tools/openfst/lib"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Create Debian package
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
echo "Creating Debian package"
|
||||
mkdir -p "${package_dir}/DEBIAN"
|
||||
cat "${debian_dir}/DEBIAN/control" | \
|
||||
envsubst > "${package_dir}/DEBIAN/control"
|
||||
|
||||
mkdir -p "${package_dir}/usr/bin"
|
||||
cp "${debian_dir}/bin/rhasspy-server" "${package_dir}/usr/bin/"
|
||||
|
||||
if [[ "${FLAGS_package}" -eq "${FLAGS_TRUE}" ]]; then
|
||||
# Actually build the package
|
||||
cd 'debian' && fakeroot dpkg --build "${package_name}"
|
||||
fi
|
||||
@@ -0,0 +1,84 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
import os
|
||||
import platform
|
||||
from pathlib import Path
|
||||
|
||||
from PyInstaller.utils.hooks import copy_metadata
|
||||
|
||||
block_cipher = None
|
||||
|
||||
# Use either virtual environment or lib/bin dirs from environment variables
|
||||
venv = Path.cwd() / ".venv"
|
||||
bin_dir = Path(os.environ.get("spec_bin_dir", venv / "bin"))
|
||||
lib_dir = Path(os.environ.get("spec_lib_dir", venv / "lib"))
|
||||
|
||||
site_dir = os.environ.get("spec_site_dir", None)
|
||||
if site_dir is None:
|
||||
venv_lib = venv / "lib"
|
||||
for dir_path in venv_lib.glob("python*"):
|
||||
if dir_path.is_dir() and (dir_path / "site-packages").exists():
|
||||
site_dir = dir_path / "site-packages"
|
||||
break
|
||||
|
||||
assert site_dir is not None, "Missing site-packages directory"
|
||||
site_dir = Path(site_dir)
|
||||
|
||||
# Need to specially handle these snowflakes
|
||||
pywrapfst_path = list(site_dir.glob("pywrapfst.*.so"))[0]
|
||||
webrtcvad_path = list(site_dir.glob("_webrtcvad.*.so"))[0]
|
||||
|
||||
a = Analysis(
|
||||
["app.py"],
|
||||
pathex=["."],
|
||||
binaries=[
|
||||
(pywrapfst_path, "."),
|
||||
(webrtcvad_path, "."),
|
||||
(lib_dir / "libfstfarscript.so.13", "."),
|
||||
(lib_dir / "libfstscript.so.13", "."),
|
||||
(lib_dir / "libfstfar.so.13", "."),
|
||||
(lib_dir / "libfst.so.13", "."),
|
||||
(lib_dir / "libngram.so.134", "."),
|
||||
(bin_dir / "ngramread", "."),
|
||||
(bin_dir / "ngramcount", "."),
|
||||
(bin_dir / "ngrammake", "."),
|
||||
(bin_dir / "ngrammerge", "."),
|
||||
(bin_dir / "ngramprint", "."),
|
||||
(bin_dir / "ngramsymbols", "."),
|
||||
(bin_dir / "ngramperplexity", "."),
|
||||
(bin_dir / "farcompilestrings", "."),
|
||||
(bin_dir / "phonetisaurus-apply", "."),
|
||||
(bin_dir / "phonetisaurus-g2pfst", "."),
|
||||
],
|
||||
datas=copy_metadata("webrtcvad"),
|
||||
hiddenimports=["doit", "dbm.gnu", "networkx", "numbers"],
|
||||
hookspath=[],
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False,
|
||||
)
|
||||
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
[],
|
||||
exclude_binaries=True,
|
||||
name="rhasspy",
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
console=True,
|
||||
)
|
||||
coll = COLLECT(
|
||||
exe,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
name="rhasspy",
|
||||
)
|
||||
@@ -465,6 +465,15 @@ def train_profile(profile_dir: Path, profile: Profile) -> Tuple[int, List[str]]:
|
||||
|
||||
DOIT_CONFIG = {"action_string_formatting": "old", "reporter": MyReporter}
|
||||
|
||||
# Monkey patch inspect to make doit work inside Pyinstaller.
|
||||
# It grabs the line numbers of functions probably for debugging reasons, but
|
||||
# PyInstaller doesn't seem to keep that information around.
|
||||
#
|
||||
# This better thing to do would be to create a custom TaskLoader.
|
||||
import inspect
|
||||
|
||||
inspect.getsourcelines = lambda obj: [0, 0]
|
||||
|
||||
# Run doit main
|
||||
result = DoitMain(ModuleTaskLoader(locals())).run(sys.argv[1:])
|
||||
return (result, errors)
|
||||
|
||||
Reference in New Issue
Block a user