added linux build

This commit is contained in:
Christian Kauer 2026-03-22 09:20:34 +01:00
parent 8de6151c81
commit 11fd47946d
7 changed files with 91 additions and 48 deletions

View File

@ -29,7 +29,14 @@
"Bash(.venv-windows/Scripts/python.exe -c \"\nimport os, site\nsp = site.getsitepackages\\(\\)[0]\ncublas = os.path.join\\(sp, 'nvidia', 'cublas', 'bin'\\)\ncudnn = os.path.join\\(sp, 'nvidia', 'cudnn', 'bin'\\)\nprint\\('cublas:', os.path.exists\\(cublas\\), cublas\\)\nprint\\('cudnn:', os.path.exists\\(cudnn\\), cudnn\\)\n\")",
"Bash(.venv-windows/Scripts/python.exe -c \"\nimport os\nsp = '.venv-windows/Lib/site-packages'\ncublas = os.path.join\\(sp, 'nvidia', 'cublas', 'bin'\\)\ncudnn = os.path.join\\(sp, 'nvidia', 'cudnn', 'bin'\\)\nprint\\('cublas:', os.path.exists\\(cublas\\), os.path.abspath\\(cublas\\)\\)\nprint\\('cudnn:', os.path.exists\\(cudnn\\), os.path.abspath\\(cudnn\\)\\)\n\")",
"Bash(.venv-windows/Scripts/python.exe -c \"import site; print\\(site.getsitepackages\\(\\)\\)\")",
"Bash(git push:*)"
"Bash(git push:*)",
"Bash(find /run/media/chk/Ventoy/projects/chrka/whisper-dictation -type f \\\\\\(-name .github -o -name *.yml -o -name *.yaml \\\\\\))",
"Bash(chmod +x /run/media/chk/Ventoy/projects/chrka/whisper-dictation/build-linux.sh)",
"Bash(bash install.sh)",
"Bash(bash build-linux.sh)",
"Bash(.venv-linux/bin/python -c \"import tkinter; print\\(''tkinter OK''\\)\")",
"Bash(pacman -Q tk)",
"Bash(sudo pacman:*)"
]
}
}

4
build-linux.sh Normal file
View File

@ -0,0 +1,4 @@
#!/bin/bash
set -e
cd "$(dirname "$0")"
.venv-linux/bin/python build.py

View File

