Install this version:
emerge -a =sci-misc/strata-0.2.8
| Version | EAPI | Keywords | Slot |
|---|---|---|---|
| 0.2.8 | 8 | amd64 | 0 |
# Copyright 1999-2026 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
EAPI=8
REPO="https://github.com/Niko1221/Strata"
# the llama.cpp pin third_party/ggml/VERSION.txt points at: its ggml is built
# statically into the engine, and CMake would FetchContent the same commit
# from the network at configure time, so the ebuild pins it as a distfile
LLAMA_REPO="https://github.com/ggml-org/llama.cpp"
LLAMA_COMMIT="3cf03257f219afbe7334045ff7c6a06ac68c627d"
# system-ggml: the sci-ml/ggml package to link (bump with its bumps)
GGML_PV="0.28.0"
# the commit the v${PV} tag points at; the desktop control staging needs it
# (the tarball has no .git, so STRATA_COMMIT supplies it)
STRATA_TAG_COMMIT="878ef09cc9092a41a37dac32fd6fe461e47fa326"
ROCM_VERSION="7.2"
# the desktop (apps/desktop) tauri shell, from apps/desktop/src-tauri/
# Cargo.lock; the crates are not listed as distfiles but packed into the
# single files/strata-desktop-${PV}-crates.tar.xz (expanded in src_unpack)
CRATES="
"
RUST_MIN_VER="1.77"
inherit cargo cmake cuda linux-info rocm
DESCRIPTION="Local LLM inference engine with an OpenAI/Anthropic-compatible API"
HOMEPAGE="https://github.com/Niko1221/Strata"
SRC_URI="
${CARGO_CRATE_URIS}
${REPO}/archive/refs/tags/v${PV}.tar.gz -> ${P}.tar.gz
!system-ggml? (
${LLAMA_REPO}/archive/${LLAMA_COMMIT}.tar.gz -> ${P}-ggml-${LLAMA_COMMIT}.tar.gz
)
desktop? (
https://nodejs.org/dist/v24.12.0/node-v24.12.0-linux-x64.tar.gz
https://github.com/astral-sh/python-build-standalone/releases/download/20261009/cpython-3.12.15%2B20261009-x86_64-unknown-linux-gnu-install_only.tar.gz -> cpython-3.12.15_20261009-x86_64-unknown-linux-gnu-install_only.tar.gz
)
"
S="${WORKDIR}/Strata-${PV}"
LICENSE="MIT"
SLOT="0"
KEYWORDS="amd64"
# the engine is built for one GPU backend; the terminal (the strata command,
# the monitor and the API server) installs in every case. system-ggml links
# the installed sci-ml/ggml instead of building the pinned commit's ggml
# (files/strata-system-ggml.patch adds the STRATA_SYSTEM_GGML option).
# desktop is the tauri app (apps/desktop): the Rust shell plus the host web
# shell, the pinned node runtime, the pinned CPython control component and
# (with cuda/hip) the engine bundle; the tauri shell locates the resources
# in <bindir>/../lib/strata-desktop, so the layout below is fixed
IUSE="cuda desktop hip system-ggml tui"
REQUIRED_USE="!cuda? ( !hip )"
# the terminal runs on the system python3 (the bin/strata launcher); these
# are the packages its requirements.txt pins; with system-ggml the engine
# links sci-ml/ggml, whose install also carries the source tree (src/ +
# include/) with the internal headers and the ggml-cuda MMQ sources strata
# compiles itself. The desktop's gui stack is the set the tauri shell links
# (best effort: the tauri build is not testable in CI)
COMMON_DEPEND="
dev-python/jinja2
dev-python/numpy
dev-python/pillow
dev-python/psutil
dev-python/pyyaml
dev-python/regex
dev-python/requests
dev-python/tqdm
tui? ( dev-python/textual )
cuda? ( dev-util/nvidia-cuda-toolkit:= )
desktop? (
dev-libs/glib
net-libs/webkit-gtk:4.1
x11-libs/gtk+:3
)
hip? (
>=dev-util/hip-${ROCM_VERSION}:=
>=sci-libs/hipBLAS-${ROCM_VERSION}:=
>=sci-libs/rocBLAS-${ROCM_VERSION}:=
)
system-ggml? ( sci-ml/ggml:0/${GGML_PV}[src] )
"
RDEPEND="${COMMON_DEPEND}"
DEPEND="${COMMON_DEPEND}"
BDEPEND="
desktop? (
>=net-libs/nodejs-24.12[npm]
)
"
PATCHES=( "${FILESDIR}/strata-9999-system-ggml.patch" )
pkg_pretend() {
if use cuda && [[ -z ${CUDA_ARCHITECTURES} ]]; then
einfo "CUDA_ARCHITECTURES is unset, so strata builds its default set of"
einfo "CUDA compute capabilities (75/86/89/120 SASS, 120 PTX), which is slow."
einfo "Set it to your GPU's compute capability to skip unused targets, e.g."
einfo 'CUDA_ARCHITECTURES="75-real" (several are ; separated: "75-real;80-real").'
einfo " find: nvidia-smi --query-gpu=compute_cap --format=csv,noheader"
einfo " suffixes: 75 (PTX+SASS), 75-real (SASS only), 75-virtual (PTX only)"
fi
}
pkg_setup() {
if use desktop; then
rust_pkg_setup
fi
if use hip; then
linux-info_pkg_setup
if linux-info_get_any_version && linux_config_exists; then
if ! linux_chkconfig_present HSA_AMD_SVM; then
ewarn "To use ROCm/HIP, you need to have HSA_AMD_SVM option enabled in your kernel."
fi
fi
fi
}
src_unpack() {
cargo_src_unpack
# the llama.cpp pin for the built-in ggml (not a distfile with
# system-ggml; CMake would fetch the commit from the network)
if ! use system-ggml; then
mkdir -p "${WORKDIR}/llama.cpp-${LLAMA_COMMIT}" || die
tar xzf "${DISTDIR}/${P}-ggml-${LLAMA_COMMIT}.tar.gz" \
-C "${WORKDIR}/llama.cpp-${LLAMA_COMMIT}" --strip-components=1 || die
fi
# the locked runtime wheels for the desktop control component
# (self-generated; not on a mirror, so it is kept in files/ and expanded
# here)
if use desktop; then
mkdir -p "${WORKDIR}/wheels" || die
tar xzf "${FILESDIR}/strata-runtime-wheels-linux-x86_64.tar.gz" \
-C "${WORKDIR}/wheels" || die
fi
# the desktop crates (self-generated, kept in files/ like the wheelhouse);
# expanded onto ${WORKDIR} without stripping so the cargo_home/gentoo
# prefix lands on the cargo eclass' vendor dir
if use desktop; then
tar xJf "${FILESDIR}/strata-desktop-${PV}-crates.tar.xz" -C "${WORKDIR}" || die
fi
}
src_prepare() {
use cuda && cuda_src_prepare
cmake_src_prepare
# the engine version for the component folder name and the manifest
ENGINE_PV=$(sed -n 's/^[[:space:]]*project([^)]*VERSION[[:space:]]*\([0-9][0-9.]*\).*/\1/p' \
"${S}/CMakeLists.txt" | head -n 1)
if use cuda || use hip; then
[[ -n ${ENGINE_PV} ]] || die "cannot find the engine version in CMakeLists.txt"
fi
}
src_configure() {
if use desktop; then
cargo_src_configure --manifest-path "${S}/apps/desktop/src-tauri/Cargo.toml"
fi
local ggml_dir
if use system-ggml; then
# the sci-ml/ggml install: the libraries to link + the source tree
ggml_dir="/usr/$(get_libdir)/ggml-${GGML_PV}"
else
ggml_dir="${WORKDIR}/llama.cpp-${LLAMA_COMMIT}"
fi
local mycmakeargs=(
# portable: the AVX2-baseline ggml-cpu instead of the build host's
# -march=native; strata's own kernels are per-file and CPU-dispatched
# at run time either way
-DSTRATA_PORTABLE=ON
-DSTRATA_NATIVE_EXPERTS=ON
-DSTRATA_Q6K_EXPERTS=ON
-DSTRATA_MMQ_KQUANTS=ON
-DSTRATA_BUILD_TESTS=OFF
# the ggml source (the pinned llama.cpp, or sci-ml/ggml's install);
# without it CMake would fetch the pinned commit from the network
-DSTRATA_GGML_DIR="${ggml_dir}"
-DSTRATA_SYSTEM_GGML=$(usex system-ggml)
)
if use cuda; then
mycmakeargs+=(
-DSTRATA_ENABLE_CUDA=ON
# CUDA_ARCHITECTURES (make.conf) restricts the compute capabilities,
# see pkg_pretend; the default is the upstream recipe: RTX 20 / 30
# / 40 / 50, the latest one with its PTX for forward compatibility
-DCMAKE_CUDA_ARCHITECTURES="${CUDA_ARCHITECTURES:-75-real;86-real;89-real;120-real;120-virtual}"
)
local -x CUDAHOSTCXX="$(cuda_gccdir)"
cuda_add_sandbox
addpredict "/dev/char/"
fi
if use hip; then
rocm_use_clang
mycmakeargs+=(
-DSTRATA_ENABLE_HIP=ON
-DSTRATA_PREFILL_MMQ=ON
# the validated wave32 targets; RDNA2 (gfx103x) is upstream-
# experimental and left out
-DCMAKE_HIP_ARCHITECTURES="gfx1100;gfx1201"
-DCMAKE_HIP_FLAGS="${CXXFLAGS}"
# cmake.eclass clears per-build-type flags for C/CXX only;
# drop CMake's "-O2 -g -DNDEBUG" for HIP
"-DCMAKE_HIP_FLAGS_${CMAKE_BUILD_TYPE^^}="
)
fi
cmake_src_configure
}
src_compile() {
if use desktop; then
# the host web shell (vite); the tauri shell embeds apps/host/dist at
# compile time, so this runs before cargo
einfo "building the host UI"
local -x NPM_CONFIG_CACHE="${WORKDIR}/.npm"
(
cd "${S}/apps/host" || die
npm install --no-audit --no-fund || die
npm run build || die
)
# tauri embeds every bundle.resources path into the binary (the
# embedded copy is unused on linux: at runtime the app reads
# <bindir>/../lib/strata-desktop), so every listed folder must exist
# at compile time; harness is never staged (the app runs without it)
mkdir -p "${S}/apps/desktop/src-tauri/resources/harness" || die
cargo_src_compile
fi
if use cuda; then
# strata_kq: the K-quant MMQ library the engine dlopens for the
# Unsloth UD-Q4/Q5/Q6_K_XL experts
cmake_src_compile strata strata_kq
elif use hip; then
cmake_src_compile strata
fi
}
src_install() {
local libdir="usr/$(get_libdir)/strata"
# ---- the terminal: the strata command, the API server, the model installer ----
insinto "/${libdir}"
doins strata.py setup.py chat.py highlight.py requirements.txt requirements-monitor.txt
doins -r strata_cli strata_control serve
doins -r data
insinto "/${libdir}/bench"
doins -r bench/prompts
insinto "/${libdir}/bin"
doins bin/strata
insinto "/${libdir}/ref"
doins ref/load.py
insinto "/${libdir}/docs"
doins docs/MANAGEMENT_PROTOCOL.md docs/TERMINAL_LAUNCH.md
insinto "/${libdir}"
# the tools modules the terminal paths import: the same closure
# packaging/package_terminal.py stages into its archive (under tools/,
# subdirectories included), computed from the sources
local stage t
stage="${T}/tools-stage"
mkdir -p "${stage}"
while IFS= read -r t; do
cp --parents "tools/${t}.py" "${stage}/"
done < <(
python3 - "${S}" <<'EOF'
import importlib.util, sys
spec = importlib.util.spec_from_file_location("pt", sys.argv[1] + "/packaging/package_terminal.py")
pt = importlib.util.module_from_spec(spec)
spec.loader.exec_module(pt)
names = set(pt.INSTALLER_TOOLS) | set(pt.INSTALLER_SCRIPTS) | set(pt.setup_tool_imports(pt.ROOT))
tools = pt.local_imports(pt.ROOT, tuple(sorted(names)))
[print(name[:-3] if name.endswith(".py") else name) for name in sorted(set(tools) | set(pt.TOOLS_SUBSET))]
EOF
)
doins -r "${stage}/tools"
# the tarball ships it 0775
fperms 0755 "${libdir}/bin/strata"
# the terminal's own version label
echo "${PV}" > "${D}/${libdir}/VERSION"
# the launcher finds the python3 (3.10+) on the PATH
dosym "../$(get_libdir)/strata/bin/strata" /usr/bin/strata
# ---- the engine: an engine component the terminal verifies before a start ----
if use cuda || use hip; then
local backend stage arch_args
use cuda && backend=cuda || backend=hip
stage="${T}/engine-stage"
mkdir -p "${stage}"
cp "${BUILD_DIR}/strata" "${stage}/"
if use cuda; then
cp "${BUILD_DIR}/libstrata_kq.so" "${stage}/"
# the component's archs are what the build actually targeted
# (CUDA_ARCHITECTURES, see pkg_pretend)
local cuda_archs arch num tokens token
local -A arch_seen
cuda_archs="${CUDA_ARCHITECTURES:-75-real;86-real;89-real;120-real;120-virtual}"
arch_args=()
for arch in ${cuda_archs//;/ }; do
num=${arch%%-*}
if [[ ${arch} == *-virtual ]]; then
tokens="compute_${num}"
elif [[ ${arch} == *-* ]]; then
tokens="sm_${num}"
else
tokens="sm_${num} compute_${num}"
fi
for token in ${tokens}; do
if [[ -z ${arch_seen[${token}]+x} ]]; then
arch_seen[${token}]=1
arch_args+=( --arch "${token}" )
fi
done
done
local cuda_pv arch_nums
cuda_pv=$(nvcc --version 2>/dev/null | sed -n 's/.*release \([0-9][0-9]*\.[0-9][0-9]*\).*/\1/p')
arch_nums=$(for arch in ${cuda_archs//;/ }; do
echo "${arch%%-*}"
done | sort -nu | paste -sd ';' -)
cat > "${stage}/BUILD.json" <<-EOF
{
"version": "${ENGINE_PV}",
"source": "gentoo ebuild",
"archs": "${arch_nums}",
"cuda": "${cuda_pv}",
"portable": true
}
EOF
else
# the hipBLASLt version and the matching tuning tables for the
# package; the ROCm install's include tree is /usr
python3 "${S}/packaging/stage_tuning.py" --stage "${stage}" \
--archs "gfx1100 gfx1201" --rocm /usr || die
arch_args=( --arch gfx1100 --arch gfx1201 )
fi
# the engine imports the CUDA toolkit's libraries (cublas, cublasLt,
# cudart); the packager refuses a component whose imports are neither
# bundled nor OS or driver libraries. The toolkit's are allowed:
# RDEPEND (nvidia-cuda-toolkit) provides them and its lib dir is in
# the ldconfig cache
local allow_args=()
use cuda && allow_args=( --allow-lib libcublas.so.13 --allow-lib libcublasLt.so.13
--allow-lib libcudart.so.13 )
# the manifest (engine-component.json): strata hashes and verifies the
# whole component before a start. The picture reader is not shipped,
# so the image input stays off (the engine reports it as missing)
python3 "${S}/packaging/package_engine.py" \
--src "${stage}" \
--backend "${backend}" \
--version "${ENGINE_PV}" \
--platform linux-x86_64 \
--out "${D}/${libdir}/components/engine" \
"${arch_args[@]}" \
"${allow_args[@]}" \
--build-id "gentoo-${PV}" \
--no-picture-reader || die
# estrip (after src_install) would break the component's integrity:
# engine-component.json records the binaries' hashes, so the engine
# must survive the install unstripped
dostrip -x "/${libdir}/components/engine"
local envd="${T}/90strata"
cat > "${envd}" <<-EOF
STRATA_COMPONENTS_DIR="/usr/$(get_libdir)/strata/components"
export STRATA_COMPONENTS_DIR
EOF
doenvd "${envd}"
fi
# ---- the desktop: the tauri shell + the resources it locates beside it ----
if use desktop; then
local desktopdir="usr/$(get_libdir)/strata-desktop"
cp "${S}/apps/desktop/src-tauri/target/release/strata-desktop" "${T}/strata-desktop" || die
insinto /usr/bin
doins "${T}/strata-desktop"
fperms 0755 /usr/bin/strata-desktop
# the web shell + engine host: node starts host/server/index.mjs
insinto "/${desktopdir}/host"
doins -r "${S}/apps/host/dist" "${S}/apps/host/server"
doins "${S}/apps/host/package.json"
# the pinned node runtime (the single binary the host uses)
insinto "/${desktopdir}/node"
doins "${WORKDIR}/node-v24.12.0-linux-x64/bin/node"
fperms 0755 "/${desktopdir}/node/node"
# control: the pinned CPython + the locked wheels + the python parts
# of strata, staged and self-verified by the upstream script. The
# interpreter distfile is pre-placed in its cache, the wheels come
# from files/, so this fetches nothing
local -x STRATA_COMMIT="${STRATA_TAG_COMMIT}"
local -x TMPDIR="${T}"
mkdir -p "${T}/strata-packaging-cache" || die
cp "${DISTDIR}/cpython-3.12.15_20261009-x86_64-unknown-linux-gnu-install_only.tar.gz" \
"${T}/strata-packaging-cache/" || die
python3 "${S}/apps/desktop/scripts/stage-control.py" \
--out "${D}/${desktopdir}/control" \
--wheelhouse "${WORKDIR}/wheels" || die
# the pinned CPython is fragile: strip corrupts its dynamic section
# (its .dynstr is not in a segment) and the interpreter stops running
dostrip -x "/usr/$(get_libdir)/strata-desktop/control"
# the engine bundle: the same component the terminal installs, so
# the app ships with its engine
if use cuda || use hip; then
local comp
mkdir -p "${D}/${desktopdir}/engine-bundle" || die
for comp in "${D}/${libdir}/components/engine"/*; do
[[ -e ${comp} ]] || continue
cp -a "${comp}" "${D}/${desktopdir}/engine-bundle/" || die
done
fi
fi
dodoc README.md
}
pkg_postinst() {
if ! use cuda && ! use hip; then
ewarn "No engine was built (enable the cuda or hip USE flag for an"
ewarn "NVIDIA / AMD GPU). The strata terminal is installed, but"
ewarn "'strata launch' needs an engine: re-emerge sci-misc/strata with"
ewarn "[cuda] or [hip] to build one."
fi
}
Manage flags for this package:
euse -i <flag> -p sci-misc/strata |
euse -E <flag> -p sci-misc/strata |
euse -D <flag> -p sci-misc/strata
dev-python/jinja2 dev-python/numpy dev-python/pillow dev-python/psutil dev-python/pyyaml dev-python/regex dev-python/requests dev-python/tqdm tui? ( dev-python/textual ) cuda? ( dev-util/nvidia-cuda-toolkit:= ) desktop? ( dev-libs/glib net-libs/webkit-gtk:4.1 x11-libs/gtk+:3 ) hip? ( >=dev-util/hip-7.2:= >=sci-libs/hipBLAS-7.2:= >=sci-libs/rocBLAS-7.2:= ) system-ggml? ( sci-ml/ggml:0/0.28.0[src] )
dev-python/jinja2 dev-python/numpy dev-python/pillow dev-python/psutil dev-python/pyyaml dev-python/regex dev-python/requests dev-python/tqdm tui? ( dev-python/textual ) cuda? ( dev-util/nvidia-cuda-toolkit:= ) desktop? ( dev-libs/glib net-libs/webkit-gtk:4.1 x11-libs/gtk+:3 ) hip? ( >=dev-util/hip-7.2:= >=sci-libs/hipBLAS-7.2:= >=sci-libs/rocBLAS-7.2:= ) system-ggml? ( sci-ml/ggml:0/0.28.0[src] )
desktop? ( >=net-libs/nodejs-24.12[npm] )