Install this version:
emerge -a =app-local-ai/piper-4.9.0
If this version is masked, you can unmask it using the autounmask tool or standard emerge options:
autounmask =app-local-ai/piper-4.9.0
Or alternatively:
emerge --autounmask-write -a =app-local-ai/piper-4.9.0
| Version | EAPI | Keywords | Slot |
|---|---|---|---|
| 4.9.0 | 8 | ~amd64 | 0 |
# Copyright 2026 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# LocalAI text-to-speech backend: LocalAI's Go gRPC wrapper around go-piper,
# which builds the piper TTS engine with its phonemizer and the rhasspy fork
# of espeak-ng (vendored deliberately: the fork carries phonemization patches
# and provides the espeak-ng-data this backend ships). fmt/spdlog and
# onnxruntime come from the system.
EAPI=8
inherit go-module local-ai-backend multilib
# Pins. Source of truth: backend/go/piper/Makefile (PIPER_VERSION) at the
# LocalAI release tag; the three below it are go-piper's submodule gitlinks
# at that commit.
GOPIPER_COMMIT="e10ca041a885d4a8f3871d52924b47792d5e5aa0"
PIPER_COMMIT="0987603ebd2a93c3c14289f3914cd9145a7dddb5"
PHONEMIZE_COMMIT="fccd4f335aa68ac0b72600822f34d84363daa2bf"
ESPEAK_COMMIT="8593723f10cfd9befd50de447f14bf0a9d2a14a4"
# piper-phonemize's onnxruntime pin (ONNXRUNTIME_VERSION in its CMakeLists).
ONNX_PV="1.14.1"
# The rhasspy espeak-ng fork FetchContents sonic at configure time
# (cmake/deps.cmake); pinned commit from there.
SONIC_COMMIT="fbf75c3d6d846bad3bb3d456cbc5d07d9fd8c104"
DESCRIPTION="LocalAI text-to-speech backend (piper gRPC server)"
HOMEPAGE="https://localai.io https://github.com/mudler/LocalAI"
SRC_URI="
${LOCAL_AI_GO_SRC_URI}
https://github.com/mudler/go-piper/archive/${GOPIPER_COMMIT}.tar.gz -> go-piper-${GOPIPER_COMMIT}.tar.gz
https://github.com/rhasspy/piper/archive/${PIPER_COMMIT}.tar.gz -> piper-${PIPER_COMMIT}.tar.gz
https://github.com/rhasspy/piper-phonemize/archive/${PHONEMIZE_COMMIT}.tar.gz -> piper-phonemize-${PHONEMIZE_COMMIT}.tar.gz
https://github.com/rhasspy/espeak-ng/archive/${ESPEAK_COMMIT}.tar.gz -> rhasspy-espeak-ng-${ESPEAK_COMMIT}.tar.gz
https://github.com/waywardgeek/sonic/archive/${SONIC_COMMIT}.tar.gz -> sonic-${SONIC_COMMIT}.tar.gz
"
S="${WORKDIR}/LocalAI-${PV}/backend/go/piper"
LICENSE="MIT"
SLOT="0"
KEYWORDS="~amd64"
RDEPEND="
sci-ml/local-ai
dev-libs/libfmt:=
dev-libs/spdlog:=
|| (
sci-libs/onnxruntime
sci-libs/onnxruntime-bin
)
"
DEPEND="${RDEPEND}"
GOPIPER="${S}/sources/go-piper"
src_unpack() {
local-ai-backend_go_unpack
# sonic stays in WORKDIR: src_prepare points espeak's FetchContent
# at it there.
unpack "sonic-${SONIC_COMMIT}.tar.gz"
# go-piper with its submodule checkouts, as upstream's clone targets
# would lay them out; the Makefile's network-using targets are then
# skipped because their directories already exist.
local subs=(
"piper-${PIPER_COMMIT}.tar.gz" "piper-${PIPER_COMMIT}" piper
"piper-phonemize-${PHONEMIZE_COMMIT}.tar.gz" "piper-phonemize-${PHONEMIZE_COMMIT}" piper-phonemize
"rhasspy-espeak-ng-${ESPEAK_COMMIT}.tar.gz" "espeak-ng-${ESPEAK_COMMIT}" espeak
)
local-ai-backend_engine_unpack "go-piper-${GOPIPER_COMMIT}.tar.gz" go-piper "${subs[@]}"
}
src_prepare() {
default
# The phonemize cmake invocation in go-piper's Makefile takes no
# argument passthrough; inject the onnxruntime location so its
# download-if-missing logic never triggers.
# go-piper's Makefile assigns its own CFLAGS/CXXFLAGS/LDFLAGS (include
# paths, -lucd, ...). Because Portage exports those names, make
# re-exports the reassigned values to the espeak/phonemize/piper cmake
# children — whose compiler sanity checks then link -lucd before it is
# built. Rename go-piper's private copies so the children inherit the
# real Portage flags and the recipes keep their own values.
einfo "Renaming go-piper's private *FLAGS so Portage flags reach the cmake sub-builds"
sed -i 's/\bCFLAGS\b/GP_CFLAGS/g; s/\bCXXFLAGS\b/GP_CXXFLAGS/g; s/\bLDFLAGS\b/GP_LDFLAGS/g' "${GOPIPER}/Makefile" || die
grep -q 'GP_LDFLAGS' "${GOPIPER}/Makefile" || die "flags rename did not apply"
einfo "Pointing espeak's sonic FetchContent at the unpacked source"
sed -i "s|cd espeak/ei && cmake ..|cd espeak/ei \&\& cmake .. -DFETCHCONTENT_SOURCE_DIR_SONIC-GIT=${WORKDIR}/sonic-${SONIC_COMMIT}|" "${GOPIPER}/Makefile" || die
grep -q 'FETCHCONTENT_SOURCE_DIR_SONIC-GIT' "${GOPIPER}/Makefile" || die "sonic redirect did not apply"
einfo "Injecting ONNXRUNTIME_DIR into go-piper's phonemize cmake invocation"
sed -i "s|cd piper-phonemize/pi && cmake .. --debug-output|cd piper-phonemize/pi \&\& cmake .. --debug-output -DONNXRUNTIME_DIR=${T}/onnx-prefix|" "${GOPIPER}/Makefile" || die
grep -q "onnx-prefix" "${GOPIPER}/Makefile" || die "onnxruntime injection did not apply"
}
# Provide ${T}/onnx-prefix with include/ and lib/ as piper-phonemize expects.
setup_onnx_prefix() {
# Real directories with only the onnxruntime pieces: phonemize's
# install() copies both include/ and lib/ of this prefix into its
# own tree, so symlinking /usr/include or the system libdir here
# would sweep system-wide content into the package staging.
mkdir -p "${T}/onnx-prefix/include" "${T}/onnx-prefix/lib" || die
cp -rL "${ESYSROOT}/usr/include/onnxruntime/." "${T}/onnx-prefix/include/" || die
cp -a "${ESYSROOT}/usr/$(get_libdir)"/libonnxruntime.so* "${T}/onnx-prefix/lib/" || die
}
src_compile() {
setup_onnx_prefix
# FMT_DIR/SPDLOG_DIR defined => piper's ExternalProject downloads are
# skipped and the system libraries are used. CMAKE_ARGS reaches the
# piper cmake line through go-piper's Makefile.
local -x CMAKE_ARGS="-DFMT_DIR=${ESYSROOT}/usr -DSPDLOG_DIR=${ESYSROOT}/usr"
emake -C "${S}" piper
}
src_install() {
local dest="${LOCAL_AI_BACKENDS_DIR#${EPREFIX}}/piper"
local-ai-backend_install piper "${S}/piper"
insinto "${dest}"
doins -r "${S}/espeak-ng-data"
exeinto "${dest}/lib"
# phonemize's install copies the onnxruntime lib into pi/lib; the
# system copy must not be bundled (RDEPEND provides it).
rm -f "${GOPIPER}"/piper-phonemize/pi/lib/libonnxruntime.so* || die
doexe "${GOPIPER}"/piper-phonemize/pi/lib/lib*.so*
doexe "${GOPIPER}"/espeak/ei/lib/lib*.so* 2>/dev/null || true
}
sci-ml/local-ai dev-libs/libfmt:= dev-libs/spdlog:= || ( sci-libs/onnxruntime sci-libs/onnxruntime-bin )
sci-ml/local-ai dev-libs/libfmt:= dev-libs/spdlog:= || ( sci-libs/onnxruntime sci-libs/onnxruntime-bin )