diff --git a/README.md b/README.md index 7407213..4de6d0b 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,18 @@ npm run start --prefix ./ext * `--skipNativeBuilds` macOS only. Skips native receiver selector build. + +#### 32-bit on Windows + +Building a 32-bit version is only supported for Windows. If you're building from a 64-bit system, you'll also need to rebuild any native dependencies as 32-bit. + +````sh +npm clean-install --prefix ./app --arch=ia32 # If on a 64-bit system + +npm run build:app -- -- --arch=x86 --usePkg # If building without packaging +npm run package:app -- -- --arch=x86 # ... else if packaging +```` + ### Packaging Build and package extension and bridge application for current platform: diff --git a/app/bin/build.js b/app/bin/build.js index 6a4bb61..941646c 100644 --- a/app/bin/build.js +++ b/app/bin/build.js @@ -13,22 +13,13 @@ const pkg = require("pkg"); const { spawnSync } = require("child_process"); const meta = require("../package.json"); +const paths = require("./lib/paths"); const { author , homepage } = require("../../package.json"); const { __extensionId: extensionId } = require("../../ext/package.json"); -const { executableName - , executablePath - , manifestName - , manifestPath - , selectorExecutableName - , pkgPlatform - , DIST_PATH - , LICENSE_PATH - , WIN_REGISTRY_KEY } = require("./lib/paths"); - // Command line args const argv = minimist(process.argv.slice(2), { @@ -46,6 +37,7 @@ const argv = minimist(process.argv.slice(2), { const supportedTargets = [ "win-x64" + , "win-x86" , "macos-x64" , "linux-x64" ]; @@ -60,7 +52,7 @@ for (const target of supportedTargets) { supportedArchs.push(arch); } -if (!supportedPlatforms.includes(pkgPlatform[process.platform])) { +if (!supportedPlatforms.includes(paths.pkgPlatformMap[process.platform])) { console.error("Unsupported target platform"); process.exit(1); } @@ -84,9 +76,9 @@ const spawnOptions = { * build directories, just in case. */ fs.removeSync(BUILD_PATH); -fs.removeSync(DIST_PATH); +fs.removeSync(paths.DIST_PATH); fs.ensureDirSync(BUILD_PATH); -fs.ensureDirSync(DIST_PATH, { recursive: true }); +fs.ensureDirSync(paths.DIST_PATH, { recursive: true }); const MDNS_BINDING_PATH = path.join( @@ -127,6 +119,9 @@ async function build () { } }; + const executableName = paths.getExecutableName(process.platform); + const executablePath = paths.getExecutablePath(process.platform, argv.arch); + // Write pkg manifest fs.writeFileSync(path.join(BUILD_PATH, "src/package.json") , JSON.stringify(pkgManifest)) @@ -134,8 +129,8 @@ async function build () { // Run pkg to create a single executable await pkg.exec([ path.join(BUILD_PATH, "src") - , "--target", `node12-${pkgPlatform[process.platform]}-${argv.arch}` - , "--output", path.join(BUILD_PATH, executableName[process.platform]) + , "--target", `node12-${paths.pkgPlatformMap[process.platform]}-${argv.arch}` + , "--output", path.join(BUILD_PATH, executableName) ]); fs.copySync(path.join(MDNS_BINDING_PATH, MDNS_BINDING_NAME) @@ -143,10 +138,9 @@ async function build () { fs.removeSync(path.join(BUILD_PATH, "src")); - manifest.path = argv.usePkg - ? path.join(DIST_PATH, executableName[process.platform]) - : path.join(executablePath[process.platform] - , executableName[process.platform]); + manifest.path = !argv.package && argv.usePkg + ? path.join(paths.DIST_PATH, executableName) + : path.join(executablePath, executableName); } else { let launcherPath = path.join(BUILD_PATH , meta.__applicationExecutableName); @@ -176,12 +170,12 @@ NODE_PATH="${modulesDir}" node $(dirname $0)/src/main.js --__name $(basename $0) } } - manifest.path = path.join(DIST_PATH, path.basename(launcherPath)); + manifest.path = path.join(paths.DIST_PATH, path.basename(launcherPath)); } // Write app manifest - fs.writeFileSync(path.join(BUILD_PATH, manifestName) + fs.writeFileSync(path.join(BUILD_PATH, paths.MANIFEST_NAME) , JSON.stringify(manifest, null, 4)); @@ -205,10 +199,10 @@ NODE_PATH="${modulesDir}" node $(dirname $0)/src/main.js --__name $(basename $0) , spawnOptions); const selectorBundlePath = path.join(derivedDataPath - , "Build/Products/Release/", selectorExecutableName); + , "Build/Products/Release/", paths.SELECTOR_EXECUTABLE_NAME); fs.moveSync(selectorBundlePath - , path.join(BUILD_PATH, selectorExecutableName)); + , path.join(BUILD_PATH, paths.SELECTOR_EXECUTABLE_NAME)); fs.removeSync(derivedDataPath); } @@ -224,16 +218,16 @@ NODE_PATH="${modulesDir}" node $(dirname $0)/src/main.js --__name $(basename $0) // Move installer to dist fs.moveSync( path.join(BUILD_PATH, installerName) - , path.join(DIST_PATH, path.basename(installerName)) + , path.join(paths.DIST_PATH, path.basename(installerName)) , { overwrite: true }); } } else { // Move tsc output and launcher to dist - fs.moveSync(BUILD_PATH, DIST_PATH, { overwrite: true }); + fs.moveSync(BUILD_PATH, paths.DIST_PATH, { overwrite: true }); /* spawnSync("npm install --production", { ...spawnOptions - , cwd: DIST_PATH + , cwd: paths.DIST_PATH }); */ } @@ -249,9 +243,12 @@ NODE_PATH="${modulesDir}" node $(dirname $0)/src/main.js --__name $(basename $0) async function packageApp (platform, arch) { const packageFunctionArgs = [ arch - , executableName[platform] // platformExecutableName - , executablePath[platform] // platformExecutablePath - , manifestPath[platform] // platformManifestPath + // platformExecutableName + , paths.getExecutableName(platform, arch) + // platformExecutablePath + , paths.getExecutablePath(platform, arch) + // platformManifestPath + , paths.getManifestPath(platform, arch, argv.packageType) ]; switch (platform) { @@ -322,13 +319,13 @@ function packageDarwin ( , path.join(rootExecutablePath, platformExecutableName)); fs.moveSync(path.join(BUILD_PATH, MDNS_BINDING_NAME) , path.join(rootExecutablePath, MDNS_BINDING_NAME)); - fs.moveSync(path.join(BUILD_PATH, manifestName) - , path.join(rootManifestPath, manifestName)); + fs.moveSync(path.join(BUILD_PATH, paths.MANIFEST_NAME) + , path.join(rootManifestPath, paths.MANIFEST_NAME)); if (process.platform === "darwin" && !argv.skipNativeBuilds) { // Move selector executable alongside main executable - fs.moveSync(path.join(BUILD_PATH, selectorExecutableName) - , path.join(rootExecutablePath, selectorExecutableName)); + fs.moveSync(path.join(BUILD_PATH, paths.SELECTOR_EXECUTABLE_NAME) + , path.join(rootExecutablePath, paths.SELECTOR_EXECUTABLE_NAME)); } @@ -337,7 +334,7 @@ function packageDarwin ( const view = { applicationName: meta.__applicationName - , manifestName + , manifestName: paths.MANIFEST_NAME , componentName , packageId: `tf.matt.${meta.__applicationName}` , executablePath: platformExecutablePath @@ -406,15 +403,12 @@ function packageLinuxDeb ( fs.ensureDirSync(rootManifestPath, { recursive: true }); // Move files to root - fs.moveSync( - path.join(BUILD_PATH, platformExecutableName) + fs.moveSync(path.join(BUILD_PATH, platformExecutableName) , path.join(rootExecutablePath, platformExecutableName)); - fs.moveSync( - path.join(BUILD_PATH, MDNS_BINDING_NAME) + fs.moveSync(path.join(BUILD_PATH, MDNS_BINDING_NAME) , path.join(rootExecutablePath, MDNS_BINDING_NAME)); - fs.moveSync( - path.join(BUILD_PATH, manifestName) - , path.join(rootManifestPath, manifestName)); + fs.moveSync(path.join(BUILD_PATH, paths.MANIFEST_NAME) + , path.join(rootManifestPath, paths.MANIFEST_NAME)); const controlDir = path.join(__dirname, "../packaging/linux/deb/DEBIAN/"); const controlOutputDir = path.join(rootPath, path.basename(controlDir)); @@ -474,7 +468,7 @@ function packageLinuxRpm ( , executablePath: platformExecutablePath , manifestPath: platformManifestPath , executableName: platformExecutableName - , manifestName + , manifestName: paths.MANIFEST_NAME , bindingName: MDNS_BINDING_NAME }; @@ -483,18 +477,17 @@ function packageLinuxRpm ( fs.readFileSync(specPath).toString() , view)); - const archMap = { + const rpmArchMap = { "x86": "i386" , "x64": "x86_64" }; - // TODO: Use argv.arch spawnSync(` rpmbuild -bb ${specOutputPath} \ --define "_distdir ${BUILD_PATH}" \ --define "_rpmdir ${BUILD_PATH}" \ --define "_rpmfilename ${outputName}" \ - --target=${archMap[arch]}-linux` + --target=${rpmArchMap[arch]}-linux` , spawnOptions); return outputName; @@ -524,11 +517,11 @@ function packageWin32 ( , applicationVersion: meta.__applicationVersion , executableName: platformExecutableName , executablePath: platformExecutablePath - , manifestName + , manifestName: paths.MANIFEST_NAME , bindingName: MDNS_BINDING_NAME - , winRegistryKey: WIN_REGISTRY_KEY + , winRegistryKey: paths.REGISTRY_KEY , outputName - , licensePath: LICENSE_PATH + , licensePath: paths.LICENSE_PATH // Uninstaller keys , registryPublisher: author @@ -541,14 +534,8 @@ function packageWin32 ( fs.readFileSync(scriptPath).toString() , view)); - - const output = makensis.compileSync(scriptOutputPath); - - if (output.status === 0) { - console.log(output.stdout); - } else { - console.error(output.stderr); - } + spawnSync(`makensis /DARCH=${arch} ${scriptOutputPath}` + , spawnOptions); return outputName; } diff --git a/app/bin/install-manifest.js b/app/bin/install-manifest.js index daab793..4cdb4b3 100644 --- a/app/bin/install-manifest.js +++ b/app/bin/install-manifest.js @@ -3,10 +3,7 @@ const os = require("os"); const path = require("path"); const minimist = require("minimist"); -const { manifestName - , manifestPath - , DIST_PATH - , WIN_REGISTRY_KEY } = require("./lib/paths"); +const paths = require("./lib/paths"); const argv = minimist(process.argv.slice(2), { @@ -17,7 +14,7 @@ const argv = minimist(process.argv.slice(2), { }); -const CURRENT_MANIFEST_PATH = path.join(DIST_PATH, manifestName); +const CURRENT_MANIFEST_PATH = path.join(paths.DIST_PATH, paths.MANIFEST_NAME); if (!fs.existsSync(CURRENT_MANIFEST_PATH) && !argv.remove) { @@ -27,6 +24,7 @@ if (!fs.existsSync(CURRENT_MANIFEST_PATH) && !argv.remove) { const platform = os.platform(); +const arch = os.arch(); switch (platform) { case "darwin": @@ -34,24 +32,24 @@ switch (platform) { // Manifest location within home directory const destination = path.join(os.homedir(), platform === "linux" ? ".mozilla/native-messaging-hosts/" - : manifestPath[platform]); + : paths.getManifestPath(platform, arch)); if (argv.remove) { - fs.remove(path.join(destination, manifestName)); + fs.remove(path.join(destination, paths.MANIFEST_NAME)); break; } // Install manifest fs.ensureDirSync(destination); fs.copyFileSync(CURRENT_MANIFEST_PATH - , path.join(destination, manifestName)); + , path.join(destination, paths.MANIFEST_NAME)); break; }; case "win32": { const { Registry } = require("rage-edit"); - const REGISTRY_PATH = `HKCU\\SOFTWARE\\Mozilla\\NativeMessagingHosts\\${WIN_REGISTRY_KEY}`; + const REGISTRY_PATH = `HKCU\\SOFTWARE\\Mozilla\\NativeMessagingHosts\\${paths.REGISTRY_KEY}`; if (argv.remove) { Registry.delete(REGISTRY_PATH); diff --git a/app/bin/lib/paths.js b/app/bin/lib/paths.js index bbf4863..a21430b 100644 --- a/app/bin/lib/paths.js +++ b/app/bin/lib/paths.js @@ -1,3 +1,5 @@ +"use strict"; + const path = require("path"); const { __applicationName @@ -9,35 +11,65 @@ const rootPath = path.join(__dirname, "../../../"); exports.DIST_PATH = path.join(rootPath, "dist/app"); exports.LICENSE_PATH = path.join(rootPath, "LICENSE"); -exports.WIN_REGISTRY_KEY = __applicationName; -exports.executableName = { - win32: `${__applicationExecutableName}.exe` - , darwin: __applicationExecutableName - , linux: __applicationExecutableName -}; +exports.REGISTRY_KEY = __applicationName; -exports.executablePath = { - win32: `C:\\Program Files\\${__applicationDirectoryName}\\` - , darwin: `/Library/Application Support/${__applicationDirectoryName}/` - , linux: `/opt/${__applicationDirectoryName}/` -}; - -exports.manifestName = `${__applicationName}.json`; - -exports.manifestPath = { - win32: `C:\\Program Files\\${__applicationDirectoryName}\\` - , darwin: "/Library/Application Support/Mozilla/NativeMessagingHosts/" - , linux: { - deb: "/usr/lib/mozilla/native-messaging-hosts/" - , rpm: "/usr/lib64/mozilla/native-messaging-hosts/" - } -}; - -exports.selectorExecutableName = "fx_cast_selector.app"; - -exports.pkgPlatform = { +exports.pkgPlatformMap = { win32: "win" , darwin: "macos" , linux: "linux" }; + +exports.MANIFEST_NAME = `${__applicationName}.json`; +exports.SELECTOR_EXECUTABLE_NAME = "fx_cast_selector.app"; + +exports.getExecutableName = platform => { + switch (platform) { + case "win32": + return `${__applicationExecutableName}.exe`; + case "darwin": + case "linux": + return __applicationExecutableName; + } +} + +exports.getExecutablePath = (platform, arch) => { + const EXECUTABLE_PATH_WIN32_X64 = `C:\\Program Files\\${__applicationDirectoryName}\\`; + const EXECUTABLE_PATH_WIN32_X86 = `C:\\Program Files (x86)\\${__applicationDirectoryName}\\`; + const EXECUTABLE_PATH_DARWIN = `/Library/Application Support/${__applicationDirectoryName}/`; + const EXECUTABLE_PATH_LINUX = `/opt/${__applicationDirectoryName}/`; + + switch (platform) { + case "win32": + switch (arch) { + case "x86": return EXECUTABLE_PATH_WIN32_X86; + case "x64": return EXECUTABLE_PATH_WIN32_X64; + } + break; + case "darwin": return EXECUTABLE_PATH_DARWIN; + case "linux": return EXECUTABLE_PATH_LINUX; + } +}; + +exports.getManifestPath = (platform, arch, linuxPackageType) => { + const MANIFEST_PATH_DARWIN = "/Library/Application Support/Mozilla/NativeMessagingHosts/"; + const MANIFEST_PATH_LINUX_DEB = "/usr/lib/mozilla/native-messaging-hosts/"; + const MANIFEST_PATH_LINUX_RPM ="/usr/lib64/mozilla/native-messaging-hosts/"; + + switch (platform) { + case "win32": + switch (arch) { + case "x86": + case "x64": return exports.getExecutablePath(platform, arch); + } + break; + case "darwin": return MANIFEST_PATH_DARWIN; + case "linux": + switch (linuxPackageType) { + case "deb": return MANIFEST_PATH_LINUX_DEB; + case "rpm": return MANIFEST_PATH_LINUX_RPM; + } + + break; + } +}; diff --git a/app/package-lock.json b/app/package-lock.json index 9bd3b1f..3bd2568 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -121,12 +121,6 @@ "fastq": "^1.6.0" } }, - "@nsis/language-data": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@nsis/language-data/-/language-data-0.7.4.tgz", - "integrity": "sha512-BJKOrBzGrgEzBA7nnNeDu5XNNOMABt+uVXi8UslM1cox3RRqYLBuOGWiF0SwLlP7CjmxIldQuGyhI8rGFxcDPw==", - "dev": true - }, "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -887,15 +881,6 @@ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, - "makensis": { - "version": "0.20.3", - "resolved": "https://registry.npmjs.org/makensis/-/makensis-0.20.3.tgz", - "integrity": "sha512-SUxlKgorrDXfoBlfkIj1IeihvNfEEJR7oBA1RdSo7LYJKXVJHLqS++TEMaq/XKmWbYW6NowJ+jzH+o0eJanRHQ==", - "dev": true, - "requires": { - "@nsis/language-data": "^0.7.2" - } - }, "mdns": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/mdns/-/mdns-2.5.1.tgz", diff --git a/app/package.json b/app/package.json index 660aea6..35cd706 100644 --- a/app/package.json +++ b/app/package.json @@ -25,7 +25,6 @@ "@types/mime-types": "^2.1.0", "@types/node": "^13.13.15", "@types/node-fetch": "^2.5.7", - "makensis": "^0.20.3", "mustache": "^4.0.1", "pkg": "^4.4.9", "tslint": "^6.1.3" diff --git a/app/packaging/win/installer.nsi b/app/packaging/win/installer.nsi index aa26839..fab691c 100644 --- a/app/packaging/win/installer.nsi +++ b/app/packaging/win/installer.nsi @@ -92,11 +92,16 @@ Section $(MSG__INSTALL_BONJOUR) \ IDNO skipInstallBonjour - File /oname=Bonjour64.msi "C:\Program Files\Bonjour SDK\Installer\Bonjour64.msi" - ExecWait "msiexec /i $\"$INSTDIR\Bonjour64.msi$\"" + ${If} ${ARCH} == "x86" + File /oname=Bonjour.msi "C:\Program Files\Bonjour SDK\Installer\Bonjour.msi" + ${ElseIf} ${ARCH} == "x64" + File /oname=Bonjour.msi "C:\Program Files\Bonjour SDK\Installer\Bonjour64.msi" + ${EndIf} + + ExecWait "msiexec /i $\"$INSTDIR\Bonjour.msi$\"" skipInstallBonjour: - Delete "$INSTDIR\Bonjour64.msi" + Delete "$INSTDIR\Bonjour.msi" # Native manifest key WriteRegStr HKLM "${KEY_MANIFEST}" "" "$INSTDIR\{{manifestName}}"