mirror of
https://github.com/vypivshiy/kuyase.git
synced 2026-11-07 22:16:05 +03:00
build(release): add release packaging scripts, rename guest kernel to kuyase-kernel-arm64.img, and generate SHA256SUMS
This commit is contained in:
@@ -11,7 +11,9 @@ backups/*
|
||||
# Built binaries (compiled from source via cargo & build-kernel.sh)
|
||||
Releases/
|
||||
kuyase-bins.tar.gz
|
||||
kuyase-kernel-arm64.img
|
||||
kernel/Image
|
||||
kernel/kuyase-kernel-arm64.img
|
||||
guest-init/bin/qemu-hw-bridge
|
||||
|
||||
# Rust build artifacts
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
## Быстрый старт (готовая портативная сборка)
|
||||
|
||||
Для запуска готовой сборки из [**GitHub Releases**](https://github.com/vypivshiy/kuyase/releases) (`kuyase-win64-portable.zip` для Windows x64 или `kuyase-linux64-portable.tar.gz` для Linux x64) не требуется устанавливать Rust, WSL2 или `adb` — ядро `Image`, гостевой инициализатор и демон `qemu-hw-bridge` уже включены в архив.
|
||||
Для запуска готовой сборки из [**GitHub Releases**](https://github.com/vypivshiy/kuyase/releases) (`kuyase-win64-portable.zip` для Windows x64 или `kuyase-linux64-portable.tar.gz` для Linux x64) не требуется устанавливать Rust, WSL2 или `adb` — пропатченное гостевое ядро `kuyase-kernel-arm64.img`, гостевой инициализатор и демон `qemu-hw-bridge` уже включены в архив.
|
||||
|
||||
### 1. Установка QEMU
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
rustup target add armv7-unknown-linux-musleabihf
|
||||
```
|
||||
* **QEMU** (`qemu-system-aarch64` в `./bin/`, `./Releases/` или системном `PATH`).
|
||||
* **Гостевое ядро Linux** (`./kernel/Image` или `./Releases/Image`).
|
||||
* **Гостевое ядро Linux** (`./kuyase-kernel-arm64.img`, `./kernel/kuyase-kernel-arm64.img` или `./Releases/kuyase-kernel-arm64.img` — можно скачать из [**GitHub Releases**](https://github.com/vypivshiy/kuyase/releases)).
|
||||
|
||||
### 2. Сборка гостевого моста и десктопного приложения
|
||||
|
||||
|
||||
@@ -345,7 +345,10 @@ pub fn render_launcher_pane(ui: &mut egui::Ui, app: &mut GuiAppState) {
|
||||
};
|
||||
(true, format!("{}{}", p.display(), suffix))
|
||||
}
|
||||
None => (false, "Не найдено (выберите файл Image)".to_string()),
|
||||
None => (
|
||||
false,
|
||||
"Не найдено (выберите kuyase-kernel-arm64.img)".to_string(),
|
||||
),
|
||||
};
|
||||
|
||||
egui::Grid::new("vm_paths_settings_grid")
|
||||
|
||||
@@ -743,8 +743,8 @@ impl GuiAppState {
|
||||
thread::spawn(move || {
|
||||
if let Some(p) = run_os_custom_file_dialog(
|
||||
&start_dir,
|
||||
"Выберите образ гостевого ядра Linux (Image)",
|
||||
"Ядро Linux (Image*)|Image*;*vmlinuz*|Все файлы (*.*)|*.*",
|
||||
"Выберите образ гостевого ядра Linux (kuyase-kernel-arm64.img / Image)",
|
||||
"Ядро Linux (kuyase-kernel-arm64.img; Image*)|*.img;Image*;*vmlinuz*|Все файлы (*.*)|*.*",
|
||||
) {
|
||||
*slot.lock().unwrap() = Some(p);
|
||||
}
|
||||
|
||||
+10
-3
@@ -22,8 +22,11 @@ pub fn resolve_repo_root() -> PathBuf {
|
||||
}
|
||||
}
|
||||
if let Ok(exe) = env::current_exe() {
|
||||
let has_local_kernel = |dir: &Path| {
|
||||
dir.join("kuyase-kernel-arm64.img").is_file() || dir.join("Image").is_file()
|
||||
};
|
||||
if let Some(exe_dir) = exe.parent() {
|
||||
if exe_dir.join("Image").is_file() && !exe_dir.join("..").join("Cargo.toml").is_file() {
|
||||
if has_local_kernel(exe_dir) && !exe_dir.join("..").join("Cargo.toml").is_file() {
|
||||
return exe_dir.to_path_buf();
|
||||
}
|
||||
}
|
||||
@@ -36,7 +39,7 @@ pub fn resolve_repo_root() -> PathBuf {
|
||||
}
|
||||
}
|
||||
if let Some(exe_dir) = exe.parent() {
|
||||
if exe_dir.join("Image").is_file() {
|
||||
if has_local_kernel(exe_dir) {
|
||||
return exe_dir.to_path_buf();
|
||||
}
|
||||
}
|
||||
@@ -95,6 +98,10 @@ pub fn resolve_qemu_binary(root: &Path) -> Result<PathBuf, String> {
|
||||
|
||||
pub fn resolve_kernel_image(root: &Path) -> Result<PathBuf, String> {
|
||||
let candidates = [
|
||||
root.join("kuyase-kernel-arm64.img"),
|
||||
root.join("kernel").join("kuyase-kernel-arm64.img"),
|
||||
root.join("Releases").join("kuyase-kernel-arm64.img"),
|
||||
root.join("bin").join("kuyase-kernel-arm64.img"),
|
||||
root.join("Image"),
|
||||
root.join("kernel").join("Image"),
|
||||
root.join("Releases").join("Image"),
|
||||
@@ -106,7 +113,7 @@ pub fn resolve_kernel_image(root: &Path) -> Result<PathBuf, String> {
|
||||
}
|
||||
}
|
||||
Err(format!(
|
||||
"Guest Linux kernel Image not found in {}/Image, {}/kernel/Image, {}/Releases/Image, or {}/bin/Image",
|
||||
"Guest Linux kernel not found in {}/kuyase-kernel-arm64.img, {}/kernel/kuyase-kernel-arm64.img, {}/Releases/kuyase-kernel-arm64.img, or {}/kernel/Image",
|
||||
root.display(),
|
||||
root.display(),
|
||||
root.display(),
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
#Requires -Version 5.1
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Сборка всех релизных артефактов KUYASE для GitHub Releases (Windows x64 + ARMv7 guest bridge + Linux x64 через WSL2 + SHA256SUMS.txt).
|
||||
.EXAMPLE
|
||||
pwsh -File scripts/build-releases.ps1
|
||||
#>
|
||||
param(
|
||||
[switch]$SkipLinux
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$RepoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
|
||||
Set-Location $RepoRoot
|
||||
|
||||
New-Item -ItemType Directory -Force -Path "guest-init/bin", "Releases", "kernel" | Out-Null
|
||||
|
||||
Write-Host "=== [1/4] Кросс-компиляция гостевого моста qemu-hw-bridge (armv7-unknown-linux-musleabihf) ===" -ForegroundColor Cyan
|
||||
cargo build --release -p qemu-hw-bridge --target armv7-unknown-linux-musleabihf
|
||||
if ($LASTEXITCODE -ne 0) { throw "Ошибка сборки qemu-hw-bridge" }
|
||||
|
||||
Copy-Item -Force "target/armv7-unknown-linux-musleabihf/release/qemu-hw-bridge" "guest-init/bin/qemu-hw-bridge"
|
||||
Copy-Item -Force "target/armv7-unknown-linux-musleabihf/release/qemu-hw-bridge" "Releases/qemu-hw-bridge"
|
||||
|
||||
Write-Host "=== [2/4] Сборка десктопного приложения и CLI для Windows x64 (kuyase.exe) ===" -ForegroundColor Cyan
|
||||
cargo build --release -p kuyase
|
||||
if ($LASTEXITCODE -ne 0) { throw "Ошибка сборки kuyase.exe" }
|
||||
|
||||
Copy-Item -Force "target/release/kuyase.exe" "Releases/kuyase.exe"
|
||||
|
||||
if (Test-Path "kernel/kuyase-kernel-arm64.img") {
|
||||
Copy-Item -Force "kernel/kuyase-kernel-arm64.img" "Releases/kuyase-kernel-arm64.img"
|
||||
} elseif (Test-Path "kernel/Image") {
|
||||
Copy-Item -Force "kernel/Image" "Releases/kuyase-kernel-arm64.img"
|
||||
} elseif ((Test-Path "Releases/Image") -and -not (Test-Path "Releases/kuyase-kernel-arm64.img")) {
|
||||
Copy-Item -Force "Releases/Image" "Releases/kuyase-kernel-arm64.img"
|
||||
}
|
||||
if (-not (Test-Path "Releases/kuyase-kernel-arm64.img")) {
|
||||
throw "Не найден образ гостевого ядра Releases/kuyase-kernel-arm64.img (или kernel/Image)"
|
||||
}
|
||||
Copy-Item -Force "Releases/kuyase-kernel-arm64.img" "kernel/kuyase-kernel-arm64.img"
|
||||
Copy-Item -Force "Releases/kuyase-kernel-arm64.img" "kernel/Image"
|
||||
|
||||
Write-Host "=== [3/4] Упаковка Releases/kuyase-win64-portable.zip ===" -ForegroundColor Cyan
|
||||
$StageWin = Join-Path ([System.IO.Path]::GetTempPath()) "kuyase-win64-stage-$PID"
|
||||
if (Test-Path $StageWin) { Remove-Item -Recurse -Force $StageWin }
|
||||
New-Item -ItemType Directory -Force -Path $StageWin, (Join-Path $StageWin "examples"), (Join-Path $StageWin "scripts") | Out-Null
|
||||
|
||||
try {
|
||||
Copy-Item -Force "Releases/kuyase.exe" (Join-Path $StageWin "kuyase.exe")
|
||||
Copy-Item -Force "Releases/kuyase-kernel-arm64.img" (Join-Path $StageWin "kuyase-kernel-arm64.img")
|
||||
Copy-Item -Force "Releases/qemu-hw-bridge" (Join-Path $StageWin "qemu-hw-bridge")
|
||||
Copy-Item -Force "README.md" (Join-Path $StageWin "README.md")
|
||||
Copy-Item -Force "DUMP_GUIDE.md" (Join-Path $StageWin "DUMP_GUIDE.md")
|
||||
Copy-Item -Force "examples/README.md" (Join-Path $StageWin "examples/README.md")
|
||||
Copy-Item -Force "examples/test_yam_lineup.py" (Join-Path $StageWin "examples/test_yam_lineup.py")
|
||||
Copy-Item -Force "scripts/dump-from-adb.ps1", "scripts/dump-from-adb.sh", "scripts/sanitize-rootfs.ps1", "scripts/sanitize-rootfs.sh" (Join-Path $StageWin "scripts/")
|
||||
|
||||
$WinZip = Join-Path $RepoRoot "Releases/kuyase-win64-portable.zip"
|
||||
if (Test-Path $WinZip) { Remove-Item -Force $WinZip }
|
||||
Compress-Archive -Path (Join-Path $StageWin "*") -DestinationPath $WinZip -Force
|
||||
} finally {
|
||||
if (Test-Path $StageWin) { Remove-Item -Recurse -Force $StageWin }
|
||||
}
|
||||
|
||||
if (-not $SkipLinux) {
|
||||
Write-Host "=== [4/4] Сборка Linux x86_64 бинарника и архива через WSL2 ===" -ForegroundColor Cyan
|
||||
$WslRepo = (wsl -e wslpath -u ($RepoRoot -replace '\\', '/')).Trim()
|
||||
wsl -e bash -lc "cd '$WslRepo' && SKIP_BRIDGE=1 CARGO_TARGET_DIR=/tmp/kuyase-linux-target bash scripts/build-releases.sh"
|
||||
if ($LASTEXITCODE -ne 0) { throw "Ошибка сборки Linux-релиза в WSL2" }
|
||||
}
|
||||
|
||||
$ReleaseAssets = @(
|
||||
"kuyase-win64-portable.zip",
|
||||
"kuyase-linux64-portable.tar.gz",
|
||||
"kuyase-kernel-arm64.img"
|
||||
)
|
||||
$SumLines = @()
|
||||
foreach ($fname in $ReleaseAssets) {
|
||||
$fpath = Join-Path $RepoRoot "Releases/$fname"
|
||||
if (Test-Path $fpath) {
|
||||
$hash = (Get-FileHash -Path $fpath -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
$SumLines += "$hash $fname"
|
||||
}
|
||||
}
|
||||
$ShaFile = Join-Path $RepoRoot "Releases/SHA256SUMS.txt"
|
||||
[System.IO.File]::WriteAllLines($ShaFile, $SumLines, (New-Object System.Text.UTF8Encoding($false)))
|
||||
|
||||
Write-Host "`n=== Готовые файлы для загрузки в GitHub Releases (Releases/): ===" -ForegroundColor Green
|
||||
Get-ChildItem "Releases" | Where-Object { $_.Name -in ($ReleaseAssets + @("SHA256SUMS.txt")) } |
|
||||
Select-Object Name, @{Name="SizeMB";Expression={[math]::Round($_.Length / 1MB, 2)}}, LastWriteTime |
|
||||
Format-Table -AutoSize
|
||||
|
||||
Write-Host "=== SHA256SUMS.txt ===" -ForegroundColor Yellow
|
||||
Get-Content $ShaFile
|
||||
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env bash
|
||||
# KUYASE — Сборка релизных бинарников и портативных архивов для GitHub Releases (Linux / WSL2)
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "${REPO_ROOT}"
|
||||
|
||||
export PATH="${HOME}/.cargo/bin:${PATH}"
|
||||
|
||||
if [ "${SKIP_BRIDGE:-0}" != "1" ]; then
|
||||
echo "=== [1/4] Кросс-компиляция гостевого моста qemu-hw-bridge (armv7-unknown-linux-musleabihf) ==="
|
||||
if command -v rustup >/dev/null 2>&1; then
|
||||
rustup target list --installed | grep -q '^armv7-unknown-linux-musleabihf$' || rustup target add armv7-unknown-linux-musleabihf
|
||||
fi
|
||||
cargo build --release -p qemu-hw-bridge --target armv7-unknown-linux-musleabihf
|
||||
mkdir -p guest-init/bin Releases
|
||||
cp -f target/armv7-unknown-linux-musleabihf/release/qemu-hw-bridge guest-init/bin/qemu-hw-bridge
|
||||
cp -f target/armv7-unknown-linux-musleabihf/release/qemu-hw-bridge Releases/qemu-hw-bridge
|
||||
chmod 0755 guest-init/bin/qemu-hw-bridge Releases/qemu-hw-bridge
|
||||
else
|
||||
echo "=== [1/4] Использование готового гостевого моста Releases/qemu-hw-bridge ==="
|
||||
fi
|
||||
|
||||
echo "=== [2/4] Сборка нативного бинарника kuyase (Linux x86_64) ==="
|
||||
CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-target-linux}" cargo build --release -p kuyase
|
||||
LINUX_BIN="${CARGO_TARGET_DIR:-target-linux}/release/kuyase"
|
||||
cp -f "${LINUX_BIN}" Releases/kuyase
|
||||
chmod 0755 Releases/kuyase
|
||||
|
||||
if [ -f kernel/kuyase-kernel-arm64.img ]; then
|
||||
cp -f kernel/kuyase-kernel-arm64.img Releases/kuyase-kernel-arm64.img
|
||||
elif [ -f kernel/Image ]; then
|
||||
cp -f kernel/Image Releases/kuyase-kernel-arm64.img
|
||||
elif [ -f Releases/Image ] && [ ! -f Releases/kuyase-kernel-arm64.img ]; then
|
||||
cp -f Releases/Image Releases/kuyase-kernel-arm64.img
|
||||
fi
|
||||
|
||||
if [ ! -f Releases/kuyase-kernel-arm64.img ]; then
|
||||
echo "[kuyase] Ошибка: не найден образ ядра Releases/kuyase-kernel-arm64.img (или kernel/Image)" >&2
|
||||
exit 1
|
||||
fi
|
||||
mkdir -p kernel
|
||||
cp -f Releases/kuyase-kernel-arm64.img kernel/kuyase-kernel-arm64.img
|
||||
cp -f Releases/kuyase-kernel-arm64.img kernel/Image
|
||||
|
||||
echo "=== [3/4] Упаковка Releases/kuyase-linux64-portable.tar.gz ==="
|
||||
STAGE_LINUX="$(mktemp -d)"
|
||||
trap 'rm -rf "${STAGE_LINUX}"' EXIT
|
||||
mkdir -p "${STAGE_LINUX}/examples" "${STAGE_LINUX}/scripts"
|
||||
cp -f Releases/kuyase "${STAGE_LINUX}/kuyase"
|
||||
cp -f Releases/kuyase-kernel-arm64.img "${STAGE_LINUX}/kuyase-kernel-arm64.img"
|
||||
cp -f Releases/qemu-hw-bridge "${STAGE_LINUX}/qemu-hw-bridge"
|
||||
chmod 0755 "${STAGE_LINUX}/kuyase" "${STAGE_LINUX}/qemu-hw-bridge"
|
||||
cp -f README.md DUMP_GUIDE.md "${STAGE_LINUX}/"
|
||||
cp -f examples/README.md examples/test_yam_lineup.py "${STAGE_LINUX}/examples/"
|
||||
cp -f scripts/dump-from-adb.sh scripts/dump-from-adb.ps1 scripts/sanitize-rootfs.sh scripts/sanitize-rootfs.ps1 "${STAGE_LINUX}/scripts/"
|
||||
chmod 0755 "${STAGE_LINUX}/scripts/"*.sh "${STAGE_LINUX}/examples/test_yam_lineup.py" 2>/dev/null || true
|
||||
|
||||
tar -czf Releases/kuyase-linux64-portable.tar.gz -C "${STAGE_LINUX}" \
|
||||
kuyase kuyase-kernel-arm64.img qemu-hw-bridge README.md DUMP_GUIDE.md examples scripts
|
||||
|
||||
echo "=== [4/4] Генерация контрольных сумм Releases/SHA256SUMS.txt ==="
|
||||
(
|
||||
cd Releases
|
||||
FILES=()
|
||||
[ -f kuyase-win64-portable.zip ] && FILES+=(kuyase-win64-portable.zip)
|
||||
[ -f kuyase-linux64-portable.tar.gz ] && FILES+=(kuyase-linux64-portable.tar.gz)
|
||||
[ -f kuyase-kernel-arm64.img ] && FILES+=(kuyase-kernel-arm64.img)
|
||||
sha256sum "${FILES[@]}" > SHA256SUMS.txt
|
||||
)
|
||||
cat Releases/SHA256SUMS.txt
|
||||
Reference in New Issue
Block a user