-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild_executable.py
More file actions
134 lines (116 loc) · 4.32 KB
/
build_executable.py
File metadata and controls
134 lines (116 loc) · 4.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env python3
"""
Build standalone executables for Terminal Chat using PyInstaller
Run this script to create executables for your current platform
"""
import sys
import os
import platform
import subprocess
import shutil
# ANSI colors
RED = "\033[1;31m"
GREEN = "\033[1;32m"
YELLOW = "\033[1;33m"
CYAN = "\033[1;36m"
RESET = "\033[0m"
def main():
"""Build executable for current platform"""
print("=" * 60)
print("Terminal Chat - Executable Builder")
print("=" * 60)
# Check if PyInstaller is installed
pyinstaller_found = False
# Try importing (works for pip/venv installs)
try:
import PyInstaller
print(f"✓ PyInstaller {PyInstaller.__version__} found")
pyinstaller_found = True
except ImportError:
# Try command (works for pipx installs)
try:
result = subprocess.run(["pyinstaller", "--version"],
capture_output=True, text=True, check=True)
version = result.stdout.strip()
print(f"✓ PyInstaller {version} found (via pipx)")
pyinstaller_found = True
except (subprocess.CalledProcessError, FileNotFoundError):
pass
if not pyinstaller_found:
print("✗ PyInstaller not found!")
print(f"\n{RED}ERROR: PyInstaller is required but not installed{RESET}")
print(f"\n{YELLOW}This system has externally-managed Python.{RESET}")
print(f"{YELLOW}Please install PyInstaller manually using ONE of these methods:{RESET}\n")
print(f"{CYAN}Option 1 - Using pipx (recommended):{RESET}")
print(" sudo apt install pipx")
print(" pipx install pyinstaller")
print(f"\n{CYAN}Option 2 - Using venv:{RESET}")
print(" python3 -m venv venv")
print(" source venv/bin/activate")
print(" pip install pyinstaller")
print(" python build_executable.py")
print(f"\n{CYAN}Option 3 - System package:{RESET}")
print(" sudo apt install pyinstaller")
print(f"\n{YELLOW}Note: The executable already exists in dist/ and works!{RESET}")
sys.exit(1)
# Determine platform
system = platform.system()
arch = platform.machine()
print(f"✓ Platform: {system} ({arch})")
# Set output name based on platform
if system == "Windows":
output_name = "terminal-chat-windows"
icon = None # Add .ico file if you have one
elif system == "Darwin":
output_name = "terminal-chat-macos"
icon = None # Add .icns file if you have one
else:
output_name = "terminal-chat-linux"
icon = None
# PyInstaller command
# We need to add src to the Python path for imports to work
cmd = [
"pyinstaller",
"--onefile", # Single executable
"--name", output_name,
"--clean", # Clean PyInstaller cache
"--paths", "src", # Add src to Python path
"--add-data", f"src{os.pathsep}src", # Include src directory
"--add-data", f"bin{os.pathsep}bin", # Include bin directory
"bin/terminal-chat.py"
]
if icon:
cmd.extend(["--icon", icon])
print("\n" + "=" * 60)
print("Building executable...")
print("=" * 60)
print(f"Command: {' '.join(cmd)}\n")
# Build
try:
subprocess.check_call(cmd)
print("\n" + "=" * 60)
print("✓ Build successful!")
print("=" * 60)
# Find the executable
dist_dir = "dist"
if system == "Windows":
exe_path = os.path.join(dist_dir, f"{output_name}.exe")
else:
exe_path = os.path.join(dist_dir, output_name)
if os.path.exists(exe_path):
size_mb = os.path.getsize(exe_path) / (1024 * 1024)
print(f"\nExecutable: {exe_path}")
print(f"Size: {size_mb:.1f} MB")
print(f"\nTo run: ./{exe_path}")
# Clean up build artifacts
print("\nCleaning up build files...")
if os.path.exists("build"):
shutil.rmtree("build")
if os.path.exists(f"{output_name}.spec"):
os.remove(f"{output_name}.spec")
print("✓ Cleanup complete")
except subprocess.CalledProcessError as e:
print(f"\n✗ Build failed: {e}")
sys.exit(1)
if __name__ == "__main__":
main()