diff options
Diffstat (limited to 'python/mozboot/mozboot/mozillabuild.py')
-rw-r--r-- | python/mozboot/mozboot/mozillabuild.py | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/python/mozboot/mozboot/mozillabuild.py b/python/mozboot/mozboot/mozillabuild.py new file mode 100644 index 0000000000..c783809656 --- /dev/null +++ b/python/mozboot/mozboot/mozillabuild.py @@ -0,0 +1,235 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import ctypes +import os +import platform +import subprocess +import sys +from pathlib import Path + +from mozbuild.util import mozilla_build_version +from packaging.version import Version + +from mozboot.base import BaseBootstrapper + + +def is_aarch64_host(): + from ctypes import wintypes + + kernel32 = ctypes.windll.kernel32 + IMAGE_FILE_MACHINE_UNKNOWN = 0 + IMAGE_FILE_MACHINE_ARM64 = 0xAA64 + + try: + iswow64process2 = kernel32.IsWow64Process2 + except Exception: + # If we can't access the symbol, we know we're not on aarch64. + return False + + currentProcess = kernel32.GetCurrentProcess() + processMachine = wintypes.USHORT(IMAGE_FILE_MACHINE_UNKNOWN) + nativeMachine = wintypes.USHORT(IMAGE_FILE_MACHINE_UNKNOWN) + + gotValue = iswow64process2( + currentProcess, ctypes.byref(processMachine), ctypes.byref(nativeMachine) + ) + # If this call fails, we have no idea. + if not gotValue: + return False + + return nativeMachine.value == IMAGE_FILE_MACHINE_ARM64 + + +def get_is_windefender_disabled(): + import winreg + + try: + with winreg.OpenKeyEx( + winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows Defender" + ) as windefender_key: + is_antivirus_disabled, _ = winreg.QueryValueEx( + windefender_key, "DisableAntiSpyware" + ) + # is_antivirus_disabled is either 0 (False) or 1 (True) + return bool(is_antivirus_disabled) + except FileNotFoundError: + return True + + +def get_windefender_exclusion_paths(): + import winreg + + paths = [] + try: + with winreg.OpenKeyEx( + winreg.HKEY_LOCAL_MACHINE, + r"SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths", + ) as exclusions_key: + _, values_count, __ = winreg.QueryInfoKey(exclusions_key) + for i in range(0, values_count): + path, _, __ = winreg.EnumValue(exclusions_key, i) + paths.append(Path(path)) + except FileNotFoundError: + pass + + return paths + + +def is_windefender_affecting_srcdir(src_dir: Path): + if get_is_windefender_disabled(): + return False + + # When there's a match, but path cases aren't the same between srcdir and exclusion_path, + # commonpath will use the casing of the first path provided. + # To avoid surprises here, we normcase(...) so we don't get unexpected breakage if we change + # the path order. + src_dir = src_dir.resolve() + + try: + exclusion_paths = get_windefender_exclusion_paths() + except OSError as e: + if e.winerror == 5: + # A version of Windows 10 released in 2021 raises an "Access is denied" + # error (ERROR_ACCESS_DENIED == 5) to un-elevated processes when they + # query Windows Defender's exclusions. Skip the exclusion path checking. + return + raise + + for exclusion_path in exclusion_paths: + exclusion_path = exclusion_path.resolve() + try: + if Path(os.path.commonpath((exclusion_path, src_dir))) == exclusion_path: + # exclusion_path is an ancestor of srcdir + return False + except ValueError: + # ValueError: Paths don't have the same drive - can't be ours + pass + return True + + +class MozillaBuildBootstrapper(BaseBootstrapper): + """Bootstrapper for MozillaBuild to install rustup.""" + + def __init__(self, no_interactive=False, no_system_changes=False): + BaseBootstrapper.__init__( + self, no_interactive=no_interactive, no_system_changes=no_system_changes + ) + + def validate_environment(self): + if self.application.startswith("mobile_android"): + print( + "WARNING!!! Building Firefox for Android on Windows is not " + "fully supported. See https://bugzilla.mozilla.org/show_bug." + "cgi?id=1169873 for details.", + file=sys.stderr, + ) + + if is_windefender_affecting_srcdir(self.srcdir): + print( + "Warning: the Firefox checkout directory is currently not in the " + "Windows Defender exclusion list. This can cause the build process " + "to be dramatically slowed or broken. To resolve this, follow the " + "directions here: " + "https://firefox-source-docs.mozilla.org/setup/windows_build.html" + "#antivirus-performance", + file=sys.stderr, + ) + + def install_system_packages(self): + pass + + def upgrade_mercurial(self, current): + # Mercurial upstream sometimes doesn't upload wheels, and building + # from source requires MS Visual C++ 9.0. So we force pip to install + # the last version that comes with wheels. + if mozilla_build_version() >= Version("4.0"): + pip_dir = ( + Path(os.environ["MOZILLABUILD"]) / "python3" / "Scripts" / "pip.exe" + ) + else: + pip_dir = ( + Path(os.environ["MOZILLABUILD"]) / "python" / "Scripts" / "pip.exe" + ) + + command = [ + str(pip_dir), + "install", + "--upgrade", + "mercurial", + "--only-binary", + "mercurial", + ] + self.run(command) + + def install_browser_packages(self, mozconfig_builder): + pass + + def install_browser_artifact_mode_packages(self, mozconfig_builder): + pass + + def _os_arch(self): + os_arch = platform.machine() + if os_arch == "AMD64": + # On Windows, x86_64 is reported as AMD64 but we use x86_64 + # everywhere else, so let's normalized it here. + return "x86_64" + return os_arch + + def install_mobile_android_packages(self, mozconfig_builder, artifact_mode=False): + from mozboot import android + + os_arch = self._os_arch() + android.ensure_android( + "windows", + os_arch, + artifact_mode=artifact_mode, + no_interactive=self.no_interactive, + ) + android.ensure_android( + "windows", + os_arch, + system_images_only=True, + artifact_mode=artifact_mode, + no_interactive=self.no_interactive, + avd_manifest_path=android.AVD_MANIFEST_X86_64, + ) + android.ensure_android( + "windows", + os_arch, + system_images_only=True, + artifact_mode=artifact_mode, + no_interactive=self.no_interactive, + avd_manifest_path=android.AVD_MANIFEST_ARM, + ) + + def ensure_mobile_android_packages(self): + from mozboot import android + + android.ensure_java("windows", self._os_arch()) + self.install_toolchain_artifact(android.WINDOWS_X86_64_ANDROID_AVD) + self.install_toolchain_artifact(android.WINDOWS_ARM_ANDROID_AVD) + + def install_mobile_android_artifact_mode_packages(self, mozconfig_builder): + self.install_mobile_android_packages(mozconfig_builder, artifact_mode=True) + + def generate_mobile_android_mozconfig(self, artifact_mode=False): + from mozboot import android + + return android.generate_mozconfig("windows", artifact_mode=artifact_mode) + + def generate_mobile_android_artifact_mode_mozconfig(self): + return self.generate_mobile_android_mozconfig(artifact_mode=True) + + def ensure_sccache_packages(self): + from mozboot import sccache + + self.install_toolchain_artifact(sccache.RUSTC_DIST_TOOLCHAIN, no_unpack=True) + self.install_toolchain_artifact(sccache.CLANG_DIST_TOOLCHAIN, no_unpack=True) + + def _update_package_manager(self): + pass + + def run(self, command): + subprocess.check_call(command, stdin=sys.stdin) |