188 lines
5.6 KiB
Bash
188 lines
5.6 KiB
Bash
#!/usr/bin/env bash
|
|
# Apply the numbered llama.cpp patch stack and build the worker scaffold.
|
|
#
|
|
# Default flow:
|
|
# 1. Fetch the pinned llama.cpp source into a build directory if needed.
|
|
# 2. Verify the checkout matches the pinned commit.
|
|
# 3. Check/apply the numbered patch stack from packages/node/native/llama/.
|
|
# 4. Compile and build the standalone worker scaffold.
|
|
# 5. Copy upstream LICENSE/AUTHORS notices into the staging directory.
|
|
#
|
|
# This script is intentionally model-free and does not contact any inference
|
|
# endpoint. It is a source/build reproducibility check.
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
NATIVE_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
LLAMA_ROOT="${NATIVE_ROOT}/llama"
|
|
UPSTREAM_COMMIT="$(tr -d '\n\r' < "${LLAMA_ROOT}/UPSTREAM_COMMIT")"
|
|
UPSTREAM_REPOSITORY="$(tr -d '\n\r' < "${LLAMA_ROOT}/UPSTREAM_REPOSITORY")"
|
|
PATCH_DIR="${LLAMA_ROOT}/patches"
|
|
DEFAULT_SOURCE_DIR="${NATIVE_ROOT}/build/llama.cpp-src"
|
|
DEFAULT_BUILD_DIR="${NATIVE_ROOT}/build/llama-worker"
|
|
SOURCE_DIR="${DEFAULT_SOURCE_DIR}"
|
|
BUILD_DIR="${DEFAULT_BUILD_DIR}"
|
|
WORKTREE_DIR=""
|
|
FETCH=1
|
|
CXX_BIN="${CXX:-}"
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
Usage: build_llama_worker.sh [--source-dir PATH] [--build-dir PATH] [--no-fetch]
|
|
|
|
Builds the project-owned worker scaffold from a pinned llama.cpp checkout.
|
|
EOF
|
|
}
|
|
|
|
fail() {
|
|
echo "error: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
while (($#)); do
|
|
case "$1" in
|
|
--source-dir)
|
|
SOURCE_DIR="${2:-}"
|
|
shift 2
|
|
;;
|
|
--build-dir)
|
|
BUILD_DIR="${2:-}"
|
|
shift 2
|
|
;;
|
|
--no-fetch)
|
|
FETCH=0
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
fail "unknown argument: $1"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
[[ -n "${SOURCE_DIR}" ]] || fail "source dir is empty"
|
|
[[ -n "${BUILD_DIR}" ]] || fail "build dir is empty"
|
|
|
|
checkout_commit() {
|
|
if [[ -f "${SOURCE_DIR}/.meshnet-upstream-commit" ]]; then
|
|
tr -d '\n\r' < "${SOURCE_DIR}/.meshnet-upstream-commit"
|
|
return 0
|
|
fi
|
|
if git -C "${SOURCE_DIR}" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
git -C "${SOURCE_DIR}" rev-parse HEAD
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
ensure_source() {
|
|
if [[ -d "${SOURCE_DIR}" ]]; then
|
|
return 0
|
|
fi
|
|
if [[ "${FETCH}" -ne 1 ]]; then
|
|
fail "source dir ${SOURCE_DIR} does not exist and --no-fetch was set"
|
|
fi
|
|
|
|
mkdir -p "${SOURCE_DIR}"
|
|
git clone --quiet "${UPSTREAM_REPOSITORY}" "${SOURCE_DIR}" || fail "unable to clone ${UPSTREAM_REPOSITORY}"
|
|
git -C "${SOURCE_DIR}" checkout --quiet "${UPSTREAM_COMMIT}" || fail "unable to checkout ${UPSTREAM_COMMIT}"
|
|
printf '%s\n' "${UPSTREAM_COMMIT}" > "${SOURCE_DIR}/.meshnet-upstream-commit"
|
|
printf '%s\n' "${UPSTREAM_REPOSITORY}" > "${SOURCE_DIR}/.meshnet-upstream-repository"
|
|
}
|
|
|
|
verify_assumptions() {
|
|
local observed_commit
|
|
observed_commit="$(checkout_commit)" || fail "source tree does not expose a commit pin; write ${SOURCE_DIR}/.meshnet-upstream-commit or use a git checkout"
|
|
if [[ "${observed_commit}" != "${UPSTREAM_COMMIT}" ]]; then
|
|
fail "llama.cpp pin mismatch: expected ${UPSTREAM_COMMIT}, got ${observed_commit}"
|
|
fi
|
|
|
|
for required in LICENSE AUTHORS CMakeLists.txt; do
|
|
[[ -e "${SOURCE_DIR}/${required}" ]] || fail "missing upstream assumption file: ${required}"
|
|
done
|
|
}
|
|
|
|
apply_patches() {
|
|
shopt -s nullglob
|
|
local patches=("${PATCH_DIR}"/*.patch)
|
|
shopt -u nullglob
|
|
if ((${#patches[@]} == 0)); then
|
|
fail "no patch files found in ${PATCH_DIR}"
|
|
fi
|
|
|
|
for patch in "${patches[@]}"; do
|
|
git -C "${SOURCE_DIR}" apply --check "${patch}" || fail "patch check failed: $(basename "${patch}")"
|
|
done
|
|
for patch in "${patches[@]}"; do
|
|
git -C "${SOURCE_DIR}" apply "${patch}" || fail "patch apply failed: $(basename "${patch}")"
|
|
done
|
|
}
|
|
|
|
build_worker() {
|
|
rm -rf "${BUILD_DIR}"
|
|
mkdir -p "${BUILD_DIR}"
|
|
WORKTREE_DIR="${BUILD_DIR}/llama.cpp-worktree"
|
|
rm -rf "${WORKTREE_DIR}"
|
|
mkdir -p "${WORKTREE_DIR}"
|
|
cp -a "${SOURCE_DIR}/." "${WORKTREE_DIR}/"
|
|
if [[ -f "${SOURCE_DIR}/.meshnet-upstream-commit" ]]; then
|
|
cp "${SOURCE_DIR}/.meshnet-upstream-commit" "${WORKTREE_DIR}/.meshnet-upstream-commit"
|
|
fi
|
|
if [[ -f "${SOURCE_DIR}/.meshnet-upstream-repository" ]]; then
|
|
cp "${SOURCE_DIR}/.meshnet-upstream-repository" "${WORKTREE_DIR}/.meshnet-upstream-repository"
|
|
fi
|
|
|
|
SOURCE_DIR="${WORKTREE_DIR}"
|
|
apply_patches
|
|
|
|
local worker_dir="${SOURCE_DIR}/examples/meshnet-worker"
|
|
cp "${LLAMA_ROOT}/templates/meshnet_worker.cpp" "${worker_dir}/meshnet_worker.cpp"
|
|
cat > "${worker_dir}/version.h" <<EOF
|
|
#pragma once
|
|
|
|
#define MESHNET_LLAMA_UPSTREAM_COMMIT "${UPSTREAM_COMMIT}"
|
|
#define MESHNET_LLAMA_PATCHSET_VERSION "0001"
|
|
EOF
|
|
|
|
local compiler=""
|
|
if [[ -n "${CXX_BIN}" ]] && command -v "${CXX_BIN}" >/dev/null 2>&1; then
|
|
compiler="${CXX_BIN}"
|
|
elif command -v g++ >/dev/null 2>&1; then
|
|
compiler="g++"
|
|
elif command -v c++ >/dev/null 2>&1; then
|
|
compiler="c++"
|
|
elif command -v clang++ >/dev/null 2>&1; then
|
|
compiler="clang++"
|
|
else
|
|
fail "no C++ compiler found (need g++, c++, clang++, or $CXX)"
|
|
fi
|
|
|
|
"${compiler}" -std=c++17 -O2 -Wall -Wextra \
|
|
-I "${worker_dir}" \
|
|
-o "${BUILD_DIR}/meshnet_worker" \
|
|
"${worker_dir}/meshnet_worker.cpp"
|
|
}
|
|
|
|
stage_notices() {
|
|
local notice_dir="${BUILD_DIR}/upstream-notices"
|
|
mkdir -p "${notice_dir}"
|
|
cp "${SOURCE_DIR}/LICENSE" "${notice_dir}/LICENSE"
|
|
cp "${SOURCE_DIR}/AUTHORS" "${notice_dir}/AUTHORS"
|
|
printf '%s\n' "${UPSTREAM_COMMIT}" > "${notice_dir}/UPSTREAM_COMMIT"
|
|
printf '%s\n' "${UPSTREAM_REPOSITORY}" > "${notice_dir}/UPSTREAM_REPOSITORY"
|
|
}
|
|
|
|
main() {
|
|
ensure_source
|
|
verify_assumptions
|
|
build_worker
|
|
stage_notices
|
|
"${BUILD_DIR}/meshnet_worker" --smoke
|
|
echo "build ok: ${BUILD_DIR}/meshnet_worker"
|
|
}
|
|
|
|
main "$@"
|