commit 5571ee922b6240f550087cfead945cc0b8bbc6a7 parent aada8c2df0e7e75cf7c3e3a0f3aaedb65c88b5f9 Author: Richard Pospesel <richard@torproject.org> Date: Mon, 1 Aug 2022 17:56:45 +0000 TB 41089: Add tor-browser build scripts + Makefile to tor-browser Diffstat:
21 files changed, 472 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore @@ -400,3 +400,6 @@ CLAUDE.local.md # Ignore .json.gz (typically profiles) in the root directory # lint-ignore-next-line: git-only /*.json.gz + +# Ignore binary base of Tor Browser +.binaries diff --git a/tools/geckoview/.gitignore b/tools/geckoview/.gitignore @@ -0,0 +1 @@ +android-env.sh diff --git a/tools/geckoview/Makefile b/tools/geckoview/Makefile @@ -0,0 +1,60 @@ +.DEFAULT_GOAL := all + +# one of armv7 aarch64 x86 x86_64 +ARCH := aarch64 +ANDROID_ARCH := $(ARCH) +ifeq ($(ANDROID_ARCH),aarch64) + ANDROID_ARCH := arm64-v8a +endif +ifeq ($(ANDROID_ARCH),armv7) + ANDROID_ARCH := armeabi-v7a +endif + +OS="${shell uname}" + +# https://stackoverflow.com/questions/18136918/how-to-get-current-relative-directory-of-your-makefile +mkfile_path := "$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))" + +DEV_ROOT = "$(mkfile_path)/../.." + +clobber: env + ./clobber.sh $(DEV_ROOT) $(ARCH) + +config: env + ./config.sh $(DEV_ROOT) $(ARCH) + +geckoview: env + ./build-geckoview.sh $(DEV_ROOT) $(ARCH) + +# These targets do not depend on GeckoView so that you can build only Fenix if +# you are not changing GV code. +fenix-release: env + ./build-fenix.sh $(DEV_ROOT) $(ARCH) Release +fenix-beta: env + ./build-fenix.sh $(DEV_ROOT) $(ARCH) Beta +fenix-nightly: env + ./build-fenix.sh $(DEV_ROOT) $(ARCH) Nightly +fenix-debug: env + ./build-fenix.sh $(DEV_ROOT) $(ARCH) Debug + +env: + test -e android-env.sh || { echo "copy android-env-...-template.sh to android-env.sh and edit appropriatly"; exit 1; } + +install-release: + ./install-fenix.sh $(DEV_ROOT) $(ARCH) $(ANDROID_ARCH) release +install-beta: + ./install-fenix.sh $(DEV_ROOT) $(ARCH) $(ANDROID_ARCH) beta +install-nightly: + ./install-fenix.sh $(DEV_ROOT) $(ARCH) $(ANDROID_ARCH) nightly +install-debug: + ./install-fenix.sh $(DEV_ROOT) $(ARCH) $(ANDROID_ARCH) debug + +all: env geckoview fenix-nightly install-nightly +all-release: env geckoview fenix-release install-release +all-beta: env geckoview fenix-beta install-beta + +jslint: + ./jslint.sh $(DEV_ROOT) $(JS) + +clean: + rm -rf $(BUILD_OUTPUT) diff --git a/tools/geckoview/android-env-linux-template.sh b/tools/geckoview/android-env-linux-template.sh @@ -0,0 +1,6 @@ +export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 +export ANDROID_HOME=$HOME/.mozbuild/android-sdk-linux/ # or $HOME/Android/Sdk/ # Or .../android-toolchain/android-sdk-linux if you extract android-toolchain from tor-browser-build +export ANDROID_NDK_HOME=$HOME/.mozbuild/android-ndk-r28b/ # for 140esr +export GRADLE_HOME=$HOME/.mozbuild/gradle-8.14.3 # not included by default, need to download from https://gradle.org/releases/ and put the extracted directory "gradle-8.14.3" into ~/.mozbuild/ +export LOCAL_DEV_BUILD=1 +export PATH=/FULL/PATH/TO/tor-browser-build/out/clang/clang-16.x.y-arm/bin/:$PATH # prepend our newly built and assembled clang to the path so it gets used to build geckoview diff --git a/tools/geckoview/android-env-macos-template.sh b/tools/geckoview/android-env-macos-template.sh @@ -0,0 +1,6 @@ +export JAVA_HOME=/opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home # for arm64. Or JAVA_HOME=/usr/local/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home for x86_64. +export ANDROID_HOME=$HOME/.mozbuild/android-sdk-macosx +export ANDROID_NDK_HOME=$HOME/.mozbuild/android-ndk-r28b # for ESR140 +export GRADLE_HOME=$HOME/.mozbuild/gradle-8.14.3 # not included by default, need to download from https://gradle.org/releases/ and put the extracted directory "gradle-8.14.3" into ~/.mozbuild/ +export LOCAL_DEV_BUILD=1 +export PATH=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin:$PATH # prepend mozbuilds NDK to the PATH so it's clang gets used to build geckoview diff --git a/tools/geckoview/build-fenix.sh b/tools/geckoview/build-fenix.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -e +DEV_ROOT=$1 +ARCH=$2 +VARIANT=$3 + +source android-env.sh + +cd $DEV_ROOT +OBJ_DIR=$(MOZCONFIG=mozconfig-android-$ARCH ./mach environment --format json --verbose | jq -r .topobjdir) +cd mobile/android/fenix +MOZCONFIG=mozconfig-android-$ARCH $GRADLE_HOME/bin/gradle --no-daemon -Dorg.gradle.jvmargs=-Xmx20g -PdisableOptimization assemble$VARIANT +tools/tba-sign-devbuilds.sh "$OBJ_DIR" diff --git a/tools/geckoview/build-geckoview.sh b/tools/geckoview/build-geckoview.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e +DEV_ROOT=$1 +ARCH=$2 + +source android-env.sh + +cd $DEV_ROOT +MOZCONFIG=mozconfig-android-$ARCH ./mach build diff --git a/tools/geckoview/clobber.sh b/tools/geckoview/clobber.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e +DEV_ROOT=$1 +ARCH=$2 + +source android-env.sh + +cd $DEV_ROOT +MOZCONFIG=mozconfig-android-$ARCH ./mach clobber diff --git a/tools/geckoview/config.sh b/tools/geckoview/config.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e +DEV_ROOT=$1 +ARCH=$2 + +source android-env.sh + +cd $DEV_ROOT +MOZCONFIG=mozconfig-android-$ARCH ./mach configure --without-wasm-sandboxed-libraries diff --git a/tools/geckoview/install-fenix.sh b/tools/geckoview/install-fenix.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -e +DEV_ROOT=$1 +ARCH=$2 +ANDROID_ARCH=$3 +VARIANT=$4 + +cd $DEV_ROOT +OBJ_DIR=$(MOZCONFIG=mozconfig-android-$ARCH ./mach environment --format json --verbose | jq -r .topobjdir) + +if [ $VARIANT == "debug" ] +then + adb install "$OBJ_DIR/gradle/build/mobile/android/fenix/app/outputs/apk/fenix/$VARIANT/app-fenix-$ANDROID_ARCH-$VARIANT.apk" +else + adb install "$OBJ_DIR/gradle/build/mobile/android/fenix/app/outputs/apk/fenix/$VARIANT/app-fenix-$ANDROID_ARCH-$VARIANT-signed.apk" +fi diff --git a/tools/geckoview/jslint.sh b/tools/geckoview/jslint.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e +DEV_ROOT=$1 +JS_FILE=$2 + +source android-env.sh + +cd $DEV_ROOT +./mach lint -l eslint --fix $JS_FILE diff --git a/tools/torbrowser/Makefile b/tools/torbrowser/Makefile @@ -0,0 +1,72 @@ +.DEFAULT_GOAL := all + +# https://stackoverflow.com/questions/18136918/how-to-get-current-relative-directory-of-your-makefile +mkfile_path := "$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))" + +DEV_ROOT = "$(mkfile_path)/../.." +BINARIES = "$(DEV_ROOT)/.binaries" +ARCHITECTURE = "$(shell uname -m)" + +# Correct the architecture naming for ARM to match what mozilla has +ifeq ($(ARCHITECTURE), "arm64") + ARCHITECTURE = "aarch64" +endif + +ifeq ($(ARCHITECTURE), "aarch64") + LINUX_VENDOR = "unknown" +else + LINUX_VENDOR = "pc" +endif + +# Define build output path based on the platform. +ifeq ("$(shell uname)", "Darwin") + BUILD_OUTPUT = "$(DEV_ROOT)/obj-$(ARCHITECTURE)-apple-darwin$(shell uname -r)" +else + BUILD_OUTPUT = "$(DEV_ROOT)/obj-$(ARCHITECTURE)-$(LINUX_VENDOR)-linux-gnu" +endif + +# Define the run command based on the platform. +ifeq ("$(shell uname)", "Darwin") + RUN_CMD := cd "$(BINARIES)/Tor Browser.app/Contents/MacOS/" && ./firefox --purgecaches +else + RUN_CMD := "$(BINARIES)/dev/Browser/start-tor-browser" -v --purgecaches $(ARGS) +endif + +config: + ./config.sh $(DEV_ROOT) + +ide-vscode: + ./ide.sh vscode $(DEV_ROOT) + +ide-eclipse: + ./ide.sh eclipse $(DEV_ROOT) + +ide-visualstudio: + ./ide.sh visualstudio $(DEV_ROOT) + +fetch: + ./fetch.sh $(BINARIES) + +build: + ./build.sh $(DEV_ROOT) + +deploy: + ./deploy.sh $(BINARIES) $(BUILD_OUTPUT) + +prepare-tests: + ./prepare-tests.sh $(BINARIES) $(BUILD_OUTPUT) + +all: build deploy + +run: + $(RUN_CMD) + +jslint: + ./jslint.sh $(DEV_ROOT) $(JS) + +clobber: + ./clobber.sh $(DEV_ROOT) + +clean: + rm -rf $(BUILD_OUTPUT) + diff --git a/tools/torbrowser/browser-self-sign-macos.sh b/tools/torbrowser/browser-self-sign-macos.sh @@ -0,0 +1,110 @@ +#!/bin/bash + +CERTNAME=my-codesign-cert-tor +BROWSERPATH=. + +if [ $# -ge 1 ] +then + BROWSERPATH=$1 +fi + + +security find-certificate -c $CERTNAME > /dev/null + +if [ $? -ne 0 ] +then + echo "" + echo "ERROR: Self Signing Certificate not found, please create:" + echo " 1. In the Keychain Access app on your Mac, choose Keychain Access > Certificate Assistant > Create a Certificate." + echo " 2. Enter the name '$CERTNAME' for the certificate" + echo " 3. Choose an identity type: Self Signed Root" + echo " 4. Certificate Type > Code Signing" + echo " 5. Check 'Let me override defaults' & click Continue." + echo " 6. Enter a unique Serial Number. (123 is fine)" + echo " 7. Enter a big Validity Period (days), like 3560 & click Continue." + echo " 8. Fill in your personal information & click Continue." + echo " 9. Accept defaults for the rest of the dialog boxes. (Continue several times)" + echo " 10. Certificate Created! Click Done." + echo "" + echo "For additional help see:" + echo " https://support.apple.com/en-ca/guide/keychain-access/kyca8916/mac" + echo " https://stackoverflow.com/questions/58356844/what-are-the-ways-or-technologies-to-sign-an-executable-application-file-in-mac" + + echo "" + read -n 1 -r -s -p $'Press enter to launch "Keychain Access"...\n' + open /System/Applications/Utilities/Keychain\ Access.app + + exit -1 +fi + +echo "Found $CERTNAME, looking for browser to sign..." + +if [ ! -f "$BROWSERPATH/XUL" ] +then + TESTPATH="$BROWSERPATH/Contents/MacOS" + if [ -f "$TESTPATH/XUL" ] + then + BROWSERPATH=$TESTPATH + else + echo "Error: browser files not detected in $BROWSERPATH!" + echo " This script needs to be run in the 'Contents/MacOS' directory of a SomeBrowser.app directory" + exit -1 + fi +fi + +echo "Mozilla based browser found, signing..." +echo ' Will be asked for password to certificate for all the things that need to be signed. Click "Always Allow" to automate' + +cd "$BROWSERPATH" + +codesign -s $CERTNAME *.dylib +codesign -s $CERTNAME plugin-container.app + +if [ -d Tor ] +then + codesign -s $CERTNAME Tor/PluggableTransports/* + codesign -s $CERTNAME Tor/libevent-2.1.7.dylib + if [ -f Tor/tor.real ] + then + codesign -s $CERTNAME Tor/tor.real + fi + if [ -f Tor/tor ] + then + codesign -s $CERTNAME Tor/tor + fi +fi + +codesign -s $CERTNAME XUL + +if [ -d updater.app ] +then + codesign -s $CERTNAME updater.app +fi + +# mullvadbrowser +if [ -f mullvadbrowser ] +then + codesign -s $CERTNAME mullvadbrowser +fi + +# BB or TB +if [ -f firefox ] +then + codesign -s $CERTNAME firefox +fi + +echo "" +echo "Browser signing step done!" +echo "" + +echo "App still needs one more override to be easily opened with double click in Finder" +echo "Alternatively you can right click it, select 'Open' and then select 'Open' from the override popup" +echo "Or to enable it to be double clicked to open perform the following" +echo "" +echo "Double click the app and select either 'Ok' or 'Cancel' from the warning popup depending on which you get (Do Not 'Move to Trash')" +echo 'Go to Preferences -> Security & Privacy and click on padlock to allow changes. ' +echo ' Then in "Allow appications downloaded from" select either:' +echo ' - App Store and identified developers' +echo ' - Anywhere' +echo ' Below that may be a notice about your specific app saying it was blocked because it was not from an identified developer. Click "Open Anyways" and "Open"' + diff --git a/tools/torbrowser/build.sh b/tools/torbrowser/build.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -e +DEV_ROOT=$1 + +cd $DEV_ROOT +./mach build + +if [ -z "$LOCALES" ]; then + ./mach build stage-package +else + export MOZ_CHROME_MULTILOCALE=$LOCALES + # No quotes on purpose + ./mach package-multi-locale --locales en-US $MOZ_CHROME_MULTILOCALE + AB_CD=multi ./mach build stage-package +fi diff --git a/tools/torbrowser/clobber.sh b/tools/torbrowser/clobber.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -e +DEV_ROOT=$1 + +cd $DEV_ROOT +./mach clobber diff --git a/tools/torbrowser/config.sh b/tools/torbrowser/config.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -e +DEV_ROOT=$1 + +cd $DEV_ROOT +./mach configure diff --git a/tools/torbrowser/deploy.sh b/tools/torbrowser/deploy.sh @@ -0,0 +1,43 @@ +#!/bin/bash +set -e + +BINARIES="$1" +BUILD_OUTPUT="$2" +SCRIPT_DIR="$(realpath "$(dirname "$0")")" + +RESDIR="$BUILD_OUTPUT/dist/firefox" +if [ "$(uname)" = "Darwin" ]; then + RESDIR="$RESDIR/Tor Browser.app/Contents/Resources" +fi + +# Repackage the manual +# rm -rf $BUILD_OUTPUT/_omni +# mkdir $BUILD_OUTPUT/_omni +# unzip $BINARIES/dev/Browser/browser/omni.ja -d $BUILD_OUTPUT/_omni +# cd $BUILD_OUTPUT/_omni && zip -Xmr $RESDIR/browser/omni.ja chrome/browser/content/browser/manual +# rm -rf $BUILD_OUTPUT/_omni + +if [ "$(uname)" = "Darwin" ]; then + + # copy binaries + cp -r "$BUILD_OUTPUT/dist/firefox/"*.app/Contents/* "$BINARIES/Tor Browser.app/Contents/" + rm -rf "$BINARIES/TorBrowser-Data/Browser/Caches/*.default/startupCache" + + # Self sign the Binaries + cd "$BINARIES/Tor Browser.app/Contents/MacOS" + "$SCRIPT_DIR/browser-self-sign-macos.sh" + +else + + # backup the startup script + mv "$BINARIES/dev/Browser/firefox" "$BINARIES/dev/Browser/firefox.bak" + + # copy binaries + cp -r "$RESDIR/"* "$BINARIES/dev/Browser" + rm -rf "$BINARIES/dev/Browser/TorBrowser/Data/Browser/profile.default/startupCache" + + # shuffle firefox bin around and restore script to match a real deployment + mv "$BINARIES/dev/Browser/firefox" "$BINARIES/dev/Browser/firefox.real" + mv "$BINARIES/dev/Browser/firefox.bak" "$BINARIES/dev/Browser/firefox" + +fi diff --git a/tools/torbrowser/fetch.sh b/tools/torbrowser/fetch.sh @@ -0,0 +1,40 @@ +#!/bin/sh +set -e + +BINARIES_DIR="$1" + +# download the current downloads.json +wget https://aus1.torproject.org/torbrowser/update_3/alpha/downloads.json +# get url for latest alpha linux package +TOR_BROWSER_VERSION=$(grep -Eo "\"version\"\s*:\s*\"[0-9.a]+\"" downloads.json | grep -Eo "[0-9.a]+") +if [ "$(uname)" = "Darwin" ]; then + TOR_BROWSER_PACKAGE="tor-browser-macos-${TOR_BROWSER_VERSION}.dmg" + else + TOR_BROWSER_PACKAGE="tor-browser-linux-$(uname -m)-${TOR_BROWSER_VERSION}.tar.xz" +fi +TOR_BROWSER_PACKAGE_URL="https://dist.torproject.org/torbrowser/${TOR_BROWSER_VERSION}/${TOR_BROWSER_PACKAGE}" + +# remove download manifest +rm downloads.json + +# clear out previous tor-browser and previous package +rm -rf "${BINARIES_DIR}" +rm -f "${TOR_BROWSER_PACKAGE}" + +# download +wget "${TOR_BROWSER_PACKAGE_URL}" +mkdir -p "${BINARIES_DIR}" + +# and extract +if [ "$(uname)" = "Darwin" ] + then + hdiutil attach "${TOR_BROWSER_PACKAGE}" + cp -R "/Volumes/Tor Browser Alpha/Tor Browser Alpha.app" "${BINARIES_DIR}/Tor Browser.app" + hdiutil detach "/Volumes/Tor Browser Alpha" + else + tar -xf "${TOR_BROWSER_PACKAGE}" -C "${BINARIES_DIR}" + mv "${BINARIES_DIR}/tor-browser" "${BINARIES_DIR}/dev" +fi + +# Final cleanup +rm -f "${TOR_BROWSER_PACKAGE}" diff --git a/tools/torbrowser/ide.sh b/tools/torbrowser/ide.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -e +IDE=$1 +DEV_ROOT=$2 + +cd $DEV_ROOT +./mach ide $IDE diff --git a/tools/torbrowser/jslint.sh b/tools/torbrowser/jslint.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -e +DEV_ROOT=$1 +JS_FILE=$2 + +cd $DEV_ROOT +./mach lint -l eslint --fix $JS_FILE diff --git a/tools/torbrowser/prepare-tests.sh b/tools/torbrowser/prepare-tests.sh @@ -0,0 +1,25 @@ +#!/bin/sh +set -e + +BINARIES="$1" +BUILD_OUTPUT="$2" + +if [ ! -d "$BUILD_OUTPUT" ]; then + echo "Error: $BUILD_OUTPUT directory does not exist." + echo "Make sure to run `mach ./build` or `make -C tools/torbrowser build`." + exit 1 +fi + +if [ ! -d "$BINARIES" ]; then + echo "Error: $BINARIES directory does not exist." + echo "Make sure to run `make -C tools/torbrowser fetch`." + exit 1 +fi + +if [ "$(uname)" = "Darwin" ]; then + cp -r "$BINARIES/Tor Browser.app/Contents/MacOS/Tor" "$BUILD_OUTPUT/dist/firefox/"*.app/Contents/MacOS + cp -r "$BINARIES/Tor Browser.app/Contents/Resources/fonts" "$BUILD_OUTPUT/dist/firefox/"*.app/Contents/Resources +else + cp -r "$BINARIES/dev/Browser/fonts" "$BUILD_OUTPUT/dist/bin" + cp -r "$BINARIES/dev/Browser/TorBrowser" "$BUILD_OUTPUT/dist/bin" +fi