123 lines
4.3 KiB
Python
123 lines
4.3 KiB
Python
import os
|
|
import sys
|
|
import shutil
|
|
import zipapp
|
|
import hashlib
|
|
import platform
|
|
import subprocess
|
|
|
|
DIST_DIR = os.path.abspath("dist")
|
|
OUT_DIR = os.path.abspath("out")
|
|
BUILD_TEMP = os.path.abspath("build_temp")
|
|
|
|
def clean_and_prep():
|
|
if os.path.exists(DIST_DIR):
|
|
shutil.rmtree(DIST_DIR)
|
|
os.makedirs(DIST_DIR, exist_ok=True)
|
|
if os.path.exists(BUILD_TEMP):
|
|
shutil.rmtree(BUILD_TEMP)
|
|
os.makedirs(BUILD_TEMP, exist_ok=True)
|
|
|
|
def build_pyinstaller_binary(script_path, binary_name):
|
|
print(f"[*] Compiling {binary_name} with PyInstaller...")
|
|
cmd = [
|
|
sys.executable, "-m", "PyInstaller",
|
|
"--onefile",
|
|
"--clean",
|
|
"--distpath", DIST_DIR,
|
|
"--workpath", os.path.join(BUILD_TEMP, f"work_{binary_name}"),
|
|
"--specpath", os.path.join(BUILD_TEMP, f"spec_{binary_name}"),
|
|
"--name", binary_name,
|
|
script_path
|
|
]
|
|
res = subprocess.run(cmd, capture_output=True, text=True)
|
|
if res.returncode != 0:
|
|
print(f"[!] Compilation error for {binary_name}:\n{res.stderr}")
|
|
raise RuntimeError(f"Failed to build {binary_name}")
|
|
print(f"[+] Successfully compiled {binary_name}")
|
|
|
|
def build_linux_zipapp_binary():
|
|
print("[*] Packaging Linux_Client.bin executable binary...")
|
|
app_dir = os.path.join(BUILD_TEMP, "linux_app")
|
|
os.makedirs(app_dir, exist_ok=True)
|
|
shutil.copy(os.path.join(OUT_DIR, "linux_client", "Linux_Client.py"), os.path.join(app_dir, "Linux_Client.py"))
|
|
|
|
bin_output = os.path.join(DIST_DIR, "Linux_Client.bin")
|
|
zipapp.create_archive(
|
|
source=app_dir,
|
|
target=bin_output,
|
|
interpreter="/usr/bin/env python3",
|
|
main="Linux_Client:main"
|
|
)
|
|
print(f"[+] Successfully generated {bin_output}")
|
|
|
|
def generate_checksums():
|
|
checksum_file = os.path.join(DIST_DIR, "SHA256SUMS.txt")
|
|
lines = []
|
|
for fname in sorted(os.listdir(DIST_DIR)):
|
|
if fname == "SHA256SUMS.txt":
|
|
continue
|
|
fpath = os.path.join(DIST_DIR, fname)
|
|
if os.path.isfile(fpath):
|
|
with open(fpath, "rb") as f:
|
|
digest = hashlib.sha256(f.read()).hexdigest()
|
|
lines.append(f"{digest} {fname}")
|
|
with open(checksum_file, "w", encoding="utf-8") as f:
|
|
f.write("\n".join(lines) + "\n")
|
|
|
|
def main():
|
|
print("=" * 60)
|
|
print(" LOGAR Binary Packaging (Binaries Only)")
|
|
print(f" Platform: {platform.system()} ({platform.machine()})")
|
|
print("=" * 60)
|
|
|
|
clean_and_prep()
|
|
|
|
is_windows = platform.system() == "Windows"
|
|
|
|
if is_windows:
|
|
# Build Windows client executable
|
|
win_client_script = os.path.join(OUT_DIR, "win_client", "Win_Client.py")
|
|
build_pyinstaller_binary(win_client_script, "Win_Client")
|
|
|
|
# Build Windows server executable
|
|
server_script = os.path.join(OUT_DIR, "server", "Server.py")
|
|
build_pyinstaller_binary(server_script, "Server")
|
|
|
|
# Build Linux client standalone binary
|
|
build_linux_zipapp_binary()
|
|
else:
|
|
# On Linux runner: Build native Linux binaries
|
|
linux_client_script = os.path.join(OUT_DIR, "linux_client", "Linux_Client.py")
|
|
build_pyinstaller_binary(linux_client_script, "Linux_Client.bin")
|
|
|
|
server_script = os.path.join(OUT_DIR, "server", "Server.py")
|
|
build_pyinstaller_binary(server_script, "Server.bin")
|
|
|
|
# Also package standalone Windows zipapp executable
|
|
win_app_dir = os.path.join(BUILD_TEMP, "win_app")
|
|
os.makedirs(win_app_dir, exist_ok=True)
|
|
shutil.copy(os.path.join(OUT_DIR, "win_client", "Win_Client.py"), os.path.join(win_app_dir, "Win_Client.py"))
|
|
win_bin_output = os.path.join(DIST_DIR, "Win_Client.pyz")
|
|
zipapp.create_archive(
|
|
source=win_app_dir,
|
|
target=win_bin_output,
|
|
interpreter="/usr/bin/env python3",
|
|
main="Win_Client:main"
|
|
)
|
|
|
|
generate_checksums()
|
|
|
|
# Clean temporary build directory
|
|
if os.path.exists(BUILD_TEMP):
|
|
shutil.rmtree(BUILD_TEMP, ignore_errors=True)
|
|
|
|
print("\n[+] Binary shipping artifacts assembled in 'dist/':")
|
|
for f in os.listdir(DIST_DIR):
|
|
sz = os.path.getsize(os.path.join(DIST_DIR, f))
|
|
print(f" - {f} ({sz / (1024*1024):.2f} MB)" if sz > 1024*1024 else f" - {f} ({sz} bytes)")
|
|
print("=" * 60)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|