Updated Windows deploy script + ubuntu updater fix

- Using a node script instead for windows deployment
- ( Will be later used for github automatic deployment)
- Updated windows.md with updated deploy steps
- Autoupdater fix for ubuntu causing update prompt to always show
- Libmpv version bump for ubuntu support
This commit is contained in:
Zarg 2024-12-26 19:07:15 +01:00
parent 42fc7be439
commit 372301093f
6 changed files with 256 additions and 176 deletions

View file

@ -1,155 +0,0 @@
@echo off
REM ============================================
REM Build and prepare the dist-win folder
REM ============================================
REM Check if BUILD_DIR is provided as an argument
if "%~1"=="" (
REM Prompt the user for BUILD_DIR
set /p BUILD_DIR="Please enter the path to the build directory (e.g., C:\path\to\build): "
) else (
set "BUILD_DIR=%~1"
)
REM Check if SSL_BIN_DIR is provided as an argument
if "%~2"=="" (
REM Prompt the user for SSL_BIN_DIR
set /p SSL_BIN_DIR="Please enter the path to the OpenSSL bin directory (e.g., C:\Program Files\OpenSSL-Win64\bin): "
) else (
set "SSL_BIN_DIR=%~2"
)
REM Remove trailing backslash from BUILD_DIR if present
if "%BUILD_DIR:~-1%"=="\" set "BUILD_DIR=%BUILD_DIR:~0,-1%"
REM Define variables
set "PROJECT_NAME=stremio"
pushd %~dp0..
set "SOURCE_DIR=%CD%\"
popd
set "DIST_DIR=%SOURCE_DIR%dist\win"
set "BUILD_DIR=%SOURCE_DIR%%BUILD_DIR%"
REM Define paths to MPV DLL and other dependencies
set "MPV_DLL=%SOURCE_DIR%deps\libmpv\x86_64\libmpv-2.dll"
REM Step 0: Check if windeployqt.exe exists
REM Check if windeployqt.exe exists in PATH
where windeployqt.exe >nul 2>&1
if %ERRORLEVEL% EQU 0 (
set "WINDEPLOYQT_EXECUTABLE=windeployqt.exe"
echo Found windeployqt.exe in PATH.
) else (
echo windeployqt.exe not found in PATH.
REM Check if windeployqt.exe exists at the default path
set "DEFAULT_QT_BIN=C:\Qt\6.8.1\msvc2022_64\bin"
if exist "%DEFAULT_QT_BIN%\windeployqt.exe" (
set "WINDEPLOYQT_EXECUTABLE=%DEFAULT_QT_BIN%\windeployqt.exe"
echo Found windeployqt.exe at default path: %WINDEPLOYQT_EXECUTABLE%
) else (
REM Prompt the user for the qt5\bin path
set /p QT_BIN_DIR="Please enter the path to qt5\bin directory (e.g., C:\Qt\5.15.2\msvc2019_64\bin): "
if exist "%QT_BIN_DIR%\windeployqt.exe" (
set "WINDEPLOYQT_EXECUTABLE=%QT_BIN_DIR%\windeployqt.exe"
echo Found windeployqt.exe at: %WINDEPLOYQT_EXECUTABLE%
) else (
echo Error: windeployqt.exe not found at specified location.
pause
exit /b 1
)
)
)
REM Start the build process
echo ============================================
echo Building and preparing the dist-win folder
echo ============================================
REM Step 1: Clean and create dist-win directory
echo Cleaning and creating dist-win directory...
if exist "%DIST_DIR%" (
REM Remove read-only attributes
attrib -R "%DIST_DIR%" /S /D
REM Force delete directory
rmdir /S /Q "%DIST_DIR%"
)
mkdir "%DIST_DIR%"
REM Step 2: Copy executable to dist-win
echo Copying executable to dist-win...
if exist "%BUILD_DIR%\%PROJECT_NAME%.exe" (
copy "%BUILD_DIR%\%PROJECT_NAME%.exe" "%DIST_DIR%" /Y >nul
) else (
echo Error: Executable %PROJECT_NAME%.exe not found in %BUILD_DIR%.
pause
exit /b 1
)
REM Verify that the executable exists in dist-win
if exist "%DIST_DIR%\%PROJECT_NAME%.exe" (
echo Executable copied successfully.
) else (
echo Error: Executable %PROJECT_NAME%.exe not found in %DIST_DIR%.
pause
exit /b 1
)
REM Step 3: Copy MPV DLL into dist-win
echo Copying MPV DLL into dist-win...
copy "%MPV_DLL%" "%DIST_DIR%" /Y >nul
REM Step 4: Copy server.js into dist-win
echo Copying server.js into dist-win...
copy "%SOURCE_DIR%utils\windows\server.js" "%DIST_DIR%" /Y >nul
REM Step 5: Copy node.exe into dist-win
echo Copying node.exe into dist-win...
copy "%SOURCE_DIR%utils\windows\node.exe" "%DIST_DIR%" /Y >nul
REM Step 6: Copy required OpenSSL DLLs into dist-win
echo Copying required OpenSSL DLLs into dist-win...
set DLL_LIST=libcrypto-3-x64.dll libssl-3-x64.dll
for %%D in (%DLL_LIST%) do (
echo Copying %%D...
copy "%SSL_BIN_DIR%\%%D" "%DIST_DIR%" /Y >nul
if ERRORLEVEL 1 (
echo Failed to copy %%D. Aborting...
exit /b 1
)
)
echo All DLLs copied successfully.
REM Step 7: Copy all files from windows\DS\ into dist-win
echo Copying DS files into dist-win...
xcopy "%SOURCE_DIR%utils\windows\DS\*" "%DIST_DIR%\" /E /I /Y >nul
REM Step 7.1: Copy all files from windows\DS\ into dist-win
echo Copying stremio-runtime files into dist-win...
xcopy "%SOURCE_DIR%utils\windows\stremio-runtime.exe" "%DIST_DIR%\" /Y >nul
REM Step 7.2: Copy all files from windows\ffmpeg\ into dist-win
echo Copying ffmpeg files into dist-win...
xcopy "%SOURCE_DIR%utils\windows\ffmpeg\*" "%DIST_DIR%\" /E /I /Y >nul
REM Step 8: Run windeployqt in dist-win
echo Deploying Qt dependencies with windeployqt...
%WINDEPLOYQT_EXECUTABLE% --qmldir %SOURCE_DIR% %DIST_DIR%\%PROJECT_NAME%.exe
REM Check if windeployqt succeeded
if %ERRORLEVEL% NEQ 0 (
echo Error: windeployqt failed.
pause
exit /b 1
)
echo ============================================
echo Build and preparation of dist-win completed.
echo ============================================
pause

