diff --git a/Taskfile.yml b/Taskfile.yml index c8dbdd7..6f6ccee 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -210,16 +210,18 @@ tasks: build-appimage: desc: Build Linux AppImage - deps: [build] + deps: [build-frontend] cmds: - "{{.NPM}} run electron-postinstall" + - "PLATFORM=linux {{.NPM}} run build-backend" - "{{.NPM}} run dist -- --linux AppImage" build-exe: desc: Build Windows portable executable - deps: [build] + deps: [build-frontend] cmds: - "{{.NPM}} run electron-postinstall" + - "PLATFORM=win32 {{.NPM}} run build-backend" - "{{.NPM}} run dist -- --win portable" build-electron-linux: @@ -250,6 +252,7 @@ tasks: desc: Build Electron ZIP archive using Electron Forge deps: [build-frontend] cmds: + - "PLATFORM=linux {{.NPM}} run build-backend" - "{{.NPM}} run dist:zip" build-electron-all: @@ -257,7 +260,8 @@ tasks: deps: [build-frontend] cmds: - "{{.NPM}} run electron-postinstall" - - "{{.NPM}} run build-backend" + - "PLATFORM=linux {{.NPM}} run build-backend" + - "PLATFORM=win32 {{.NPM}} run build-backend" - "{{.NPM}} run dist -- --linux AppImage deb --win portable nsis" dist: @@ -272,17 +276,19 @@ tasks: build-appimage-legacy: desc: Build Linux AppImage with legacy Electron version - deps: [build, electron-legacy] + deps: [build-frontend, electron-legacy] cmds: - "{{.NPM}} run electron-postinstall" + - "PLATFORM=linux {{.NPM}} run build-backend" - "{{.NPM}} run dist -- --linux AppImage -c.extraMetadata.main=electron/main-legacy.js" - "./scripts/rename_legacy_artifacts.sh" build-exe-legacy: desc: Build Windows portable executable with legacy Electron version - deps: [build, electron-legacy] + deps: [build-frontend, electron-legacy] cmds: - "{{.NPM}} run electron-postinstall" + - "PLATFORM=win32 {{.NPM}} run build-backend" - "{{.NPM}} run dist -- --win portable -c.extraMetadata.main=electron/main-legacy.js" - "./scripts/rename_legacy_artifacts.sh" diff --git a/cx_setup.py b/cx_setup.py index 00fa221..e0160c7 100644 --- a/cx_setup.py +++ b/cx_setup.py @@ -1,3 +1,4 @@ +import os import sys from pathlib import Path @@ -8,6 +9,9 @@ from meshchatx.src.version import __version__ ROOT = Path(__file__).resolve().parent PUBLIC_DIR = ROOT / "meshchatx" / "public" +target_name = os.environ.get("CX_FREEZE_TARGET_NAME", "ReticulumMeshChatX") +build_exe_dir = os.environ.get("CX_FREEZE_BUILD_EXE", "build/exe") + include_files = [] if PUBLIC_DIR.exists() and PUBLIC_DIR.is_dir(): @@ -42,7 +46,7 @@ setup( Executable( script="meshchatx/meshchat.py", base=None, - target_name="ReticulumMeshChatX", + target_name=target_name, shortcut_name="ReticulumMeshChatX", shortcut_dir="ProgramMenuFolder", icon="logo/icon.ico", @@ -56,7 +60,7 @@ setup( "PIL", ], "optimize": 1, - "build_exe": "build/exe", + "build_exe": build_exe_dir, "replace_paths": [ ("*", ""), ], diff --git a/electron/main.js b/electron/main.js index 59b8cc3..aec565e 100644 --- a/electron/main.js +++ b/electron/main.js @@ -98,7 +98,7 @@ app.on("open-url", (event, url) => { }); function verifyBackendIntegrity(exeDir) { - const manifestPath = path.join(__dirname, "backend-manifest.json"); + const manifestPath = path.join(exeDir, "backend-manifest.json"); if (!fs.existsSync(manifestPath)) { log("Backend integrity manifest missing, skipping check."); return { ok: true, issues: ["Manifest missing"] }; diff --git a/forge.config.js b/forge.config.js index 8f98e1b..2969b81 100644 --- a/forge.config.js +++ b/forge.config.js @@ -1,10 +1,13 @@ const { FusesPlugin } = require("@electron-forge/plugin-fuses"); const { FuseV1Options, FuseVersion } = require("@electron/fuses"); +const platform = process.env.PLATFORM || process.platform; +const extraResourceDir = platform === "win32" || platform === "win" ? "build/exe/win32" : "build/exe/linux"; + module.exports = { packagerConfig: { asar: true, - extraResource: ["build/exe"], + extraResource: [extraResourceDir], executableName: "reticulum-meshchatx", name: "Reticulum MeshChatX", appBundleId: "com.sudoivan.reticulummeshchatx", diff --git a/package.json b/package.json index 9379e5c..e3492e1 100644 --- a/package.json +++ b/package.json @@ -20,10 +20,10 @@ "electron-postinstall": "electron-builder install-app-deps", "electron": "pnpm run electron-postinstall && pnpm run build && electron .", "dist": "pnpm run electron-postinstall && pnpm run build && electron-builder --publish=never", - "dist:linux": "pnpm run electron-postinstall && pnpm run build && electron-builder --linux AppImage deb --publish=never", - "dist:rpm": "pnpm run electron-postinstall && pnpm run build && electron-builder --linux rpm --publish=never", - "dist:flatpak": "pnpm run electron-postinstall && pnpm run build && electron-builder --linux flatpak --publish=never", - "dist:windows": "pnpm run electron-postinstall && pnpm run build && electron-builder --win portable nsis --publish=never", + "dist:linux": "pnpm run electron-postinstall && PLATFORM=linux pnpm run build && electron-builder --linux AppImage deb --publish=never", + "dist:rpm": "pnpm run electron-postinstall && PLATFORM=linux pnpm run build && electron-builder --linux rpm --publish=never", + "dist:flatpak": "pnpm run electron-postinstall && PLATFORM=linux pnpm run build && electron-builder --linux flatpak --publish=never", + "dist:windows": "pnpm run electron-postinstall && PLATFORM=win32 pnpm run build && electron-builder --win portable nsis --publish=never", "dist:zip": "pnpm run electron-postinstall && pnpm run build && electron-forge make --targets @electron-forge/maker-zip", "dist-prebuilt": "pnpm run electron-postinstall && pnpm run build-backend && electron-builder --publish=never", "dist:mac-arm64": "pnpm run electron-postinstall && pnpm run build && electron-builder --mac --arm64 --publish=never", @@ -114,7 +114,7 @@ }, "extraResources": [ { - "from": "build/exe", + "from": "build/exe/linux", "to": "backend", "filter": [ "**/*" @@ -134,7 +134,7 @@ ], "extraResources": [ { - "from": "build/exe", + "from": "build/exe/win32", "to": "backend", "filter": [ "**/*" @@ -152,7 +152,7 @@ "category": "Network", "extraResources": [ { - "from": "build/exe", + "from": "build/exe/linux", "to": "backend", "filter": [ "**/*" diff --git a/scripts/build-backend.js b/scripts/build-backend.js index a7b3e62..982310d 100755 --- a/scripts/build-backend.js +++ b/scripts/build-backend.js @@ -32,6 +32,7 @@ function generateManifest(buildDir, manifestPath) { for (const file of files) { const relativePath = path.relative(buildDir, file); + if (relativePath === "backend-manifest.json") continue; const fileBuffer = fs.readFileSync(file); const hash = crypto.createHash("sha256").update(fileBuffer).digest("hex"); manifest.files[relativePath] = hash; @@ -42,8 +43,26 @@ function generateManifest(buildDir, manifestPath) { } try { - console.log("Building backend with cx_Freeze..."); - const result = spawnSync("poetry", ["run", "python", "cx_setup.py", "build"], { stdio: "inherit", shell: false }); + const platform = process.env.PLATFORM || process.platform; + const isWin = platform === "win32" || platform === "win"; + const targetName = isWin ? "ReticulumMeshChatX.exe" : "ReticulumMeshChatX"; + const buildDirRelative = isWin ? "build/exe/win32" : "build/exe/linux"; + const buildDir = path.join(__dirname, "..", buildDirRelative); + + console.log( + `Building backend for ${platform} (target: ${targetName}, output: ${buildDirRelative}) with cx_Freeze...` + ); + + const env = { + ...process.env, + CX_FREEZE_TARGET_NAME: targetName, + CX_FREEZE_BUILD_EXE: buildDirRelative, + }; + const result = spawnSync("poetry", ["run", "python", "cx_setup.py", "build"], { + stdio: "inherit", + shell: false, + env: env, + }); if (result.error) { throw result.error; } @@ -51,13 +70,11 @@ try { process.exit(result.status || 1); } - const buildDir = path.join(__dirname, "..", "build", "exe"); - const manifestPath = path.join(__dirname, "..", "electron", "backend-manifest.json"); - if (fs.existsSync(buildDir)) { + const manifestPath = path.join(buildDir, "backend-manifest.json"); generateManifest(buildDir, manifestPath); } else { - console.error("Build directory not found, manifest generation skipped."); + console.error(`Build directory not found (${buildDir}), manifest generation skipped.`); } } catch (error) { console.error("Build failed:", error.message);