brizental pushed to branch mullvad-browser-147.0a1-16.0-2 at The Tor Project / Applications / Mullvad Browser Commits: e913cc4c by Beatriz Rizental at 2026-01-26T10:35:04-03:00 fixup! BB 43564: Modify ./mach bootstrap for Base Browser Generalize extension symlinking code. - - - - - d3c6d733 by Beatriz Rizental at 2026-01-26T11:09:02-03:00 MB 43564: Modify ./mach bootstrap for Mullvad Browser - - - - - 5 changed files: - build/moz.configure/basebrowser-resources.configure - build/moz.configure/bootstrap.configure - python/mozboot/mozboot/bootstrap.py - python/mozbuild/mozbuild/backend/base.py - python/mozbuild/mozbuild/tbbutils.py Changes: ===================================== build/moz.configure/basebrowser-resources.configure ===================================== @@ -27,7 +27,7 @@ option( "noscript", no_unpack=True, when=depends("--with-noscript")(lambda x: not x) ), ) -@checking("for noscript") +@checking("for noscript extension") @imports(_from="pathlib", _import="Path") def noscript(value, mozbuild_state_path, _bootstrapped): if value: @@ -49,6 +49,84 @@ def noscript(value, mozbuild_state_path, _bootstrapped): set_config("NOSCRIPT", noscript) +option( + "--with-ublock", + env="UBLOCK", + nargs=1, + default=None, + help="Path to ublock .xpi extension archive.", +) + + +@depends( + "--with-ublock", + mozbuild_state_path, + bootstrap_path( + "ublock", no_unpack=True, when=depends("--with-ublock")(lambda x: not x) + ), +) +@checking("for ublock extension") +@imports(_from="pathlib", _import="Path") +def ublock(value, mozbuild_state_path, _bootstrapped): + if value: + path = Path(value[0]) + if path.is_file() and path.suffix == ".xpi": + return value[0] + else: + die("--with-ublock must be an existing .xpi file") + + bootstrapped_location = Path(mozbuild_state_path) / "browser" + for file in bootstrapped_location.glob(f"*.xpi"): + if "ublock" in file.name: + return str(bootstrapped_location / file) + + # ublock is not required for building. + return None + + +set_config("UBLOCK", ublock) + + +option( + "--with-mullvad-extension", + env="MULLVAD_EXTENSION", + nargs=1, + default=None, + help="Path to mullvad extension .xpi extension archive.", +) + + +@depends( + "--with-mullvad-extension", + mozbuild_state_path, + bootstrap_path( + "mullvad-browser-extension", + no_unpack=True, + when=depends("--with-mullvad-extension")(lambda x: not x), + ), +) +@checking("for mullvad extension") +@imports(_from="pathlib", _import="Path") +def mullvad_extension(value, mozbuild_state_path, _bootstrapped): + if value: + path = Path(value[0]) + if path.is_file() and path.suffix == ".xpi": + return value[0] + else: + die("--with-mullvad-extension must be an existing .xpi file") + + bootstrapped_location = Path(mozbuild_state_path) / "browser" + for file in bootstrapped_location.glob(f"*.xpi"): + if "mullvad-browser-extension" in file.name: + return str(bootstrapped_location / file) + + # mullvad extension is not required for building. + return None + + +set_config("MULLVAD_EXTENSION", mullvad_extension) + + option( "--with-tor-browser-fonts", env="TOR_BROWSER_FONTS", ===================================== build/moz.configure/bootstrap.configure ===================================== @@ -197,8 +197,12 @@ def bootstrap_path(path, **kwargs): if path_parts[0] == "clang-tools": path_prefix = path_parts.pop(0) - # Small hack because noscript is inside the browser folder. - if path_parts[0] == "noscript": + # Small hack because extensions are inside the browser folder. + if path_parts[0] in ( + "noscript", + "ublock", + "mullvad-browser-extension", + ): path_prefix = "browser" def try_tbb_bootstrap(exists): ===================================== python/mozboot/mozboot/bootstrap.py ===================================== @@ -49,28 +49,28 @@ Note on Artifact Mode: Artifact builds download prebuilt C++ components rather than building them locally. Artifact builds are faster! -Artifact builds are recommended for people working on Tor Browser or +Artifact builds are recommended for people working on Mullvad Browser or Base Browser for Android frontends, or the GeckoView Java API. They are unsuitable for those working on C++ code. For more information see: https://firefox-source-docs.mozilla.org/contributing/build/artifact_builds.h.... -# Note to Base Browser developers +# Note to Mullvad Browser developers This is still highly experimental. Expect bugs! -Please choose the version of Base Browser you want to build (see note above): +Please choose the version of Mullvad Browser you want to build (see note above): %s Your choice: """ APPLICATIONS = OrderedDict( [ - ("Base Browser for Desktop Artifact Mode", "browser_artifact_mode"), - ("Base Browser for Desktop", "browser"), + ("Mullvad Browser for Desktop Artifact Mode", "browser_artifact_mode"), + ("Mullvad Browser for Desktop", "browser"), ( - "GeckoView/Base Browser for Android Artifact Mode", + "GeckoView/Mullvad Browser for Android Artifact Mode", "mobile_android_artifact_mode", ), - ("GeckoView/Base Browser for Android", "mobile_android"), + ("GeckoView/Mullvad Browser for Android", "mobile_android"), ("SpiderMonkey JavaScript engine", "js"), ] ) ===================================== python/mozbuild/mozbuild/backend/base.py ===================================== @@ -243,22 +243,47 @@ class BuildBackend(LoggingMixin): with open(mozpath.join(dir, ".purgecaches"), "w") as f: f.write("\n") - def _setup_tor_browser_environment(self, config): + def _create_or_replace_symlink(self, src, dst): + try: + os.symlink(src, dst) + except OSError as e: + if e.errno == errno.EEXIST: + # If the symlink already exists, remove it and try again. + os.remove(dst) + os.symlink(src, dst) + else: + return + + def _setup_extension_symlink(self, location, target_filename, exts_path): + if not location: + return + + target = exts_path / target_filename + + self.log( + logging.INFO, + "_setup_extension_symlink", + { + "location": location, + "target": str(target), + }, + "Creating symlink for extension from {location} to {target}", + ) + + exts_path.mkdir(parents=True, exist_ok=True) + self._create_or_replace_symlink(location, target) + + def _setup_base_browser_environment(self, config): app = config.substs["MOZ_BUILD_APP"] noscript_target_filename = "{73a6fe31-595d-460b-a920-fcc0f8843232}.xpi" noscript_location = config.substs.get("NOSCRIPT") - def _infallible_symlink(src, dst): - try: - os.symlink(src, dst) - except OSError as e: - if e.errno == errno.EEXIST: - # If the symlink already exists, remove it and try again. - os.remove(dst) - os.symlink(src, dst) - else: - return + ublock_target_filename = "uBlock0@raymondhill.net.xpi" + ublock_location = config.substs.get("UBLOCK") + + mullvad_extension_target_filename = "{d19a89b9-76c1-4a61-bcd4-49e8de916403}.xpi" + mullvad_extension_location = config.substs.get("MULLVAD_EXTENSION") if app == "browser": tbdir = Path(config.topobjdir) / "dist" / "bin" @@ -281,7 +306,7 @@ class BuildBackend(LoggingMixin): if fonts_location: self.log( logging.INFO, - "_setup_tor_browser_environment", + "_setup_base_browser_environment", { "fonts_location": fonts_location, "fonts_target": str(paths["fonts"]), @@ -291,23 +316,25 @@ class BuildBackend(LoggingMixin): for file in Path(fonts_location).iterdir(): target = paths["fonts"] / file.name - _infallible_symlink(file, target) + self._create_or_replace_symlink(file, target) - # Set up NoScript extension - if noscript_location: - noscript_target = paths["exts"] / noscript_target_filename - self.log( - logging.INFO, - "_setup_tor_browser_environment", - { - "noscript_location": noscript_location, - "noscript_target": str(noscript_target), - }, - "Creating symlink for NoScript from {noscript_location} to {noscript_target}", - ) + self._setup_extension_symlink( + noscript_location, + noscript_target_filename, + paths["exts"], + ) - paths["exts"].mkdir(parents=True, exist_ok=True) - _infallible_symlink(noscript_location, noscript_target) + self._setup_extension_symlink( + ublock_location, + ublock_target_filename, + paths["exts"], + ) + + self._setup_extension_symlink( + mullvad_extension_location, + mullvad_extension_target_filename, + paths["exts"], + ) def post_build(self, config, output, jobs, verbose, status): """Called late during 'mach build' execution, after `build(...)` has finished. @@ -328,7 +355,7 @@ class BuildBackend(LoggingMixin): self._write_purgecaches(config) if status == 0: - self._setup_tor_browser_environment(config) + self._setup_base_browser_environment(config) return status ===================================== python/mozbuild/mozbuild/tbbutils.py ===================================== @@ -22,10 +22,12 @@ def list_files_http(url): return links -TOR_BROWSER_BUILD_ARTIFACTS = [ - # Tor Browser Build-only artifacts, these artifacts are not common with Firefox. +MULLVAD_BROWSER_BUILD_ARTIFACTS = [ + # Mullvad Browser Build-only artifacts, these artifacts are not common with Firefox. + "mullvad-browser-extension", "noscript", "fonts", + "ublock", ] # Mapping of artifacts from taskcluster to tor-browser-build. @@ -55,7 +57,7 @@ def get_artifact_index(artifact_path): def get_artifact_name(original_artifact_name, host): # These are not build artifacts, they are pre-built artifacts to be added to the final build, # therefore this check can come before the host check. - if original_artifact_name in TOR_BROWSER_BUILD_ARTIFACTS: + if original_artifact_name in MULLVAD_BROWSER_BUILD_ARTIFACTS: return original_artifact_name if host != "linux64": View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/58b... -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/58b... You're receiving this email because of your account on gitlab.torproject.org.