246
build/deploy_windows.js Normal file
View file

@ -0,0 +1,246 @@
#!/usr/bin/env node
/****************************************************************************
* deploy_windows.js
*
* Builds windows distributable folder dist/win.
* Pass --installer to also build the windows installer
* Make sure to have set up utils/windows and the environment correctly by following windows.md
*
****************************************************************************/
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const readline = require('readline');
// ---------------------------------------------------------------------
// Project/Layout Configuration
// ---------------------------------------------------------------------
const SOURCE_DIR = path.resolve(__dirname, '..');
const BUILD_DIR = path.join(SOURCE_DIR, 'cmake-build-release');
const DIST_DIR = path.join(SOURCE_DIR, 'dist', 'win');
const PROJECT_NAME = 'stremio';
// Paths to Additional Dependencies
const MPV_DLL = path.join(SOURCE_DIR, 'deps', 'libmpv', 'x86_64', 'libmpv-2.dll');
const SERVER_JS = path.join(SOURCE_DIR, 'utils', 'windows', 'server.js');
const NODE_EXE = path.join(SOURCE_DIR, 'utils', 'windows', 'node.exe');
const DS_FOLDER = path.join(SOURCE_DIR, 'utils', 'windows', 'DS');
const STREMIO_RUNTIME_EXE = path.join(SOURCE_DIR, 'utils', 'windows', 'stremio-runtime.exe');
const FFMPEG_FOLDER = path.join(SOURCE_DIR, 'utils', 'windows', 'ffmpeg');
// Default Paths
const DEFAULT_OPENSSL_BIN = 'C:\\Program Files\\OpenSSL-Win64\\bin';
const DEFAULT_QT_BIN = 'C:\\Qt\\6.8.1\\msvc2022_64\\bin';
const DEFAULT_NSIS = 'C:\\Program Files (x86)\\NSIS\\makensis.exe';
// ---------------------------------------------------------------------
// Main
// ---------------------------------------------------------------------
(async function main() {
try {
const args = process.argv.slice(2);
const buildInstaller = args.includes('--installer');
// 1) Check or ask for OpenSSL path
let sslBinDir = DEFAULT_OPENSSL_BIN;
if (!fs.existsSync(sslBinDir)) {
console.log(`Default OpenSSL bin not found at: ${sslBinDir}`);
sslBinDir = await askQuestion(
'Enter path to OpenSSL bin (e.g., C:\\Program Files\\OpenSSL-Win64\\bin): '
);
if (!fs.existsSync(sslBinDir)) {
console.error(`Error: No valid OpenSSL bin dir at: ${sslBinDir}`);
process.exit(1);
}
}
console.log(`Using OpenSSL bin: ${sslBinDir}\n`);
// 2) Locate windeployqt.exe
let windeployqtPath = findInPath('windeployqt.exe');
if (!windeployqtPath) {
const defaultWindeployqt = path.join(DEFAULT_QT_BIN, 'windeployqt.exe');
if (fs.existsSync(defaultWindeployqt)) {
windeployqtPath = defaultWindeployqt;
console.log(`Found windeployqt.exe at default path: ${windeployqtPath}`);
} else {
const promptQtBin = await askQuestion(
'Enter path to Qt bin (e.g. C:\\Qt\\6.8.1\\msvc2022_64\\bin): '
);
const possibleQtExe = path.join(promptQtBin, 'windeployqt.exe');
if (!fs.existsSync(possibleQtExe)) {
console.error('Error: windeployqt.exe not found at that location.');
process.exit(1);
}
windeployqtPath = possibleQtExe;
}
} else {
console.log(`Found windeployqt.exe in PATH: ${windeployqtPath}`);
}
// 3) Run CMake + Ninja in ../cmake-build-release (64-bit)
if (!fs.existsSync(BUILD_DIR)) {
fs.mkdirSync(BUILD_DIR, { recursive: true });
}
console.log('\n=== Running CMake in cmake-build-release ===');
process.chdir(BUILD_DIR);
execSync(`cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ..`, { stdio: 'inherit' });
console.log('=== Running Ninja in cmake-build-release ===');
execSync('ninja', { stdio: 'inherit' });
// Return to script directory
process.chdir(__dirname);
// 4) Prepare dist\win
console.log(`\n=== Cleaning and creating ${DIST_DIR} ===`);
safeRemove(DIST_DIR);
fs.mkdirSync(DIST_DIR, { recursive: true });
// 5) Copy main .exe
const builtExe = path.join(BUILD_DIR, `${PROJECT_NAME}.exe`);
const distExe = path.join(DIST_DIR, `${PROJECT_NAME}.exe`);
copyFile(builtExe, distExe);
// 6) Copy mpv DLL, server.js, node.exe
copyFile(MPV_DLL, path.join(DIST_DIR, path.basename(MPV_DLL)));
copyFile(SERVER_JS, path.join(DIST_DIR, path.basename(SERVER_JS)));
copyFile(NODE_EXE, path.join(DIST_DIR, 'node.exe'));
// 7) Copy OpenSSL DLLs
console.log('Copying OpenSSL DLLs...');
const dllList = ['libcrypto-3-x64.dll', 'libssl-3-x64.dll'];
for (const dll of dllList) {
copyFile(path.join(sslBinDir, dll), path.join(DIST_DIR, dll));
}
// 8) Flatten DS folder, stremio-runtime, ffmpeg
console.log('Flattening DS folder, stremio-runtime, ffmpeg...');
copyFolderContents(DS_FOLDER, DIST_DIR);
copyFile(STREMIO_RUNTIME_EXE, path.join(DIST_DIR, 'stremio-runtime.exe'));
copyFolderContents(FFMPEG_FOLDER, DIST_DIR);
// 9) Run windeployqt.exe
console.log('\n=== Deploying Qt dependencies ===');
execSync(`"${windeployqtPath}" --qmldir "${SOURCE_DIR}" "${distExe}"`, { stdio: 'inherit' });
console.log('\n=== dist\\win preparation complete. ===');
// 10) If --installer, parse version and build NSIS
if (buildInstaller) {
console.log('\n--installer detected: building NSIS installer...');
// Extract the version first so we can set process.env before calling NSIS
const version = getPackageVersionFromCMake();
process.env.package_version = version;
console.log(`Set package_version to: ${version}`);
buildNsisInstaller();
}
console.log('\nAll done!');
} catch (err) {
console.error('Error in deploy_windows.js:', err);
process.exit(1);
}
})();
/****************************************************************************
* Helper Functions
****************************************************************************/
function askQuestion(prompt) {
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
return new Promise(resolve => {
rl.question(prompt, answer => {
rl.close();
resolve(answer.trim());
});
});
}
function safeRemove(dirPath) {
if (fs.existsSync(dirPath)) {
fs.rmSync(dirPath, { recursive: true, force: true });
}
}
function copyFile(src, dest) {
if (!fs.existsSync(src)) {
console.warn(`Warning: missing file: ${src}`);
return;
}
fs.copyFileSync(src, dest);
console.log(`Copied: ${src} -> ${dest}`);
}
/**
* Recursively copies only the contents of "src" into "dest" (flattened).
* If src has files/folders, they go directly into dest, rather than
* creating a subfolder named src.
*/
function copyFolderContents(src, dest) {
if (!fs.existsSync(src)) {
console.warn(`Warning: missing folder: ${src}`);
return;
}
const stats = fs.statSync(src);
if (!stats.isDirectory()) {
console.warn(`Warning: not a directory: ${src}`);
return;
}
for (const item of fs.readdirSync(src)) {
const srcItem = path.join(src, item);
const itemStats = fs.statSync(srcItem);
const destItem = path.join(dest, item);
if (itemStats.isDirectory()) {
copyFolderContents(srcItem, dest);
} else {
copyFile(srcItem, destItem);
}
}
}
/**
* Attempt to find an executable in PATH on Windows.
*/
function findInPath(executable) {
try {
const result = execSync(`where ${executable}`, { stdio: ['pipe', 'pipe', 'ignore'] });
return result.toString().split(/\r?\n/)[0].trim();
} catch {
return null;
}
}
/**
* Retrieves version from CMakeLists.txt (handles quotes):
* project(stremio VERSION "5.0.2")
*/
function getPackageVersionFromCMake() {
const cmakeFile = path.join(SOURCE_DIR, 'CMakeLists.txt');
let version = '0.0.0';
if (fs.existsSync(cmakeFile)) {
const content = fs.readFileSync(cmakeFile, 'utf8');
// Accept either quoted or unquoted numerical version
const match = content.match(/project\s*\(\s*stremio\s+VERSION\s+"?([\d.]+)"?\)/i);
if (match) {
version = match[1];
}
}
return version;
}
function buildNsisInstaller() {
if (!fs.existsSync(DEFAULT_NSIS)) {
console.warn(`NSIS not found at default path: ${DEFAULT_NSIS}. Skipping installer.`);
return;
}
try {
const nsiScript = path.join(SOURCE_DIR, 'utils', 'windows', 'installer', 'windows-installer.nsi');
console.log(`Running makensis.exe with version: ${process.env.package_version} ...`);
execSync(`"${DEFAULT_NSIS}" "${nsiScript}"`, { stdio: 'inherit' });
console.log(`\nInstaller created: "Stremio ${process.env.package_version}.exe"`);
} catch (err) {
console.error('Failed to run NSIS (makensis.exe):', err);
}
}

