summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xbuild.sh33
-rw-r--r--desktop/packages/mullvad-vpn/tasks/distribution.js102
-rw-r--r--scripts/pack-universal-win.sh66
3 files changed, 138 insertions, 63 deletions
diff --git a/build.sh b/build.sh
index 8509cdb1c7..8a51a48f92 100755
--- a/build.sh
+++ b/build.sh
@@ -28,8 +28,8 @@ OPTIMIZE="false"
SIGN="false"
# If the produced app and pkg should be notarized by apple (macOS only)
NOTARIZE="false"
-# If a macOS build should create an installer artifact working on both
-# Intel and Apple Silicon Macs
+# If a macOS or Windows build should create an installer artifact working on both
+# x86 and arm64
UNIVERSAL="false"
while [[ "$#" -gt 0 ]]; do
@@ -38,8 +38,8 @@ while [[ "$#" -gt 0 ]]; do
--sign) SIGN="true";;
--notarize) NOTARIZE="true";;
--universal)
- if [[ "$(uname -s)" != "Darwin" ]]; then
- log_error "--universal only works on macOS"
+ if [[ "$(uname -s)" != "Darwin" && "$(uname -s)" != "MINGW"* ]]; then
+ log_error "--universal only works on macOS and Windows"
exit 1
fi
UNIVERSAL="true"
@@ -79,11 +79,11 @@ if [[ "$UNIVERSAL" == "true" ]]; then
log_error "'TARGETS' and '--universal' cannot be specified simultaneously."
exit 1
else
- log_info "Building universal macOS distribution"
+ log_info "Building universal distribution"
fi
- # Universal macOS builds package targets for both aarch64-apple-darwin and x86_64-apple-darwin.
- # We leave the target corresponding to the host machine empty to avoid rebuilding multiple times.
+ # Universal builds package targets for both aarch64 and x86_64. We leave the target
+ # corresponding to the host machine empty to avoid rebuilding multiple times.
# When the --target flag is provided to cargo it always puts the build in the target/$ENV_TARGET
# folder even when it matches you local machine, as opposed to just the target folder.
# This causes the cached build not to get used when later running e.g.
@@ -91,6 +91,8 @@ if [[ "$UNIVERSAL" == "true" ]]; then
case $HOST in
x86_64-apple-darwin) TARGETS=("" aarch64-apple-darwin);;
aarch64-apple-darwin) TARGETS=("" x86_64-apple-darwin);;
+ x86_64-pc-windows-msvc) TARGETS=("" aarch64-pc-windows-msvc);;
+ aarch64-pc-windows-msvc) TARGETS=("" x86_64-pc-windows-msvc);;
esac
NPM_PACK_ARGS+=(--universal)
@@ -311,7 +313,7 @@ function build {
if [[ "$(uname -s)" == "MINGW"* ]]; then
for t in "${TARGETS[@]:-"$HOST"}"; do
- case $t in
+ case "${t:-"$HOST"}" in
x86_64-pc-windows-msvc) CPP_BUILD_TARGET=x64;;
aarch64-pc-windows-msvc) CPP_BUILD_TARGET=ARM64;;
*)
@@ -384,6 +386,21 @@ if [[ "$SIGN" == "true" && "$(uname -s)" == "MINGW"* ]]; then
done
fi
+# pack universal installer on Windows
+if [[ "$UNIVERSAL" == "true" && "$(uname -s)" == "MINGW"* ]]; then
+ WIN_PACK_ARGS=()
+ if [[ "$OPTIMIZE" == "true" ]]; then
+ WIN_PACK_ARGS+=(--optimize)
+ fi
+ ./scripts/pack-universal-win.sh \
+ --x64-installer "$SCRIPT_DIR/dist/"*"$PRODUCT_VERSION"_x64.exe \
+ --arm64-installer "$SCRIPT_DIR/dist/"*"$PRODUCT_VERSION"_arm64.exe \
+ "${WIN_PACK_ARGS[@]}"
+ if [[ "$SIGN" == "true" ]]; then
+ sign_win "dist/MullvadVPN-${PRODUCT_VERSION}.exe"
+ fi
+fi
+
# notarize installer on macOS
if [[ "$NOTARIZE" == "true" && "$(uname -s)" == "Darwin" ]]; then
log_info "Notarizing pkg"
diff --git a/desktop/packages/mullvad-vpn/tasks/distribution.js b/desktop/packages/mullvad-vpn/tasks/distribution.js
index 6401e24a45..afc6e85b69 100644
--- a/desktop/packages/mullvad-vpn/tasks/distribution.js
+++ b/desktop/packages/mullvad-vpn/tasks/distribution.js
@@ -132,29 +132,25 @@ const config = {
},
win: {
- target: [
- {
- target: 'nsis',
- arch: getWindowsTargetArch(),
- },
- ],
- artifactName: getWindowsArtifactName(),
+ target: [],
+ signAndEditExecutable: false,
+ artifactName: 'MullvadVPN-${version}_${arch}.${ext}',
publisherName: 'Mullvad VPN AB',
extraResources: [
- { from: distAssets(path.join(getWindowsDistSubdir(), 'mullvad.exe')), to: '.' },
+ { from: distAssets(path.join('${env.DIST_SUBDIR}', 'mullvad.exe')), to: '.' },
{
- from: distAssets(path.join(getWindowsDistSubdir(), 'mullvad-problem-report.exe')),
+ from: distAssets(path.join('${env.DIST_SUBDIR}', 'mullvad-problem-report.exe')),
to: '.',
},
- { from: distAssets(path.join(getWindowsDistSubdir(), 'mullvad-daemon.exe')), to: '.' },
- { from: distAssets(path.join(getWindowsDistSubdir(), 'talpid_openvpn_plugin.dll')), to: '.' },
+ { from: distAssets(path.join('${env.DIST_SUBDIR}', 'mullvad-daemon.exe')), to: '.' },
+ { from: distAssets(path.join('${env.DIST_SUBDIR}', 'talpid_openvpn_plugin.dll')), to: '.' },
{
from: root(
path.join(
'windows',
'winfw',
'bin',
- getWindowsTargetArch() + '-${env.CPP_BUILD_MODE}',
+ '${env.TARGET_ARCHITECTURE}-${env.CPP_BUILD_MODE}',
'winfw.dll',
),
),
@@ -163,22 +159,22 @@ const config = {
// TODO: OpenVPN does not have an ARM64 build yet.
{ from: distAssets('binaries/x86_64-pc-windows-msvc/openvpn.exe'), to: '.' },
{
- from: distAssets(path.join('binaries', getWindowsTargetSubdir(), 'apisocks5.exe')),
+ from: distAssets(path.join('binaries', '${env.TARGET_SUBDIR}', 'apisocks5.exe')),
to: '.',
},
{
- from: distAssets(path.join('binaries', getWindowsTargetSubdir(), 'wintun/wintun.dll')),
+ from: distAssets(path.join('binaries', '${env.TARGET_SUBDIR}', 'wintun/wintun.dll')),
to: '.',
},
{
from: distAssets(
- path.join('binaries', getWindowsTargetSubdir(), 'split-tunnel/mullvad-split-tunnel.sys'),
+ path.join('binaries', '${env.TARGET_SUBDIR}', 'split-tunnel/mullvad-split-tunnel.sys'),
),
to: '.',
},
{
from: distAssets(
- path.join('binaries', getWindowsTargetSubdir(), 'wireguard-nt/mullvad-wireguard.dll'),
+ path.join('binaries', '${env.TARGET_SUBDIR}', 'wireguard-nt/mullvad-wireguard.dll'),
),
to: '.',
},
@@ -277,11 +273,23 @@ const config = {
},
};
-function packWin() {
- return builder.build({
- targets: builder.Platform.WINDOWS.createTarget(),
- config: {
+async function packWin() {
+ const DEFAULT_ARCH = targets === 'aarch64-pc-windows-msvc' ? 'arm64' : 'x64';
+
+ function prepareConfig(arch) {
+ return {
...config,
+ files: [...config.files],
+ win: {
+ ...config.win,
+ extraResources: [...config.win.extraResources],
+ target: [
+ {
+ target: 'nsis',
+ arch: arch,
+ },
+ ],
+ },
asarUnpack: ['build/assets/images/menubar-icons/win32/lock-*.ico'],
beforeBuild: (options) => {
process.env.CPP_BUILD_MODE = release ? 'Release' : 'Debug';
@@ -291,10 +299,14 @@ function packWin() {
case 'x64':
process.env.TARGET_TRIPLE = 'x86_64-pc-windows-msvc';
process.env.SETUP_SUBDIR = '.';
+ process.env.TARGET_SUBDIR = 'x86_64-pc-windows-msvc';
+ process.env.DIST_SUBDIR = '';
break;
case 'arm64':
process.env.TARGET_TRIPLE = 'aarch64-pc-windows-msvc';
process.env.SETUP_SUBDIR = 'aarch64-pc-windows-msvc';
+ process.env.TARGET_SUBDIR = 'aarch64-pc-windows-msvc';
+ process.env.DIST_SUBDIR = 'aarch64-pc-windows-msvc';
break;
default:
throw new Error('Invalid or unknown target (only one may be specified)');
@@ -320,7 +332,21 @@ function packWin() {
fs.renameSync(artifactPath, targetArtifactPath);
}
},
- },
+ };
+ }
+
+ if (universal) {
+ // For universal builds, we simply build for all targets. It is up to build.sh to pack the
+ // installers in the same binary.
+ await builder.build({
+ targets: builder.Platform.WINDOWS.createTarget(),
+ config: prepareConfig(DEFAULT_ARCH === 'x64' ? 'arm64' : 'x64'),
+ });
+ }
+
+ return builder.build({
+ targets: builder.Platform.WINDOWS.createTarget(),
+ config: prepareConfig(DEFAULT_ARCH),
});
}
@@ -441,40 +467,6 @@ function root(relativePath) {
return path.join(path.resolve(__dirname, '../../../../'), relativePath);
}
-function getWindowsDistSubdir() {
- if (targets === 'aarch64-pc-windows-msvc') {
- return targets;
- } else {
- return '';
- }
-}
-
-function getWindowsTargetArch() {
- if (targets && process.platform === 'win32') {
- if (targets === 'aarch64-pc-windows-msvc') {
- return 'arm64';
- }
- throw new Error('Invalid or unknown target (only one may be specified)');
- }
- // Use host architecture (we assume this is x64 since building on Arm64 isn't supported).
- return 'x64';
-}
-
-function getWindowsArtifactName() {
- return 'MullvadVPN-${version}_${arch}.${ext}';
-}
-
-function getWindowsTargetSubdir() {
- if (targets && process.platform === 'win32') {
- if (targets === 'aarch64-pc-windows-msvc') {
- return targets;
- }
- throw new Error('Invalid or unknown target (only one may be specified)');
- }
- // Use host architecture (we assume this is x64 since building on Arm64 isn't supported).
- return 'x86_64-pc-windows-msvc';
-}
-
function getLinuxTargetArch() {
if (targets && process.platform === 'linux') {
if (targets === 'aarch64-unknown-linux-gnu') {
diff --git a/scripts/pack-universal-win.sh b/scripts/pack-universal-win.sh
new file mode 100644
index 0000000000..453b722011
--- /dev/null
+++ b/scripts/pack-universal-win.sh
@@ -0,0 +1,66 @@
+#!/usr/bin/env bash
+# shellcheck shell=bash
+# Build universal installer for both ARM and x64.
+
+set -eu
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+cd "$SCRIPT_DIR/.."
+
+CARGO_TARGET_DIR=${CARGO_TARGET_DIR:-"target"}
+
+# If enabled, build in release mode with optimizations enabled
+OPTIMIZE="false"
+
+source scripts/utils/log
+
+echo "Computing build version..."
+PRODUCT_VERSION=$(cargo run -q --bin mullvad-version)
+log_header "Building universal Windows installer for Mullvad VPN $PRODUCT_VERSION"
+
+while [[ "$#" -gt 0 ]]; do
+ case $1 in
+ --x64-installer)
+ export WIN_X64_INSTALLER="$2"
+ shift 2
+ ;;
+ --arm64-installer)
+ export WIN_ARM64_INSTALLER="$2"
+ shift 2
+ ;;
+ --optimize)
+ OPTIMIZE="true"
+ shift
+ ;;
+ *)
+ log_error "Unknown argument: $1"
+ exit 1
+ ;;
+ esac
+done
+
+CARGO_ARGS=()
+
+if [[ "$OPTIMIZE" == "true" ]]; then
+ CARGO_ARGS+=(--release)
+ RUST_BUILD_MODE="release"
+else
+ RUST_BUILD_MODE="debug"
+fi
+
+if [[ "$OPTIMIZE" == "true" && "$PRODUCT_VERSION" != *"-dev-"* ]]; then
+ CARGO_ARGS+=(--locked)
+fi
+
+if [[ -z ${WIN_X64_INSTALLER-} ]] || [[ -z ${WIN_ARM64_INSTALLER-} ]]; then
+ log_error "Must provide --x64-installer and --arm64-installer"
+ exit 1
+fi
+
+cargo build "${CARGO_ARGS[@]}" -p windows-installer --target x86_64-pc-windows-msvc
+
+dest="dist/MullvadVPN-${PRODUCT_VERSION}.exe"
+
+cp "$CARGO_TARGET_DIR/x86_64-pc-windows-msvc/${RUST_BUILD_MODE}/windows-installer.exe" "$dest"
+
+log_success "Built universal installer: $dest"