@ -3,29 +3,40 @@ import os
import shutil
import sys
import subprocess
from PIL import Image
from PIL import Image, ImageDraw
_IS_WINDOWS = sys.platform == "win32"
_PLATFORM_TAG = "windows" if _IS_WINDOWS else "linux"
def _make_icon_image(size: int) -> Image.Image:
"""Create a green-dot icon at the given size."""
img = Image.new("RGBA", (size, size), (0, 0, 0, 0))
d = ImageDraw.Draw(img)
margin = max(1, size // 16)
d.ellipse([margin, margin, size - margin, size - margin], fill=(40, 200, 80))
return img
def generate_icon():
"""Generate icon.ico from tray icon colors (green dot on transparent)."""
"""Generate platform-appropriate icon files."""
sizes = [16, 32, 48, 256]
frames = []
for size in sizes:
img = Image.new("RGBA", (size, size), (0, 0, 0, 0))
from PIL import ImageDraw
d = ImageDraw.Draw(img)
margin = max(1, size // 16)
d.ellipse([margin, margin, size - margin, size - margin], fill=(40, 200, 80))
frames.append(img)
frames[0].save("icon.ico", format="ICO", sizes=[(s, s) for s in sizes],
append_images=frames[1:])
print("icon.ico generated.")
frames = [_make_icon_image(s) for s in sizes]
if _IS_WINDOWS:
frames[0].save("icon.ico", format="ICO", sizes=[(s, s) for s in sizes],
append_images=frames[1:])
print("icon.ico generated.")
else:
frames[-1].save("icon.png", format="PNG")
print("icon.png generated.")
def build():
generate_icon()
subprocess.run([sys.executable, "-m", "PyInstaller", "whisper-dictation.spec",
"--noconfirm"], check=True)
dist_dir = os.path.join("dist", "whisper-dictation")
dist_dir = os.path.join("dist", "whisper-dictation-" + _PLATFORM_TAG)
for fname in ["config.json", "vocabulary.json"]:
dest = os.path.join(dist_dir, fname)
if not os.path.exists(dest):
@ -34,7 +45,15 @@ def build():
else:
print(f"Skipped {fname} (already exists in dist — preserving user edits)")
# Copy icon.png into dist for Linux .desktop files
if not _IS_WINDOWS:
icon_dest = os.path.join(dist_dir, "icon.png")
if not os.path.exists(icon_dest):
shutil.copy("icon.png", icon_dest)
print(f"Copied icon.png -> {dist_dir}/")
print(f"\nBuild complete: {dist_dir}/")
if __name__ == "__main__":
build()

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1,13 +1,15 @@
#!/bin/bash
set -e
cd "$(dirname "$0")"
echo "Creating Linux venv (.venv-linux)..."
python3 -m venv --system-site-packages .venv-linux
echo "Installing dependencies..."
.venv-linux/bin/pip install --upgrade pip
.venv-linux/bin/pip install -r requirements.txt
# No CUDA deps on Linux — runs on CPU
echo "Done. Run ./start.sh to launch."
#!/bin/bash
set -e
cd "$(dirname "$0")"
echo "Creating Linux venv (.venv-linux)..."
python3 -m venv --system-site-packages .venv-linux
echo "Installing dependencies..."
.venv-linux/bin/pip install --upgrade pip
.venv-linux/bin/pip install -r requirements.txt
.venv-linux/bin/pip install pyinstaller
# CUDA: uses system-installed CUDA libs (no pip CUDA packages needed)
echo ""
echo "Done. Run ./start.sh to launch, or ./build-linux.sh to create a standalone build."

View File

@ -1,3 +1,3 @@
#!/bin/bash
cd "$(dirname "$0")"
.venv-linux/bin/python -u main.py
#!/bin/bash
cd "$(dirname "$0")"
.venv-linux/bin/python -u main.py

View File

@ -11,27 +11,38 @@ def _pkg_path(pkg):
sp = site.getsitepackages()[0]
return os.path.join(sp, *pkg.split('.'))
_sp = next(p for p in site.getsitepackages() if p.endswith('site-packages'))
_nvidia = os.path.join(_sp, 'nvidia')
_is_windows = sys.platform == 'win32'
_platform_tag = 'windows' if _is_windows else 'linux'
# ── Platform-specific binaries ────────────────────────────────────────────────
_binaries = []
if _is_windows:
_sp = next(p for p in site.getsitepackages() if p.endswith('site-packages'))
_nvidia = os.path.join(_sp, 'nvidia')
_binaries = [
(os.path.join(_nvidia, 'cublas', 'bin', '*.dll'), '.'),
(os.path.join(_nvidia, 'cudnn', 'bin', '*.dll'), '.'),
]
# ── Platform-specific hidden imports ──────────────────────────────────────────
_hiddenimports = [
'ctranslate2',
'faster_whisper',
'sounddevice',
]
if _is_windows:
_hiddenimports.append('pynput.keyboard._win32')
else:
_hiddenimports += ['pynput.keyboard._xorg', 'pynput.keyboard._uinput']
a = Analysis(
['main.py'],
pathex=[],
binaries=[
(os.path.join(_nvidia, 'cublas', 'bin', '*.dll'), '.'),
(os.path.join(_nvidia, 'cudnn', 'bin', '*.dll'), '.'),
],
binaries=_binaries,
datas=[
(os.path.join(_pkg_path('faster_whisper'), 'assets', '*.onnx'), 'faster_whisper/assets'),
],
hiddenimports=[
'ctranslate2',
'faster_whisper',
'sounddevice',
'pynput.keyboard._win32',
'pynput.keyboard._xorg',
'pynput.keyboard._uinput',
],
hiddenimports=_hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
@ -49,8 +60,8 @@ exe = EXE(
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
icon='icon.ico',
console=not _is_windows,
icon='icon.ico' if _is_windows else None,
)
coll = COLLECT(
exe,
@ -59,5 +70,5 @@ coll = COLLECT(
strip=False,
upx=True,
upx_exclude=[],
name='whisper-dictation',
name='whisper-dictation-' + _platform_tag,
)