2
deps/libmpv vendored

@ -1 +1 @@
Subproject commit 145b8ac1ec57dd5e93993670d53b06e0a7e2c486
Subproject commit d57999b78b2d7b22f32f3a827a44903fdaa59e62

View file

@ -80,30 +80,19 @@ Ensure the following are installed on your system:
```
---
### 5⃣ **Build the Shell**
### 5⃣ **Build / Deploying the Shell**
1. Make sure to run the following in the `Developer Command Prompt for VS 2022`
1. Make sure to run the following in the `x64 Native Tools Command Prompt for VS 2022`
> **⏳ Note:** Make sure to set the Envs from step 4.2
2. Generate the build files:
2. Run the deployment script in the ``build`` folder
```cmd
cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release ..
```
3. Compile:
```cmd
cmake --build .
node deploy_windows.js --installer
```
> **⏳ Note:** This script uses common paths for ``qt`` and ``openssl`` make sure those are installed. If running with ``--installer`` make sure u installed ``nsis`` with the needed ``nsprocess`` plugin at least once.
4. Build distributable
```cmd
build_windows.bat {cmake-build-folder} {openssl-bin}
build_windows.bat cmake-build-release "C:\Program Files\OpenSSL-Win64\bin"
```
3. Done. This will build the `installer` and ``dist/win`` folder.
> **⏳ Note:** This will create `dist-win` with all necessary files like `node.exe`, `ffmpeg.exe`. Also make sure to have `node.exe, stremio-runtime.exe, server.js` are in `utils\windows\` folder
> **⏳ Note:** This will create `dist/win` with all necessary files like `node.exe`, `ffmpeg.exe`. Also make sure to have `node.exe, stremio-runtime.exe, server.js` are in `utils\windows\` folder
---
## 📦 Installer (Optional)

View file

@ -218,7 +218,7 @@ void AutoUpdater::prepareUpdate(QJsonDocument versionDescDoc) {
|| versionDesc.value("shellVersion").toString() != QCoreApplication::applicationVersion()
) {
toDownload = FULL_UPDATE_FILES;
} else if (files.value(PARTIAL_UPDATE_FILES).toObject().value("checksum").toString() != serverHashHex) {
} else if (files.value(SERVER_FNAME).toObject().value("checksum").toString() != serverHashHex) {
toDownload = PARTIAL_UPDATE_FILES;
} else {
qDebug() << "Everything is up to date";

View file

@ -30,7 +30,7 @@ extern "C" {
#define SERVER_FNAME "server.js"
//#define ASAR_FNAME "stremio.asar"
#define PARTIAL_UPDATE_FILES { SERVER_FNAME, "" }
#define PARTIAL_UPDATE_FILES { SERVER_FNAME }
#if defined(Q_OS_WIN)
#define FULL_UPDATE_FILES { "windows" }