init
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
@echo off
|
||||
setlocal
|
||||
cd /d "%~dp0.."
|
||||
call conda activate py311
|
||||
if errorlevel 1 (
|
||||
echo Failed to activate conda environment: py311
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
python "%~dp0build_exe.py" %*
|
||||
if errorlevel 1 (
|
||||
echo.
|
||||
echo Build failed.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo.
|
||||
echo Build finished.
|
||||
pause
|
||||
@@ -0,0 +1,19 @@
|
||||
param(
|
||||
[string]$CondaEnv = "py311"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$ProjectRoot = Split-Path -Parent $ScriptDir
|
||||
|
||||
Set-Location $ProjectRoot
|
||||
|
||||
Write-Host "Project root: $ProjectRoot"
|
||||
Write-Host "Conda env: $CondaEnv"
|
||||
|
||||
$ForwardArgs = $args -join " "
|
||||
cmd /d /s /c "call conda activate $CondaEnv && python `"$ScriptDir\build_exe.py`" $ForwardArgs"
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "build failed"
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
import argparse
|
||||
import importlib.util
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
BUILD_DIR = Path(__file__).resolve().parent
|
||||
PROJECT_ROOT = BUILD_DIR.parent
|
||||
|
||||
|
||||
def module_exists(name):
|
||||
return importlib.util.find_spec(name) is not None
|
||||
|
||||
|
||||
def require_module(name, install_hint):
|
||||
if module_exists(name):
|
||||
return
|
||||
raise SystemExit(f"Missing module '{name}'. Install it first: {install_hint}")
|
||||
|
||||
|
||||
def data_arg(source, target):
|
||||
return f"{source};{target}"
|
||||
|
||||
|
||||
def copy_runtime_dir(source, app_dir, name):
|
||||
target = app_dir / name
|
||||
if target.exists():
|
||||
shutil.rmtree(target)
|
||||
shutil.copytree(
|
||||
source,
|
||||
target,
|
||||
ignore=shutil.ignore_patterns("__pycache__", "*.pyc"),
|
||||
)
|
||||
return target
|
||||
|
||||
|
||||
def build(app_name, clean_dist):
|
||||
require_module("PyInstaller", "pip install pyinstaller")
|
||||
|
||||
dist_dir = PROJECT_ROOT / "dist"
|
||||
work_dir = BUILD_DIR / "_pyinstaller"
|
||||
launcher = BUILD_DIR / "run_visualizer.py"
|
||||
|
||||
if clean_dist:
|
||||
app_dist = dist_dir / app_name
|
||||
if app_dist.exists():
|
||||
shutil.rmtree(app_dist)
|
||||
|
||||
args = [
|
||||
sys.executable,
|
||||
"-m",
|
||||
"PyInstaller",
|
||||
"--noconfirm",
|
||||
"--clean",
|
||||
"--onedir",
|
||||
"--windowed",
|
||||
"--name",
|
||||
app_name,
|
||||
"--distpath",
|
||||
str(dist_dir),
|
||||
"--workpath",
|
||||
str(work_dir),
|
||||
"--specpath",
|
||||
str(BUILD_DIR),
|
||||
"--paths",
|
||||
str(PROJECT_ROOT),
|
||||
"--paths",
|
||||
str(PROJECT_ROOT / "sdk"),
|
||||
"--add-data",
|
||||
data_arg(PROJECT_ROOT / "config", "config"),
|
||||
"--add-data",
|
||||
data_arg(PROJECT_ROOT / "sdk", "sdk"),
|
||||
"--hidden-import",
|
||||
"changingtek_p_rtu_Servo",
|
||||
"--hidden-import",
|
||||
"minimalmodbus",
|
||||
"--hidden-import",
|
||||
"serial",
|
||||
"--hidden-import",
|
||||
"cv2",
|
||||
"--hidden-import",
|
||||
"numpy",
|
||||
"--collect-all",
|
||||
"PyQt5",
|
||||
"--collect-all",
|
||||
"pyqtgraph",
|
||||
]
|
||||
|
||||
if module_exists("orisys"):
|
||||
args.extend(["--collect-submodules", "orisys"])
|
||||
else:
|
||||
print("Warning: module 'orisys' was not found; camera runtime may fail unless it is installed.")
|
||||
|
||||
args.append(str(launcher))
|
||||
|
||||
subprocess.run(args, cwd=PROJECT_ROOT, check=True)
|
||||
|
||||
exe_path = dist_dir / app_name / f"{app_name}.exe"
|
||||
if not exe_path.exists():
|
||||
raise SystemExit(f"Build finished but exe was not found: {exe_path}")
|
||||
|
||||
app_dir = exe_path.parent
|
||||
config_dir = copy_runtime_dir(PROJECT_ROOT / "config", app_dir, "config")
|
||||
sdk_dir = copy_runtime_dir(PROJECT_ROOT / "sdk", app_dir, "sdk")
|
||||
|
||||
print()
|
||||
print(f"Build complete: {exe_path}")
|
||||
print(f"Runtime config copied to: {config_dir}")
|
||||
print(f"Runtime sdk copied to: {sdk_dir}")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--name", default="GripperDemo02", help="Output exe/app folder name.")
|
||||
parser.add_argument("--clean-dist", action="store_true", help="Delete dist/<name> before building.")
|
||||
args = parser.parse_args()
|
||||
build(args.name, args.clean_dist)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,15 @@
|
||||
import multiprocessing as mp
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
if getattr(sys, "frozen", False):
|
||||
os.chdir(Path(sys.executable).resolve().parent)
|
||||
|
||||
from gripper.visualizer import main
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
mp.freeze_support()
|
||||
raise SystemExit(main(sys.argv[1:]))
|
||||
Reference in New Issue
Block a user