added linux build
This commit is contained in:
parent
8de6151c81
commit
11fd47946d
|
|
@ -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, 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 \"\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(.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:*)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
.venv-linux/bin/python build.py
|
||||||
47
build.py
47
build.py
|
|
@ -3,29 +3,40 @@ import os
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
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():
|
def generate_icon():
|
||||||
"""Generate icon.ico from tray icon colors (green dot on transparent)."""
|
"""Generate platform-appropriate icon files."""
|
||||||
sizes = [16, 32, 48, 256]
|
sizes = [16, 32, 48, 256]
|
||||||
frames = []
|
frames = [_make_icon_image(s) for s in sizes]
|
||||||
for size in sizes:
|
if _IS_WINDOWS:
|
||||||
img = Image.new("RGBA", (size, size), (0, 0, 0, 0))
|
frames[0].save("icon.ico", format="ICO", sizes=[(s, s) for s in sizes],
|
||||||
from PIL import ImageDraw
|
append_images=frames[1:])
|
||||||
d = ImageDraw.Draw(img)
|
print("icon.ico generated.")
|
||||||
margin = max(1, size // 16)
|
else:
|
||||||
d.ellipse([margin, margin, size - margin, size - margin], fill=(40, 200, 80))
|
frames[-1].save("icon.png", format="PNG")
|
||||||
frames.append(img)
|
print("icon.png generated.")
|
||||||
frames[0].save("icon.ico", format="ICO", sizes=[(s, s) for s in sizes],
|
|
||||||
append_images=frames[1:])
|
|
||||||
print("icon.ico generated.")
|
|
||||||
|
|
||||||
def build():
|
def build():
|
||||||
generate_icon()
|
generate_icon()
|
||||||
subprocess.run([sys.executable, "-m", "PyInstaller", "whisper-dictation.spec",
|
subprocess.run([sys.executable, "-m", "PyInstaller", "whisper-dictation.spec",
|
||||||
"--noconfirm"], check=True)
|
"--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"]:
|
for fname in ["config.json", "vocabulary.json"]:
|
||||||
dest = os.path.join(dist_dir, fname)
|
dest = os.path.join(dist_dir, fname)
|
||||||
if not os.path.exists(dest):
|
if not os.path.exists(dest):
|
||||||
|
|
@ -34,7 +45,15 @@ def build():
|
||||||
else:
|
else:
|
||||||
print(f"Skipped {fname} (already exists in dist — preserving user edits)")
|
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}/")
|
print(f"\nBuild complete: {dist_dir}/")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
build()
|
build()
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ python3 -m venv --system-site-packages .venv-linux
|
||||||
echo "Installing dependencies..."
|
echo "Installing dependencies..."
|
||||||
.venv-linux/bin/pip install --upgrade pip
|
.venv-linux/bin/pip install --upgrade pip
|
||||||
.venv-linux/bin/pip install -r requirements.txt
|
.venv-linux/bin/pip install -r requirements.txt
|
||||||
# No CUDA deps on Linux — runs on CPU
|
.venv-linux/bin/pip install pyinstaller
|
||||||
|
# CUDA: uses system-installed CUDA libs (no pip CUDA packages needed)
|
||||||
|
|
||||||
echo "Done. Run ./start.sh to launch."
|
echo ""
|
||||||
|
echo "Done. Run ./start.sh to launch, or ./build-linux.sh to create a standalone build."
|
||||||
|
|
|
||||||
|
|
@ -11,27 +11,38 @@ def _pkg_path(pkg):
|
||||||
sp = site.getsitepackages()[0]
|
sp = site.getsitepackages()[0]
|
||||||
return os.path.join(sp, *pkg.split('.'))
|
return os.path.join(sp, *pkg.split('.'))
|
||||||
|
|
||||||
_sp = next(p for p in site.getsitepackages() if p.endswith('site-packages'))
|
_is_windows = sys.platform == 'win32'
|
||||||
_nvidia = os.path.join(_sp, 'nvidia')
|
_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(
|
a = Analysis(
|
||||||
['main.py'],
|
['main.py'],
|
||||||
pathex=[],
|
pathex=[],
|
||||||
binaries=[
|
binaries=_binaries,
|
||||||
(os.path.join(_nvidia, 'cublas', 'bin', '*.dll'), '.'),
|
|
||||||
(os.path.join(_nvidia, 'cudnn', 'bin', '*.dll'), '.'),
|
|
||||||
],
|
|
||||||
datas=[
|
datas=[
|
||||||
(os.path.join(_pkg_path('faster_whisper'), 'assets', '*.onnx'), 'faster_whisper/assets'),
|
(os.path.join(_pkg_path('faster_whisper'), 'assets', '*.onnx'), 'faster_whisper/assets'),
|
||||||
],
|
],
|
||||||
hiddenimports=[
|
hiddenimports=_hiddenimports,
|
||||||
'ctranslate2',
|
|
||||||
'faster_whisper',
|
|
||||||
'sounddevice',
|
|
||||||
'pynput.keyboard._win32',
|
|
||||||
'pynput.keyboard._xorg',
|
|
||||||
'pynput.keyboard._uinput',
|
|
||||||
],
|
|
||||||
hookspath=[],
|
hookspath=[],
|
||||||
hooksconfig={},
|
hooksconfig={},
|
||||||
runtime_hooks=[],
|
runtime_hooks=[],
|
||||||
|
|
@ -49,8 +60,8 @@ exe = EXE(
|
||||||
bootloader_ignore_signals=False,
|
bootloader_ignore_signals=False,
|
||||||
strip=False,
|
strip=False,
|
||||||
upx=True,
|
upx=True,
|
||||||
console=False,
|
console=not _is_windows,
|
||||||
icon='icon.ico',
|
icon='icon.ico' if _is_windows else None,
|
||||||
)
|
)
|
||||||
coll = COLLECT(
|
coll = COLLECT(
|
||||||
exe,
|
exe,
|
||||||
|
|
@ -59,5 +70,5 @@ coll = COLLECT(
|
||||||
strip=False,
|
strip=False,
|
||||||
upx=True,
|
upx=True,
|
||||||
upx_exclude=[],
|
upx_exclude=[],
|
||||||
name='whisper-dictation',
|
name='whisper-dictation-' + _platform_tag,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue