summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.md5
-rwxr-xr-xbuild-windows-modules.sh8
-rwxr-xr-xbuild.sh298
-rwxr-xr-xci/check-rust.sh2
4 files changed, 181 insertions, 132 deletions
diff --git a/README.md b/README.md
index 927bafe818..cf50926ea9 100644
--- a/README.md
+++ b/README.md
@@ -382,7 +382,7 @@ echo "org.gradle.jvmargs=-Xmx4608M" >> ~/.gradle/gradle.properties
1. On Windows, make sure to start bash first (e.g., Git BASH). Then build the C++ libraries:
```bash
- ./build-windows-modules.sh --dev-build
+ ./build-windows-modules.sh
```
1. Build the system daemon plus the other Rust tools and programs:
@@ -628,8 +628,7 @@ If you're using GNOME, try installing one of these GNOME Shell extensions:
### Building, testing and misc
- **build-windows-modules.sh** - Compiles the C++ libraries needed on Windows
-- **build.sh** - Sanity checks the working directory state and then builds release artifacts for
- the app
+- **build.sh** - Sanity checks the working directory state and then builds installers for the app
### Mullvad Daemon
diff --git a/build-windows-modules.sh b/build-windows-modules.sh
index 0b18f5d6cf..8954ad6a72 100755
--- a/build-windows-modules.sh
+++ b/build-windows-modules.sh
@@ -9,18 +9,16 @@ CPP_BUILD_MODES=${CPP_BUILD_MODES:-"Debug"}
# Common platforms include "x86" and "x64".
CPP_BUILD_TARGETS=${CPP_BUILD_TARGETS:-"x64"}
-if [[ "${1:-""}" == "--dev-build" ]]; then
- DEV_BUILD=true
-fi
+IS_RELEASE=${IS_RELEASE:-"false"}
function clean_solution {
local path="$1"
- if [[ -z ${DEV_BUILD+x} ]]; then
+ if [[ "$IS_RELEASE" == "true" ]]; then
# Clean all intermediate and output files
rm -r "${path:?}/bin/"* || true
else
- echo "Will NOT clean intermediate files in $path/bin/"
+ echo "Will NOT clean intermediate files in $path/bin/ in dev builds"
fi
}
diff --git a/build.sh b/build.sh
index 20ee0171c4..8feca5ee67 100755
--- a/build.sh
+++ b/build.sh
@@ -1,12 +1,13 @@
#!/usr/bin/env bash
-# This script is used to build, and sign a release artifact. See `README.md` for further
-# instructions.
-#
-# Invoke the script with --dev-build in order to skip checks, cleaning and signing.
+# This script is used to build, and optionally sign the app.
+# See `README.md` for further instructions.
set -eu
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+cd "$SCRIPT_DIR"
+
function log {
local NO_COLOR="0m"
local msg=$1
@@ -36,33 +37,34 @@ function log_info {
log "$1" $BOLD
}
+
################################################################################
-# Verify and configure environment.
+# Analyze environment and parse arguments
################################################################################
-SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-cd "$SCRIPT_DIR"
RUSTC_VERSION=$(rustc --version)
-PRODUCT_VERSION=$(node -p "require('./gui/package.json').version" | sed -Ee 's/\.0//g')
CARGO_TARGET_DIR=${CARGO_TARGET_DIR:-"target"}
-CARGO_ARGS=()
-NPM_PACK_ARGS=()
+PRODUCT_VERSION=$(node -p "require('./gui/package.json').version" | sed -Ee 's/\.0//g')
+
+# If compiler optimization and artifact compression should be turned on or not
+OPTIMIZE="false"
+# If the produced binaries should be signed (Windows + macOS only)
+SIGN="false"
+# If a macOS build should create an installer artifact working on both
+# Intel and Apple Silicon Macs
+UNIVERSAL="false"
-BUILD_MODE="release"
while [[ "$#" -gt 0 ]]; do
case $1 in
- --dev-build)
- BUILD_MODE="dev"
- ;;
+ --optimize) OPTIMIZE="true";;
+ --sign) SIGN="true";;
--universal)
- if [[ "$(uname -s)" == "Darwin" ]]; then
- TARGETS=(x86_64-apple-darwin aarch64-apple-darwin)
- NPM_PACK_ARGS+=(--universal)
- else
+ if [[ "$(uname -s)" != "Darwin" ]]; then
log_error "--universal only works on macOS"
exit 1
fi
+ UNIVERSAL="true"
;;
*)
log_error "Unknown parameter: $1"
@@ -72,13 +74,50 @@ while [[ "$#" -gt 0 ]]; do
shift
done
-if [[ "$BUILD_MODE" == "release" ]]; then
+# Check if we are a building a release. Meaning we are configured to build with optimizations,
+# sign the artifacts, AND we are currently building on a release git tag.
+# Everything that is not a release build is called a "dev build" and has "-dev-{commit hash}"
+# appended to the version name.
+IS_RELEASE="false"
+product_version_commit_hash=$(git rev-parse "$PRODUCT_VERSION^{commit}" || echo "")
+current_head_commit_hash=$(git rev-parse "HEAD^{commit}")
+if [[ "$SIGN" == "true" && "$OPTIMIZE" == "true" && \
+ $product_version_commit_hash == "$current_head_commit_hash" ]]; then
+ IS_RELEASE="true"
+fi
+
+################################################################################
+# Configure build
+################################################################################
+
+CARGO_ARGS=()
+NPM_PACK_ARGS=()
+
+if [[ "$UNIVERSAL" == "true" ]]; then
+ TARGETS=(x86_64-apple-darwin aarch64-apple-darwin)
+ NPM_PACK_ARGS+=(--universal)
+fi
+
+if [[ "$OPTIMIZE" == "true" ]]; then
+ CARGO_ARGS+=(--release)
+ RUST_BUILD_MODE="release"
+ CPP_BUILD_MODE="Release"
+else
+ RUST_BUILD_MODE="debug"
+ CPP_BUILD_MODE="Debug"
+ NPM_PACK_ARGS+=(--no-compression)
+fi
+
+if [[ "$SIGN" == "true" ]]; then
if [[ $(git diff --shortstat 2> /dev/null | tail -n1) != "" ]]; then
log_error "Dirty working directory!"
log_error "Will only build a signed app in a clean working directory"
exit 1
fi
+ # Will not allow an outdated lockfile when signing the build
+ CARGO_ARGS+=(--locked)
+
if [[ "$(uname -s)" == "Darwin" || "$(uname -s)" == "MINGW"* ]]; then
log_info "Configuring environment for signing of binaries"
if [[ -z ${CSC_LINK-} ]]; then
@@ -105,61 +144,44 @@ if [[ "$BUILD_MODE" == "release" ]]; then
export CSC_IDENTITY_AUTO_DISCOVERY=false
fi
else
- NPM_PACK_ARGS+=(--no-compression)
- log_info "!! Development build. Not for general distribution !!"
+ log_info "!! Unsigned build. Not for general distribution !!"
unset CSC_LINK CSC_KEY_PASSWORD
export CSC_IDENTITY_AUTO_DISCOVERY=false
fi
-product_version_commit_hash=$(git rev-parse "$PRODUCT_VERSION^{commit}" || echo "")
-current_head_commit_hash=$(git rev-parse "HEAD^{commit}")
-if [[ "$BUILD_MODE" == "dev" || $product_version_commit_hash != "$current_head_commit_hash" ]]; then
+if [[ "$IS_RELEASE" == "true" ]]; then
+ log_info "Removing old Rust build artifacts..."
+ cargo clean
+else
PRODUCT_VERSION="$PRODUCT_VERSION-dev-${current_head_commit_hash:0:6}"
- log_info "Disabling Apple notarization (macOS only) of installer in this dev build"
- NPM_PACK_ARGS+=(--no-apple-notarization)
+ # Allow dev builds to override which API server to use at runtime.
CARGO_ARGS+=(--features api-override)
-else
- log_info "Removing old Rust build artifacts..."
- cargo clean
- CARGO_ARGS+=(--locked)
-fi
-log_header "Building Mullvad VPN $PRODUCT_VERSION"
+ if [[ "$(uname -s)" == "Darwin" ]]; then
+ log_info "Disabling Apple notarization of installer in dev build"
+ NPM_PACK_ARGS+=(--no-apple-notarization)
+ fi
+fi
-if [[ ("$(uname -s)" == "Darwin") ]]; then
- BINARIES=(
- mullvad-daemon
- mullvad
- mullvad-problem-report
- libtalpid_openvpn_plugin.dylib
- mullvad-setup
- )
-elif [[ ("$(uname -s)" == "Linux") ]]; then
- BINARIES=(
- mullvad-daemon
- mullvad
- mullvad-problem-report
- libtalpid_openvpn_plugin.so
- mullvad-setup
- mullvad-exclude
- )
-elif [[ ("$(uname -s)" == "MINGW"*) ]]; then
- BINARIES=(
- mullvad-daemon.exe
- mullvad.exe
- mullvad-problem-report.exe
- talpid_openvpn_plugin.dll
- mullvad-setup.exe
- )
+# Make Windows builds include a manifest in the daemon binary declaring it must
+# be run as admin.
+if [[ "$(uname -s)" == "MINGW"* ]]; then
+ export MULLVAD_ADD_MANIFEST="1"
fi
+################################################################################
+# Compile and build
+################################################################################
+
+log_header "Building Mullvad VPN $PRODUCT_VERSION"
+
function restore_metadata_backups {
- pushd "$SCRIPT_DIR"
+ pushd "$SCRIPT_DIR" > /dev/null
log_info "Restoring version metadata files..."
./version-metadata.sh restore-backup --desktop
mv Cargo.lock.bak Cargo.lock || true
- popd
+ popd > /dev/null
}
trap 'restore_metadata_backups' EXIT
@@ -167,6 +189,8 @@ log_info "Updating version in metadata files..."
cp Cargo.lock Cargo.lock.bak
./version-metadata.sh inject "$PRODUCT_VERSION" --desktop
+
+# Sign all binaries passed as arguments to this function
function sign_win {
local NUM_RETRIES=3
@@ -207,72 +231,98 @@ function build {
# Compile and link all binaries.
################################################################################
- if [[ "$(uname -s)" == "MINGW"* ]]; then
- CPP_BUILD_MODES="Release" ./build-windows-modules.sh "$@"
- fi
-
- ################################################################################
- # Compile wireguard-go
- ################################################################################
+ log_header "Building wireguard-go$for_target_string"
./wireguard/build-wireguard-go.sh "$current_target"
+ if [[ "$SIGN" == "true" && "$(uname -s)" == "MINGW"* ]]; then
+ # Windows can only be built for this one target anyway, so it can be hardcoded.
+ sign_win "build/lib/x86_64-pc-windows-msvc/libwg.dll"
+ fi
- export MULLVAD_ADD_MANIFEST="1"
-
- log_header "Building Rust code in release mode using $RUSTC_VERSION$for_target_string"
+ log_header "Building Rust code in $RUST_BUILD_MODE mode using $RUSTC_VERSION$for_target_string"
- CARGO_TARGET_ARG=()
+ local cargo_target_arg=()
if [[ -n $current_target ]]; then
- CARGO_TARGET_ARG+=(--target="$current_target")
+ cargo_target_arg+=(--target="$current_target")
fi
-
- cargo build "${CARGO_TARGET_ARG[@]}" "${CARGO_ARGS[@]}" --release
+ cargo build "${cargo_target_arg[@]}" "${CARGO_ARGS[@]}"
################################################################################
# Move binaries to correct locations in dist-assets
################################################################################
- for binary in ${BINARIES[*]}; do
- if [[ -n $current_target ]]; then
- SRC="$CARGO_TARGET_DIR/$current_target/release/$binary"
- else
- SRC="$CARGO_TARGET_DIR/release/$binary"
- fi
- if [[ "$(uname -s)" == "Darwin" ]]; then
- # To make it easier to package universal builds on macOS the binaries are located in a
- # directory with the name of the target triple.
- DST_DIR="dist-assets/$current_target"
- DST="$DST_DIR/$binary"
- mkdir -p "$DST_DIR"
- else
- DST="dist-assets/$binary"
- fi
+ if [[ ("$(uname -s)" == "Darwin") ]]; then
+ BINARIES=(
+ mullvad-daemon
+ mullvad
+ mullvad-problem-report
+ libtalpid_openvpn_plugin.dylib
+ mullvad-setup
+ )
+ elif [[ ("$(uname -s)" == "Linux") ]]; then
+ BINARIES=(
+ mullvad-daemon
+ mullvad
+ mullvad-problem-report
+ libtalpid_openvpn_plugin.so
+ mullvad-setup
+ mullvad-exclude
+ )
+ elif [[ ("$(uname -s)" == "MINGW"*) ]]; then
+ BINARIES=(
+ mullvad-daemon.exe
+ mullvad.exe
+ mullvad-problem-report.exe
+ talpid_openvpn_plugin.dll
+ mullvad-setup.exe
+ )
+ fi
- if [[ "$BUILD_MODE" == "release" && "$(uname -s)" == "MINGW"* ]]; then
- sign_win "$SRC"
- fi
+ if [[ -n $current_target ]]; then
+ local src_dir="$CARGO_TARGET_DIR/$current_target/$RUST_BUILD_MODE"
+ # To make it easier to package universal builds on macOS the binaries are located in a
+ # directory with the name of the target triple.
+ local dst_dir="dist-assets/$current_target"
+ mkdir -p "$dst_dir"
+ else
+ local src_dir="$CARGO_TARGET_DIR/$RUST_BUILD_MODE"
+ local dst_dir="dist-assets"
+ fi
+
+ for binary in ${BINARIES[*]}; do
+ local src="$src_dir/$binary"
+ local dst="$dst_dir/$binary"
if [[ "$(uname -s)" == "MINGW"* || "$binary" == *.dylib ]]; then
- log_info "Copying $SRC => $DST"
- cp "$SRC" "$DST"
+ log_info "Copying $src => $dst"
+ cp "$src" "$dst"
else
- log_info "Stripping $SRC => $DST"
- strip "$SRC" -o "$DST"
+ log_info "Stripping $src => $dst"
+ strip "$src" -o "$dst"
+ fi
+
+ if [[ "$SIGN" == "true" && "$(uname -s)" == "MINGW"* ]]; then
+ sign_win "$dst"
fi
done
}
-if [[ "$(uname -s)" == "Darwin" || "$(uname -s)" == "Linux" ]]; then
- mkdir -p "dist-assets/shell-completions"
- for sh in bash zsh fish; do
- log_info "Generating shell completion script for $sh..."
- cargo run --bin mullvad "${CARGO_ARGS[@]}" --release -- shell-completions "$sh" \
- "dist-assets/shell-completions/"
- done
-fi
+if [[ "$(uname -s)" == "MINGW"* ]]; then
+ log_header "Building C++ code in $CPP_BUILD_MODE mode"
+ CPP_BUILD_MODES=$CPP_BUILD_MODE IS_RELEASE=$IS_RELEASE ./build-windows-modules.sh
-./update-relays.sh
-./update-api-address.sh
+ if [[ "$SIGN" == "true" ]]; then
+ signdep=(
+ windows/winfw/bin/x64-$CPP_BUILD_MODE/winfw.dll
+ windows/windns/bin/x64-$CPP_BUILD_MODE/windns.dll
+ windows/winnet/bin/x64-$CPP_BUILD_MODE/winnet.dll
+ windows/driverlogic/bin/x64-$CPP_BUILD_MODE/driverlogic.exe
+ # The nsis plugin is always built in 32 bit release mode
+ windows/nsis-plugins/bin/Win32-Release/*.dll
+ )
+ sign_win "${signdep[@]}"
+ fi
+fi
# Compile for all defined targets, or the current architecture if unspecified.
if [[ -n ${TARGETS:-""} ]]; then
@@ -285,29 +335,33 @@ else
build
fi
-if [[ "$BUILD_MODE" == "release" && "$(uname -s)" == "MINGW"* ]]; then
- signdep=(
- windows/winfw/bin/x64-Release/winfw.dll
- windows/windns/bin/x64-Release/windns.dll
- windows/winnet/bin/x64-Release/winnet.dll
- windows/driverlogic/bin/x64-Release/driverlogic.exe
- windows/nsis-plugins/bin/Win32-Release/*.dll
- build/lib/x86_64-pc-windows-msvc/libwg.dll
- )
- sign_win "${signdep[@]}"
+################################################################################
+# Package app.
+################################################################################
+
+log_header "Preparing for packaging Mullvad VPN $PRODUCT_VERSION"
+
+if [[ "$(uname -s)" == "Darwin" || "$(uname -s)" == "Linux" ]]; then
+ mkdir -p "dist-assets/shell-completions"
+ for sh in bash zsh fish; do
+ log_info "Generating shell completion script for $sh..."
+ cargo run --bin mullvad "${CARGO_ARGS[@]}" -- shell-completions "$sh" \
+ "dist-assets/shell-completions/"
+ done
fi
+log_info "Updating relays.json..."
+cargo run --bin relay_list "${CARGO_ARGS[@]}" > dist-assets/relays.json
+log_info "Updating api-ip-address..."
+cargo run --bin address_cache "${CARGO_ARGS[@]}" > dist-assets/api-ip-address.txt
+
log_header "Installing JavaScript dependencies"
pushd gui
npm ci
-################################################################################
-# Package release.
-################################################################################
-
-log_header "Packing final release artifact(s)"
+log_header "Packing Mullvad VPN $PRODUCT_VERSION artifact(s)"
case "$(uname -s)" in
Linux*) npm run pack:linux -- "${NPM_PACK_ARGS[@]}";;
@@ -323,14 +377,12 @@ for semver_path in dist/*"$SEMVER_VERSION"*; do
log_info "Moving $semver_path -> $product_path"
mv "$semver_path" "$product_path"
- if [[ "$BUILD_MODE" == "release" && "$(uname -s)" == "MINGW"* && "$product_path" == *.exe ]]
- then
+ if [[ "$SIGN" == "true" && "$(uname -s)" == "MINGW"* && "$product_path" == *.exe ]]; then
# sign installer
sign_win "$product_path"
fi
done
-
log_success "**********************************"
log_success ""
log_success " The build finished successfully! "
diff --git a/ci/check-rust.sh b/ci/check-rust.sh
index 3d2bf34f67..e85ce32ec6 100755
--- a/ci/check-rust.sh
+++ b/ci/check-rust.sh
@@ -10,7 +10,7 @@ export RUSTFLAGS="--deny warnings"
# Build Windows modules
case "$(uname -s)" in
MINGW*|MSYS_NT*)
- time ./build-windows-modules.sh --dev-build
+ time ./build-windows-modules.sh
;;
esac