Example #1
0
    def build_cef(self,
                  jobs=None,
                  verbose=False,
                  release=False,
                  with_debug_assertions=False):
        self.ensure_bootstrapped()
        self.ensure_clobbered()

        ret = None
        opts = []
        opts += ["--manifest-path", self.cef_manifest()]

        if jobs is not None:
            opts += ["-j", jobs]
        if verbose:
            opts += ["-v"]
        if release:
            opts += ["--release"]

        servo_features = self.servo_features()
        if servo_features:
            opts += ["--features", "%s" % ' '.join(servo_features)]

        build_start = time()
        env = self.build_env(is_build=True)

        if with_debug_assertions:
            env["RUSTFLAGS"] = "-C debug_assertions"

        if is_macosx():
            # Unlike RUSTFLAGS, these are only passed in the final rustc invocation
            # so that `./mach build` followed by `./mach build-cef` both build
            # common dependencies with the same flags.
            opts += [
                "--", "-C",
                "link-args=-Xlinker -undefined -Xlinker dynamic_lookup"
            ]

        ret = call(["cargo", "rustc"] + opts, env=env, verbose=verbose)
        elapsed = time() - build_start

        # Generate Desktop Notification if elapsed-time > some threshold value
        notify_build_done(self.config, elapsed)

        print("CEF build completed in %s" % format_duration(elapsed))

        return ret
Example #2
0
    def build_cef(self, jobs=None, verbose=False, release=False,
                  with_debug_assertions=False):
        self.ensure_bootstrapped()
        self.ensure_clobbered()

        ret = None
        opts = []
        if jobs is not None:
            opts += ["-j", jobs]
        if verbose:
            opts += ["-v"]
        if release:
            opts += ["--release"]

        servo_features = self.servo_features()
        if servo_features:
            opts += ["--features", "%s" % ' '.join(servo_features)]

        build_start = time()
        env = self.build_env(is_build=True)

        if with_debug_assertions:
            env["RUSTFLAGS"] = "-C debug_assertions"

        if is_macosx():
            # Unlike RUSTFLAGS, these are only passed in the final rustc invocation
            # so that `./mach build` followed by `./mach build-cef` both build
            # common dependencies with the same flags.
            opts += ["--", "-C", "link-args=-Xlinker -undefined -Xlinker dynamic_lookup"]

        with cd(path.join("ports", "cef")):
            ret = call(["cargo", "rustc"] + opts,
                       env=env,
                       verbose=verbose)
        elapsed = time() - build_start

        # Generate Desktop Notification if elapsed-time > some threshold value
        notify_build_done(self.config, elapsed)

        print("CEF build completed in %s" % format_duration(elapsed))

        return ret
Example #3
0
    def package(self, release=False, dev=False, android=None, magicleap=None, debug=False,
                debugger=None, target=None, flavor=None, maven=False):
        if android is None:
            android = self.config["build"]["android"]
        if target and android:
            print("Please specify either --target or --android.")
            sys.exit(1)
        if not android:
            android = self.handle_android_target(target)
        else:
            target = self.config["android"]["target"]
        if target and magicleap:
            print("Please specify either --target or --magicleap.")
            sys.exit(1)
        if magicleap:
            target = "aarch64-linux-android"
        env = self.build_env(target=target)
        binary_path = self.get_binary_path(release, dev, android=android, magicleap=magicleap)
        dir_to_root = self.get_top_dir()
        target_dir = path.dirname(binary_path)
        if magicleap:
            if platform.system() not in ["Darwin"]:
                raise Exception("Magic Leap builds are only supported on macOS.")
            if not env.get("MAGICLEAP_SDK"):
                raise Exception("Magic Leap builds need the MAGICLEAP_SDK environment variable")
            if not env.get("MLCERT"):
                raise Exception("Magic Leap builds need the MLCERT environment variable")
            mabu = path.join(env.get("MAGICLEAP_SDK"), "mabu")
            package = "./support/magicleap/Servo2D/Servo2D.package"
            if dev:
                build_type = "lumin_debug"
            else:
                build_type = "lumin_release"
            argv = [
                mabu,
                "-o", target_dir,
                "-t", build_type,
                package
            ]
            try:
                subprocess.check_call(argv, env=env)
            except subprocess.CalledProcessError as e:
                print("Packaging Magic Leap exited with return value %d" % e.returncode)
                return e.returncode
        elif android:
            android_target = self.config["android"]["target"]
            if "aarch64" in android_target:
                build_type = "Arm64"
            elif "armv7" in android_target:
                build_type = "Armv7"
            elif "i686" in android_target:
                build_type = "x86"
            else:
                build_type = "Arm"

            if dev:
                build_mode = "Debug"
            else:
                build_mode = "Release"

            flavor_name = "Main"
            if flavor is not None:
                flavor_name = flavor.title()

            vr = flavor == "googlevr" or flavor == "oculusvr"

            dir_to_resources = path.join(self.get_top_dir(), 'target', 'android', 'resources')
            if path.exists(dir_to_resources):
                delete(dir_to_resources)

            shutil.copytree(path.join(dir_to_root, 'resources'), dir_to_resources)
            change_prefs(dir_to_resources, "android", vr=vr)

            variant = ":assemble" + flavor_name + build_type + build_mode
            apk_task_name = ":servoapp" + variant
            aar_task_name = ":servoview" + variant
            maven_task_name = ":servoview:uploadArchive"
            argv = ["./gradlew", "--no-daemon", apk_task_name, aar_task_name]
            if maven:
                argv.append(maven_task_name)
            try:
                with cd(path.join("support", "android", "apk")):
                    subprocess.check_call(argv, env=env)
            except subprocess.CalledProcessError as e:
                print("Packaging Android exited with return value %d" % e.returncode)
                return e.returncode
        elif is_macosx():
            print("Creating Servo.app")
            dir_to_dmg = path.join(target_dir, 'dmg')
            dir_to_app = path.join(dir_to_dmg, 'Servo.app')
            dir_to_resources = path.join(dir_to_app, 'Contents', 'Resources')
            if path.exists(dir_to_dmg):
                print("Cleaning up from previous packaging")
                delete(dir_to_dmg)

            print("Copying files")
            shutil.copytree(path.join(dir_to_root, 'resources'), dir_to_resources)
            shutil.copy2(path.join(dir_to_root, 'Info.plist'), path.join(dir_to_app, 'Contents', 'Info.plist'))

            content_dir = path.join(dir_to_app, 'Contents', 'MacOS')
            os.makedirs(content_dir)
            shutil.copy2(binary_path, content_dir)

            change_prefs(dir_to_resources, "macosx")

            print("Finding dylibs and relinking")
            copy_dependencies(path.join(content_dir, 'servo'), content_dir)

            print("Adding version to Credits.rtf")
            version_command = [binary_path, '--version']
            p = subprocess.Popen(version_command,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE,
                                 universal_newlines=True)
            version, stderr = p.communicate()
            if p.returncode != 0:
                raise Exception("Error occurred when getting Servo version: " + stderr)
            version = "Nightly version: " + version

            import mako.template
            template_path = path.join(dir_to_resources, 'Credits.rtf.mako')
            credits_path = path.join(dir_to_resources, 'Credits.rtf')
            with open(template_path) as template_file:
                template = mako.template.Template(template_file.read())
                with open(credits_path, "w") as credits_file:
                    credits_file.write(template.render(version=version))
            delete(template_path)

            print("Creating dmg")
            os.symlink('/Applications', path.join(dir_to_dmg, 'Applications'))
            dmg_path = path.join(target_dir, "servo-tech-demo.dmg")

            if path.exists(dmg_path):
                print("Deleting existing dmg")
                os.remove(dmg_path)

            try:
                subprocess.check_call(['hdiutil', 'create',
                                       '-volname', 'Servo',
                                       '-megabytes', '900',
                                       dmg_path,
                                       '-srcfolder', dir_to_dmg])
            except subprocess.CalledProcessError as e:
                print("Packaging MacOS dmg exited with return value %d" % e.returncode)
                return e.returncode
            print("Cleaning up")
            delete(dir_to_dmg)
            print("Packaged Servo into " + dmg_path)

            print("Creating brew package")
            dir_to_brew = path.join(target_dir, 'brew_tmp')
            dir_to_tar = path.join(target_dir, 'brew')
            if not path.exists(dir_to_tar):
                os.makedirs(dir_to_tar)
            tar_path = path.join(dir_to_tar, "servo.tar.gz")
            if path.exists(dir_to_brew):
                print("Cleaning up from previous packaging")
                delete(dir_to_brew)
            if path.exists(tar_path):
                print("Deleting existing package")
                os.remove(tar_path)
            shutil.copytree(path.join(dir_to_root, 'resources'), path.join(dir_to_brew, 'resources'))
            os.makedirs(path.join(dir_to_brew, 'bin'))
            shutil.copy2(binary_path, path.join(dir_to_brew, 'bin', 'servo'))
            # Note that in the context of Homebrew, libexec is reserved for private use by the formula
            # and therefore is not symlinked into HOMEBREW_PREFIX.
            os.makedirs(path.join(dir_to_brew, 'libexec'))
            copy_dependencies(path.join(dir_to_brew, 'bin', 'servo'), path.join(dir_to_brew, 'libexec'))
            archive_deterministically(dir_to_brew, tar_path, prepend_path='servo/')
            delete(dir_to_brew)
            print("Packaged Servo into " + tar_path)
        elif is_windows():
            dir_to_msi = path.join(target_dir, 'msi')
            if path.exists(dir_to_msi):
                print("Cleaning up from previous packaging")
                delete(dir_to_msi)
            os.makedirs(dir_to_msi)

            print("Copying files")
            dir_to_temp = path.join(dir_to_msi, 'temp')
            dir_to_resources = path.join(dir_to_temp, 'resources')
            shutil.copytree(path.join(dir_to_root, 'resources'), dir_to_resources)
            shutil.copy(binary_path, dir_to_temp)
            copy_windows_dependencies(target_dir, dir_to_temp)

            change_prefs(dir_to_resources, "windows")

            # generate Servo.wxs
            import mako.template
            template_path = path.join(dir_to_root, "support", "windows", "Servo.wxs.mako")
            template = mako.template.Template(open(template_path).read())
            wxs_path = path.join(dir_to_msi, "Installer.wxs")
            open(wxs_path, "w").write(template.render(
                exe_path=target_dir,
                dir_to_temp=dir_to_temp,
                resources_path=dir_to_resources))

            # run candle and light
            print("Creating MSI")
            try:
                with cd(dir_to_msi):
                    subprocess.check_call(['candle', wxs_path])
            except subprocess.CalledProcessError as e:
                print("WiX candle exited with return value %d" % e.returncode)
                return e.returncode
            try:
                wxsobj_path = "{}.wixobj".format(path.splitext(wxs_path)[0])
                with cd(dir_to_msi):
                    subprocess.check_call(['light', wxsobj_path])
            except subprocess.CalledProcessError as e:
                print("WiX light exited with return value %d" % e.returncode)
                return e.returncode
            dir_to_installer = path.join(dir_to_msi, "Installer.msi")
            print("Packaged Servo into " + dir_to_installer)

            # Generate bundle with Servo installer.
            print("Creating bundle")
            shutil.copy(path.join(dir_to_root, 'support', 'windows', 'Servo.wxs'), dir_to_msi)
            bundle_wxs_path = path.join(dir_to_msi, 'Servo.wxs')
            try:
                with cd(dir_to_msi):
                    subprocess.check_call(['candle', bundle_wxs_path, '-ext', 'WixBalExtension'])
            except subprocess.CalledProcessError as e:
                print("WiX candle exited with return value %d" % e.returncode)
                return e.returncode
            try:
                wxsobj_path = "{}.wixobj".format(path.splitext(bundle_wxs_path)[0])
                with cd(dir_to_msi):
                    subprocess.check_call(['light', wxsobj_path, '-ext', 'WixBalExtension'])
            except subprocess.CalledProcessError as e:
                print("WiX light exited with return value %d" % e.returncode)
                return e.returncode
            print("Packaged Servo into " + path.join(dir_to_msi, "Servo.exe"))

            print("Creating ZIP")
            zip_path = path.join(dir_to_msi, "Servo.zip")
            archive_deterministically(dir_to_temp, zip_path, prepend_path='servo/')
            print("Packaged Servo into " + zip_path)

            print("Cleaning up")
            delete(dir_to_temp)
            delete(dir_to_installer)
        else:
            dir_to_temp = path.join(target_dir, 'packaging-temp')
            if path.exists(dir_to_temp):
                # TODO(aneeshusa): lock dir_to_temp to prevent simultaneous builds
                print("Cleaning up from previous packaging")
                delete(dir_to_temp)

            print("Copying files")
            dir_to_resources = path.join(dir_to_temp, 'resources')
            shutil.copytree(path.join(dir_to_root, 'resources'), dir_to_resources)
            shutil.copy(binary_path, dir_to_temp)

            change_prefs(dir_to_resources, "linux")

            print("Creating tarball")
            tar_path = path.join(target_dir, 'servo-tech-demo.tar.gz')

            archive_deterministically(dir_to_temp, tar_path, prepend_path='servo/')

            print("Cleaning up")
            delete(dir_to_temp)
            print("Packaged Servo into " + tar_path)
Example #4
0
    def run(self,
            params,
            release=False,
            dev=False,
            android=None,
            debug=False,
            debugger=None,
            browserhtml=False,
            headless=False):
        env = self.build_env()
        env["RUST_BACKTRACE"] = "1"

        # Make --debugger imply --debug
        if debugger:
            debug = True

        if android is None:
            android = self.config["build"]["android"]

        if android:
            if debug:
                print(
                    "Android on-device debugging is not supported by mach yet. See"
                )
                print(
                    "https://github.com/servo/servo/wiki/Building-for-Android#debugging-on-device"
                )
                return
            script = [
                "am force-stop com.mozilla.servo",
                "echo servo >/sdcard/servo/android_params"
            ]
            for param in params:
                script += [
                    "echo '%s' >>/sdcard/servo/android_params" %
                    param.replace("'", "\\'")
                ]
            script += [
                "am start com.mozilla.servo/com.mozilla.servo.MainActivity",
                "exit"
            ]
            shell = subprocess.Popen(["adb", "shell"], stdin=subprocess.PIPE)
            shell.communicate("\n".join(script) + "\n")
            return shell.wait()

        args = [self.get_binary_path(release, dev)]

        if browserhtml:
            browserhtml_path = get_browserhtml_path('browserhtml', args[0])
            if is_macosx():
                # Enable borderless on OSX
                args = args + ['-b']
            elif is_windows():
                # Convert to a relative path to avoid mingw -> Windows path conversions
                browserhtml_path = path.relpath(browserhtml_path, os.getcwd())

            args = args + [
                '--pref', 'dom.mozbrowser.enabled', '--pref',
                'dom.forcetouch.enabled', '--pref',
                'shell.builtin-key-shortcuts.enabled=false',
                path.join(browserhtml_path, 'out', 'index.html')
            ]

        if headless:
            set_osmesa_env(args[0], env)
            args.append('-z')

        # Borrowed and modified from:
        # http://hg.mozilla.org/mozilla-central/file/c9cfa9b91dea/python/mozbuild/mozbuild/mach_commands.py#l883
        if debug:
            import mozdebug
            if not debugger:
                # No debugger name was provided. Look for the default ones on
                # current OS.
                debugger = mozdebug.get_default_debugger_name(
                    mozdebug.DebuggerSearch.KeepLooking)

            self.debuggerInfo = mozdebug.get_debugger_info(debugger)
            if not self.debuggerInfo:
                print("Could not find a suitable debugger in your PATH.")
                return 1

            command = self.debuggerInfo.path
            if debugger == 'gdb' or debugger == 'lldb':
                rustCommand = 'rust-' + debugger
                try:
                    subprocess.check_call([rustCommand, '--version'],
                                          env=env,
                                          stdout=open(os.devnull, 'w'))
                except (OSError, subprocess.CalledProcessError):
                    pass
                else:
                    command = rustCommand

            # Prepend the debugger args.
            args = ([command] + self.debuggerInfo.args + args + params)
        else:
            args = args + params

        try:
            check_call(args, env=env)
        except subprocess.CalledProcessError as e:
            print("Servo exited with return value %d" % e.returncode)
            return e.returncode
        except OSError as e:
            if e.errno == 2:
                print("Servo Binary can't be found! Run './mach build'"
                      " and try again!")
            else:
                raise e
Example #5
0
    def package(self, release=False, dev=False, android=None, debug=False, debugger=None, target=None):
        env = self.build_env()
        if android is None:
            android = self.config["build"]["android"]
        if target and android:
            print("Please specify either --target or --android.")
            sys.exit(1)
        if not android:
            android = self.handle_android_target(target)
        binary_path = self.get_binary_path(release, dev, android=android)
        dir_to_root = self.get_top_dir()
        target_dir = path.dirname(binary_path)
        if android:
            android_target = self.config["android"]["target"]
            if "aarch64" in android_target:
                build_type = "Arm64"
            elif "armv7" in android_target:
                build_type = "Armv7"
            else:
                build_type = "Arm"

            if dev:
                build_mode = "Debug"
            else:
                build_mode = "Release"

            task_name = "assemble" + build_type + build_mode
            try:
                with cd(path.join("support", "android", "apk")):
                    subprocess.check_call(["./gradlew", "--no-daemon", task_name], env=env)
            except subprocess.CalledProcessError as e:
                print("Packaging Android exited with return value %d" % e.returncode)
                return e.returncode
        elif is_macosx():
            print("Creating Servo.app")
            dir_to_dmg = path.join(target_dir, 'dmg')
            dir_to_app = path.join(dir_to_dmg, 'Servo.app')
            dir_to_resources = path.join(dir_to_app, 'Contents', 'Resources')
            if path.exists(dir_to_dmg):
                print("Cleaning up from previous packaging")
                delete(dir_to_dmg)
            browserhtml_path = get_browserhtml_path(binary_path)

            print("Copying files")
            shutil.copytree(path.join(dir_to_root, 'resources'), dir_to_resources)
            shutil.copytree(browserhtml_path, path.join(dir_to_resources, 'browserhtml'))
            shutil.copy2(path.join(dir_to_root, 'Info.plist'), path.join(dir_to_app, 'Contents', 'Info.plist'))

            content_dir = path.join(dir_to_app, 'Contents', 'MacOS')
            os.makedirs(content_dir)
            shutil.copy2(binary_path, content_dir)

            change_prefs(dir_to_resources, "macosx")

            print("Finding dylibs and relinking")
            copy_dependencies(path.join(content_dir, 'servo'), content_dir)

            print("Adding version to Credits.rtf")
            version_command = [binary_path, '--version']
            p = subprocess.Popen(version_command,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE,
                                 universal_newlines=True)
            version, stderr = p.communicate()
            if p.returncode != 0:
                raise Exception("Error occurred when getting Servo version: " + stderr)
            version = "Nightly version: " + version

            import mako.template
            template_path = path.join(dir_to_resources, 'Credits.rtf.mako')
            credits_path = path.join(dir_to_resources, 'Credits.rtf')
            with open(template_path) as template_file:
                template = mako.template.Template(template_file.read())
                with open(credits_path, "w") as credits_file:
                    credits_file.write(template.render(version=version))
            delete(template_path)

            print("Writing run-servo")
            bhtml_path = path.join('${0%/*}', '..', 'Resources', 'browserhtml', 'index.html')
            runservo = os.open(
                path.join(content_dir, 'run-servo'),
                os.O_WRONLY | os.O_CREAT,
                int("0755", 8)
            )
            os.write(runservo, '#!/bin/bash\nexec ${0%/*}/servo ' + bhtml_path)
            os.close(runservo)

            print("Creating dmg")
            os.symlink('/Applications', path.join(dir_to_dmg, 'Applications'))
            dmg_path = path.join(target_dir, "servo-tech-demo.dmg")

            if path.exists(dmg_path):
                print("Deleting existing dmg")
                os.remove(dmg_path)

            try:
                subprocess.check_call(['hdiutil', 'create',
                                       '-volname', 'Servo',
                                       '-megabytes', '900',
                                       dmg_path,
                                       '-srcfolder', dir_to_dmg])
            except subprocess.CalledProcessError as e:
                print("Packaging MacOS dmg exited with return value %d" % e.returncode)
                return e.returncode
            print("Cleaning up")
            delete(dir_to_dmg)
            print("Packaged Servo into " + dmg_path)

            print("Creating brew package")
            dir_to_brew = path.join(target_dir, 'brew_tmp')
            dir_to_tar = path.join(target_dir, 'brew')
            if not path.exists(dir_to_tar):
                os.makedirs(dir_to_tar)
            tar_path = path.join(dir_to_tar, "servo.tar.gz")
            if path.exists(dir_to_brew):
                print("Cleaning up from previous packaging")
                delete(dir_to_brew)
            if path.exists(tar_path):
                print("Deleting existing package")
                os.remove(tar_path)
            shutil.copytree(path.join(dir_to_root, 'resources'), path.join(dir_to_brew, 'resources'))
            os.makedirs(path.join(dir_to_brew, 'bin'))
            shutil.copy2(binary_path, path.join(dir_to_brew, 'bin', 'servo'))
            # Note that in the context of Homebrew, libexec is reserved for private use by the formula
            # and therefore is not symlinked into HOMEBREW_PREFIX.
            os.makedirs(path.join(dir_to_brew, 'libexec'))
            copy_dependencies(path.join(dir_to_brew, 'bin', 'servo'), path.join(dir_to_brew, 'libexec'))
            archive_deterministically(dir_to_brew, tar_path, prepend_path='servo/')
            delete(dir_to_brew)
            print("Packaged Servo into " + tar_path)
        elif is_windows():
            dir_to_msi = path.join(target_dir, 'msi')
            if path.exists(dir_to_msi):
                print("Cleaning up from previous packaging")
                delete(dir_to_msi)
            os.makedirs(dir_to_msi)
            browserhtml_path = get_browserhtml_path(binary_path)

            print("Copying files")
            dir_to_temp = path.join(dir_to_msi, 'temp')
            dir_to_temp_servo = path.join(dir_to_temp, 'servo')
            dir_to_resources = path.join(dir_to_temp_servo, 'resources')
            shutil.copytree(path.join(dir_to_root, 'resources'), dir_to_resources)
            shutil.copytree(browserhtml_path, path.join(dir_to_temp_servo, 'browserhtml'))
            shutil.copy(binary_path, dir_to_temp_servo)
            shutil.copy("{}.manifest".format(binary_path), dir_to_temp_servo)
            copy_windows_dependencies(target_dir, dir_to_temp_servo)

            change_prefs(dir_to_resources, "windows")

            # generate Servo.wxs
            import mako.template
            template_path = path.join(dir_to_root, "support", "windows", "Servo.wxs.mako")
            template = mako.template.Template(open(template_path).read())
            wxs_path = path.join(dir_to_msi, "Servo.wxs")
            open(wxs_path, "w").write(template.render(
                exe_path=target_dir,
                dir_to_temp=dir_to_temp_servo,
                resources_path=dir_to_resources))

            # run candle and light
            print("Creating MSI")
            try:
                with cd(dir_to_msi):
                    subprocess.check_call(['candle', wxs_path])
            except subprocess.CalledProcessError as e:
                print("WiX candle exited with return value %d" % e.returncode)
                return e.returncode
            try:
                wxsobj_path = "{}.wixobj".format(path.splitext(wxs_path)[0])
                with cd(dir_to_msi):
                    subprocess.check_call(['light', wxsobj_path])
            except subprocess.CalledProcessError as e:
                print("WiX light exited with return value %d" % e.returncode)
                return e.returncode
            print("Packaged Servo into " + path.join(dir_to_msi, "Servo.msi"))

            print("Creating ZIP")
            shutil.make_archive(path.join(dir_to_msi, "Servo"), "zip", dir_to_temp)
            print("Packaged Servo into " + path.join(dir_to_msi, "Servo.zip"))

            print("Cleaning up")
            delete(dir_to_temp)
        else:
            dir_to_temp = path.join(target_dir, 'packaging-temp')
            browserhtml_path = get_browserhtml_path(binary_path)
            if path.exists(dir_to_temp):
                # TODO(aneeshusa): lock dir_to_temp to prevent simultaneous builds
                print("Cleaning up from previous packaging")
                delete(dir_to_temp)

            print("Copying files")
            dir_to_resources = path.join(dir_to_temp, 'resources')
            shutil.copytree(path.join(dir_to_root, 'resources'), dir_to_resources)
            shutil.copytree(browserhtml_path, path.join(dir_to_temp, 'browserhtml'))
            shutil.copy(binary_path, dir_to_temp)

            change_prefs(dir_to_resources, "linux")

            print("Creating tarball")
            tar_path = path.join(target_dir, 'servo-tech-demo.tar.gz')

            archive_deterministically(dir_to_temp, tar_path, prepend_path='servo/')

            print("Cleaning up")
            delete(dir_to_temp)
            print("Packaged Servo into " + tar_path)
Example #6
0
    def run(self, params, release=False, dev=False, android=None, debug=False, debugger=None, browserhtml=False,
            headless=False):
        env = self.build_env()
        env["RUST_BACKTRACE"] = "1"

        # Make --debugger imply --debug
        if debugger:
            debug = True

        if android is None:
            android = self.config["build"]["android"]

        if android:
            if debug:
                print("Android on-device debugging is not supported by mach yet. See")
                print("https://github.com/servo/servo/wiki/Building-for-Android#debugging-on-device")
                return
            script = [
                "am force-stop com.mozilla.servo",
                "echo servo >/sdcard/servo/android_params"
            ]
            for param in params:
                script += [
                    "echo '%s' >>/sdcard/servo/android_params" % param.replace("'", "\\'")
                ]
            script += [
                "am start com.mozilla.servo/com.mozilla.servo.MainActivity",
                "exit"
            ]
            shell = subprocess.Popen(["adb", "shell"], stdin=subprocess.PIPE)
            shell.communicate("\n".join(script) + "\n")
            return shell.wait()

        args = [self.get_binary_path(release, dev)]

        if browserhtml:
            browserhtml_path = get_browserhtml_path('browserhtml', args[0])
            if is_macosx():
                # Enable borderless on OSX
                args = args + ['-b']
            elif is_windows():
                # Convert to a relative path to avoid mingw -> Windows path conversions
                browserhtml_path = path.relpath(browserhtml_path, os.getcwd())

            args = args + ['--pref', 'dom.mozbrowser.enabled',
                           '--pref', 'dom.forcetouch.enabled',
                           '--pref', 'shell.builtin-key-shortcuts.enabled=false',
                           path.join(browserhtml_path, 'out', 'index.html')]

        if headless:
            set_osmesa_env(args[0], env)
            args.append('-z')

        # Borrowed and modified from:
        # http://hg.mozilla.org/mozilla-central/file/c9cfa9b91dea/python/mozbuild/mozbuild/mach_commands.py#l883
        if debug:
            import mozdebug
            if not debugger:
                # No debugger name was provided. Look for the default ones on
                # current OS.
                debugger = mozdebug.get_default_debugger_name(
                    mozdebug.DebuggerSearch.KeepLooking)

            self.debuggerInfo = mozdebug.get_debugger_info(debugger)
            if not self.debuggerInfo:
                print("Could not find a suitable debugger in your PATH.")
                return 1

            command = self.debuggerInfo.path
            if debugger == 'gdb' or debugger == 'lldb':
                rustCommand = 'rust-' + debugger
                try:
                    subprocess.check_call([rustCommand, '--version'], env=env, stdout=open(os.devnull, 'w'))
                except (OSError, subprocess.CalledProcessError):
                    pass
                else:
                    command = rustCommand

            # Prepend the debugger args.
            args = ([command] + self.debuggerInfo.args +
                    args + params)
        else:
            args = args + params

        try:
            check_call(args, env=env)
        except subprocess.CalledProcessError as e:
            print("Servo exited with return value %d" % e.returncode)
            return e.returncode
        except OSError as e:
            if e.errno == 2:
                print("Servo Binary can't be found! Run './mach build'"
                      " and try again!")
            else:
                raise e
Example #7
0
    def package(self, release=False, dev=False, android=None, debug=False, debugger=None):
        env = self.build_env()
        if android is None:
            android = self.config["build"]["android"]
        binary_path = self.get_binary_path(release, dev, android=android)
        if android:
            if dev:
                env["NDK_DEBUG"] = "1"
                env["ANT_FLAVOR"] = "debug"
                dev_flag = "-d"
            else:
                env["ANT_FLAVOR"] = "release"
                dev_flag = ""

            target_dir = path.dirname(binary_path)
            output_apk = "{}.apk".format(binary_path)
            blurdroid_path = find_dep_path_newest('blurdroid', binary_path)
            if blurdroid_path is None:
                print("Could not find blurdroid package; perhaps you haven't built Servo.")
                return 1
            else:
                dir_to_libs = path.join("support", "android", "apk", "libs")
                if not path.exists(dir_to_libs):
                    os.makedirs(dir_to_libs)
                shutil.copy2(blurdroid_path + '/out/blurdroid.jar', dir_to_libs)
            try:
                with cd(path.join("support", "android", "build-apk")):
                    subprocess.check_call(["cargo", "run", "--", dev_flag, "-o", output_apk, "-t", target_dir,
                                           "-r", self.get_top_dir()], env=env)
            except subprocess.CalledProcessError as e:
                print("Packaging Android exited with return value %d" % e.returncode)
                return e.returncode
        elif is_macosx():

            dir_to_build = '/'.join(binary_path.split('/')[:-1])
            dir_to_root = '/'.join(binary_path.split('/')[:-3])
            now = datetime.utcnow()

            print("Creating Servo.app")
            dir_to_dmg = '/'.join(binary_path.split('/')[:-2]) + '/dmg'
            dir_to_app = dir_to_dmg + '/Servo.app'
            dir_to_resources = dir_to_app + '/Contents/Resources/'
            if path.exists(dir_to_dmg):
                print("Cleaning up from previous packaging")
                delete(dir_to_dmg)
            browserhtml_path = find_dep_path_newest('browserhtml', binary_path)
            if browserhtml_path is None:
                print("Could not find browserhtml package; perhaps you haven't built Servo.")
                return 1

            print("Copying files")
            shutil.copytree(dir_to_root + '/resources', dir_to_resources)
            shutil.copytree(browserhtml_path, dir_to_resources + browserhtml_path.split('/')[-1])
            shutil.copy2(dir_to_root + '/Info.plist', dir_to_app + '/Contents/Info.plist')
            os.makedirs(dir_to_app + '/Contents/MacOS/')
            shutil.copy2(dir_to_build + '/servo', dir_to_app + '/Contents/MacOS/')

            print("Swapping prefs")
            delete(dir_to_resources + '/prefs.json')
            shutil.copy2(dir_to_resources + 'package-prefs.json', dir_to_resources + 'prefs.json')
            delete(dir_to_resources + '/package-prefs.json')

            print("Finding dylibs and relinking")
            copy_dependencies(dir_to_app + '/Contents/MacOS/servo', dir_to_app + '/Contents/MacOS/')

            print("Adding version to Credits.rtf")
            version_command = [binary_path, '--version']
            p = subprocess.Popen(version_command,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE,
                                 universal_newlines=True)
            version, stderr = p.communicate()
            if p.returncode != 0:
                raise Exception("Error occurred when getting Servo version: " + stderr)
            version = "Nightly version: " + version

            template_path = os.path.join(dir_to_resources, 'Credits.rtf.mako')
            credits_path = os.path.join(dir_to_resources, 'Credits.rtf')
            with open(template_path) as template_file:
                template = mako.template.Template(template_file.read())
                with open(credits_path, "w") as credits_file:
                    credits_file.write(template.render(version=version))
            delete(template_path)

            print("Writing run-servo")
            bhtml_path = path.join('${0%/*}/../Resources', browserhtml_path.split('/')[-1], 'out', 'index.html')
            runservo = os.open(dir_to_app + '/Contents/MacOS/run-servo', os.O_WRONLY | os.O_CREAT, int("0755", 8))
            os.write(runservo, '#!/bin/bash\nexec ${0%/*}/servo ' + bhtml_path)
            os.close(runservo)

            print("Creating dmg")
            os.symlink('/Applications', dir_to_dmg + '/Applications')
            dmg_path = '/'.join(dir_to_build.split('/')[:-1]) + '/'
            time = now.replace(microsecond=0).isoformat()
            time = time.replace(':', '-')
            dmg_path += time + "-servo-tech-demo.dmg"
            try:
                subprocess.check_call(['hdiutil', 'create', '-volname', 'Servo', dmg_path, '-srcfolder', dir_to_dmg])
            except subprocess.CalledProcessError as e:
                print("Packaging MacOS dmg exited with return value %d" % e.returncode)
                return e.returncode
            print("Cleaning up")
            delete(dir_to_dmg)
            print("Packaged Servo into " + dmg_path)

            print("Creating brew package")
            dir_to_brew = '/'.join(binary_path.split('/')[:-2]) + '/brew_tmp/'
            dir_to_tar = '/'.join(dir_to_build.split('/')[:-1]) + '/brew/'
            if not path.exists(dir_to_tar):
                os.makedirs(dir_to_tar)
            tar_path = dir_to_tar + now.strftime("servo-%Y-%m-%d.tar.gz")
            if path.exists(dir_to_brew):
                print("Cleaning up from previous packaging")
                delete(dir_to_brew)
            if path.exists(tar_path):
                print("Deleting existing package")
                os.remove(tar_path)
            shutil.copytree(dir_to_root + '/resources', dir_to_brew + "/resources/")
            os.makedirs(dir_to_brew + '/bin/')
            shutil.copy2(dir_to_build + '/servo', dir_to_brew + '/bin/servo')
            # Note that in the context of Homebrew, libexec is reserved for private use by the formula
            # and therefore is not symlinked into HOMEBREW_PREFIX.
            os.makedirs(dir_to_brew + '/libexec/')
            copy_dependencies(dir_to_brew + '/bin/servo', dir_to_brew + '/libexec/')
            archive_deterministically(dir_to_brew, tar_path, prepend_path='servo/')
            delete(dir_to_brew)
            print("Packaged Servo into " + tar_path)

        elif is_windows():
            dir_to_package = path.dirname(binary_path)
            dir_to_root = self.get_top_dir()
            dir_to_msi = path.join(dir_to_package, 'msi')
            if path.exists(dir_to_msi):
                print("Cleaning up from previous packaging")
                delete(dir_to_msi)
            os.makedirs(dir_to_msi)
            top_path = dir_to_root
            browserhtml_path = find_dep_path_newest('browserhtml', binary_path)
            if browserhtml_path is None:
                print("Could not find browserhtml package; perhaps you haven't built Servo.")
                return 1
            browserhtml_path = path.join(browserhtml_path, "out")
            # generate Servo.wxs
            template_path = path.join(dir_to_root, "support", "windows", "Servo.wxs.mako")
            template = Template(open(template_path).read())
            wxs_path = path.join(dir_to_msi, "Servo.wxs")
            open(wxs_path, "w").write(template.render(
                exe_path=dir_to_package,
                top_path=top_path,
                browserhtml_path=browserhtml_path))
            # run candle and light
            print("Creating MSI")
            try:
                with cd(dir_to_msi):
                    subprocess.check_call(['candle', wxs_path])
            except subprocess.CalledProcessError as e:
                print("WiX candle exited with return value %d" % e.returncode)
                return e.returncode
            try:
                wxsobj_path = "{}.wixobj".format(path.splitext(wxs_path)[0])
                with cd(dir_to_msi):
                    subprocess.check_call(['light', wxsobj_path])
            except subprocess.CalledProcessError as e:
                print("WiX light exited with return value %d" % e.returncode)
                return e.returncode
            msi_path = path.join(dir_to_msi, "Servo.msi")
            print("Packaged Servo into {}".format(msi_path))
        else:
            dir_to_temp = path.join(os.path.dirname(binary_path), 'packaging-temp')
            browserhtml_path = find_dep_path_newest('browserhtml', binary_path)
            if browserhtml_path is None:
                print("Could not find browserhtml package; perhaps you haven't built Servo.")
                return 1
            if path.exists(dir_to_temp):
                # TODO(aneeshusa): lock dir_to_temp to prevent simultaneous builds
                print("Cleaning up from previous packaging")
                delete(dir_to_temp)

            print("Copying files")
            dir_to_resources = path.join(dir_to_temp, 'resources')
            shutil.copytree(path.join(self.get_top_dir(), 'resources'), dir_to_resources)
            shutil.copytree(browserhtml_path, path.join(dir_to_temp, 'browserhtml'))
            shutil.copy(binary_path, dir_to_temp)

            print("Writing runservo.sh")
            # TODO: deduplicate this arg list from post_build_commands
            servo_args = ['-b',
                          '--pref', 'dom.mozbrowser.enabled',
                          '--pref', 'dom.forcetouch.enabled',
                          '--pref', 'shell.builtin-key-shortcuts.enabled=false',
                          path.join('./browserhtml', 'out', 'index.html')]

            runservo = os.open(dir_to_temp + '/runservo.sh', os.O_WRONLY | os.O_CREAT, int("0755", 8))
            os.write(runservo, "#!/usr/bin/env sh\n./servo " + ' '.join(servo_args))
            os.close(runservo)

            print("Creating tarball")
            time = datetime.utcnow().replace(microsecond=0).isoformat()
            time = time.replace(':', "-")
            tar_path = path.join(self.get_target_dir(), time + '-servo-tech-demo.tar.gz')

            archive_deterministically(dir_to_temp, tar_path, prepend_path='servo/')

            print("Cleaning up")
            delete(dir_to_temp)
            print("Packaged Servo into " + tar_path)
Example #8
0
    def package(self,
                release=False,
                dev=False,
                android=None,
                debug=False,
                debugger=None):
        env = self.build_env()
        if android is None:
            android = self.config["build"]["android"]
        binary_path = self.get_binary_path(release, dev, android=android)
        if android:
            if dev:
                env["NDK_DEBUG"] = "1"
                env["ANT_FLAVOR"] = "debug"
                dev_flag = "-d"
            else:
                env["ANT_FLAVOR"] = "release"
                dev_flag = ""

            target_dir = path.dirname(binary_path)
            output_apk = "{}.apk".format(binary_path)
            blurdroid_path = find_dep_path_newest('blurdroid', binary_path)
            if blurdroid_path is None:
                print(
                    "Could not find blurdroid package; perhaps you haven't built Servo."
                )
                return 1
            else:
                dir_to_libs = path.join("support", "android", "apk", "libs")
                if not path.exists(dir_to_libs):
                    os.makedirs(dir_to_libs)
                shutil.copy2(blurdroid_path + '/out/blurdroid.jar',
                             dir_to_libs)
            try:
                with cd(path.join("support", "android", "build-apk")):
                    subprocess.check_call([
                        "cargo", "run", "--", dev_flag, "-o", output_apk, "-t",
                        target_dir, "-r",
                        self.get_top_dir()
                    ],
                                          env=env)
            except subprocess.CalledProcessError as e:
                print("Packaging Android exited with return value %d" %
                      e.returncode)
                return e.returncode
        elif is_macosx():

            dir_to_build = '/'.join(binary_path.split('/')[:-1])
            dir_to_root = '/'.join(binary_path.split('/')[:-3])
            now = datetime.utcnow()

            print("Creating Servo.app")
            dir_to_dmg = '/'.join(binary_path.split('/')[:-2]) + '/dmg'
            dir_to_app = dir_to_dmg + '/Servo.app'
            dir_to_resources = dir_to_app + '/Contents/Resources/'
            if path.exists(dir_to_dmg):
                print("Cleaning up from previous packaging")
                delete(dir_to_dmg)
            browserhtml_path = find_dep_path_newest('browserhtml', binary_path)
            if browserhtml_path is None:
                print(
                    "Could not find browserhtml package; perhaps you haven't built Servo."
                )
                return 1

            print("Copying files")
            shutil.copytree(dir_to_root + '/resources', dir_to_resources)
            shutil.copytree(browserhtml_path,
                            dir_to_resources + browserhtml_path.split('/')[-1])
            shutil.copy2(dir_to_root + '/Info.plist',
                         dir_to_app + '/Contents/Info.plist')
            os.makedirs(dir_to_app + '/Contents/MacOS/')
            shutil.copy2(dir_to_build + '/servo',
                         dir_to_app + '/Contents/MacOS/')

            print("Swapping prefs")
            delete(dir_to_resources + '/prefs.json')
            shutil.copy2(dir_to_resources + 'package-prefs.json',
                         dir_to_resources + 'prefs.json')
            delete(dir_to_resources + '/package-prefs.json')

            print("Finding dylibs and relinking")
            copy_dependencies(dir_to_app + '/Contents/MacOS/servo',
                              dir_to_app + '/Contents/MacOS/')

            print("Adding version to Credits.rtf")
            version_command = [binary_path, '--version']
            p = subprocess.Popen(version_command,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE,
                                 universal_newlines=True)
            version, stderr = p.communicate()
            if p.returncode != 0:
                raise Exception("Error occurred when getting Servo version: " +
                                stderr)
            version = "Nightly version: " + version

            template_path = os.path.join(dir_to_resources, 'Credits.rtf.mako')
            credits_path = os.path.join(dir_to_resources, 'Credits.rtf')
            with open(template_path) as template_file:
                template = mako.template.Template(template_file.read())
                with open(credits_path, "w") as credits_file:
                    credits_file.write(template.render(version=version))
            delete(template_path)

            print("Writing run-servo")
            bhtml_path = path.join('${0%/*}/../Resources',
                                   browserhtml_path.split('/')[-1], 'out',
                                   'index.html')
            runservo = os.open(dir_to_app + '/Contents/MacOS/run-servo',
                               os.O_WRONLY | os.O_CREAT, int("0755", 8))
            os.write(runservo, '#!/bin/bash\nexec ${0%/*}/servo ' + bhtml_path)
            os.close(runservo)

            print("Creating dmg")
            os.symlink('/Applications', dir_to_dmg + '/Applications')
            dmg_path = '/'.join(dir_to_build.split('/')[:-1]) + '/'
            time = now.replace(microsecond=0).isoformat()
            time = time.replace(':', '-')
            dmg_path += time + "-servo-tech-demo.dmg"
            try:
                subprocess.check_call([
                    'hdiutil', 'create', '-volname', 'Servo', dmg_path,
                    '-srcfolder', dir_to_dmg
                ])
            except subprocess.CalledProcessError as e:
                print("Packaging MacOS dmg exited with return value %d" %
                      e.returncode)
                return e.returncode
            print("Cleaning up")
            delete(dir_to_dmg)
            print("Packaged Servo into " + dmg_path)

            print("Creating brew package")
            dir_to_brew = '/'.join(binary_path.split('/')[:-2]) + '/brew_tmp/'
            dir_to_tar = '/'.join(dir_to_build.split('/')[:-1]) + '/brew/'
            if not path.exists(dir_to_tar):
                os.makedirs(dir_to_tar)
            tar_path = dir_to_tar + now.strftime("servo-%Y-%m-%d.tar.gz")
            if path.exists(dir_to_brew):
                print("Cleaning up from previous packaging")
                delete(dir_to_brew)
            if path.exists(tar_path):
                print("Deleting existing package")
                os.remove(tar_path)
            shutil.copytree(dir_to_root + '/resources',
                            dir_to_brew + "/resources/")
            os.makedirs(dir_to_brew + '/bin/')
            shutil.copy2(dir_to_build + '/servo', dir_to_brew + '/bin/servo')
            # Note that in the context of Homebrew, libexec is reserved for private use by the formula
            # and therefore is not symlinked into HOMEBREW_PREFIX.
            os.makedirs(dir_to_brew + '/libexec/')
            copy_dependencies(dir_to_brew + '/bin/servo',
                              dir_to_brew + '/libexec/')
            archive_deterministically(dir_to_brew,
                                      tar_path,
                                      prepend_path='servo/')
            delete(dir_to_brew)
            print("Packaged Servo into " + tar_path)

        elif is_windows():
            dir_to_package = path.dirname(binary_path)
            dir_to_root = self.get_top_dir()
            dir_to_msi = path.join(dir_to_package, 'msi')
            if path.exists(dir_to_msi):
                print("Cleaning up from previous packaging")
                delete(dir_to_msi)
            os.makedirs(dir_to_msi)
            top_path = dir_to_root
            browserhtml_path = find_dep_path_newest('browserhtml', binary_path)
            if browserhtml_path is None:
                print(
                    "Could not find browserhtml package; perhaps you haven't built Servo."
                )
                return 1
            browserhtml_path = path.join(browserhtml_path, "out")
            # generate Servo.wxs
            template_path = path.join(dir_to_root, "support", "windows",
                                      "Servo.wxs.mako")
            template = Template(open(template_path).read())
            wxs_path = path.join(dir_to_msi, "Servo.wxs")
            open(wxs_path, "w").write(
                template.render(exe_path=dir_to_package,
                                top_path=top_path,
                                browserhtml_path=browserhtml_path))
            # run candle and light
            print("Creating MSI")
            try:
                with cd(dir_to_msi):
                    subprocess.check_call(['candle', wxs_path])
            except subprocess.CalledProcessError as e:
                print("WiX candle exited with return value %d" % e.returncode)
                return e.returncode
            try:
                wxsobj_path = "{}.wixobj".format(path.splitext(wxs_path)[0])
                with cd(dir_to_msi):
                    subprocess.check_call(['light', wxsobj_path])
            except subprocess.CalledProcessError as e:
                print("WiX light exited with return value %d" % e.returncode)
                return e.returncode
            msi_path = path.join(dir_to_msi, "Servo.msi")
            print("Packaged Servo into {}".format(msi_path))
        else:
            dir_to_temp = path.join(os.path.dirname(binary_path),
                                    'packaging-temp')
            browserhtml_path = find_dep_path_newest('browserhtml', binary_path)
            if browserhtml_path is None:
                print(
                    "Could not find browserhtml package; perhaps you haven't built Servo."
                )
                return 1
            if path.exists(dir_to_temp):
                # TODO(aneeshusa): lock dir_to_temp to prevent simultaneous builds
                print("Cleaning up from previous packaging")
                delete(dir_to_temp)

            print("Copying files")
            dir_to_resources = path.join(dir_to_temp, 'resources')
            shutil.copytree(path.join(self.get_top_dir(), 'resources'),
                            dir_to_resources)
            shutil.copytree(browserhtml_path,
                            path.join(dir_to_temp, 'browserhtml'))
            shutil.copy(binary_path, dir_to_temp)

            print("Writing runservo.sh")
            # TODO: deduplicate this arg list from post_build_commands
            servo_args = [
                '-b', '--pref', 'dom.mozbrowser.enabled', '--pref',
                'dom.forcetouch.enabled', '--pref',
                'shell.builtin-key-shortcuts.enabled=false',
                path.join('./browserhtml', 'out', 'index.html')
            ]

            runservo = os.open(dir_to_temp + '/runservo.sh',
                               os.O_WRONLY | os.O_CREAT, int("0755", 8))
            os.write(runservo,
                     "#!/usr/bin/env sh\n./servo " + ' '.join(servo_args))
            os.close(runservo)

            print("Creating tarball")
            time = datetime.utcnow().replace(microsecond=0).isoformat()
            time = time.replace(':', "-")
            tar_path = path.join(self.get_target_dir(),
                                 time + '-servo-tech-demo.tar.gz')

            archive_deterministically(dir_to_temp,
                                      tar_path,
                                      prepend_path='servo/')

            print("Cleaning up")
            delete(dir_to_temp)
            print("Packaged Servo into " + tar_path)
Example #9
0
    def package(self, release=False, dev=False, android=None, debug=False, debugger=None):
        env = self.build_env()
        if android is None:
            android = self.config["build"]["android"]
        binary_path = self.get_binary_path(release, dev, android=android)
        if android:
            if dev:
                env["NDK_DEBUG"] = "1"
                env["ANT_FLAVOR"] = "debug"
                dev_flag = "-d"
            else:
                env["ANT_FLAVOR"] = "release"
                dev_flag = ""

            target_dir = path.dirname(binary_path)
            output_apk = "{}.apk".format(binary_path)
            try:
                with cd(path.join("support", "android", "build-apk")):
                    subprocess.check_call(["cargo", "run", "--", dev_flag, "-o", output_apk, "-t", target_dir,
                                           "-r", self.get_top_dir()], env=env)
            except subprocess.CalledProcessError as e:
                print("Packaging Android exited with return value %d" % e.returncode)
                return e.returncode
        elif is_macosx():
            dir_to_build = '/'.join(binary_path.split('/')[:-1])
            dir_to_dmg = '/'.join(binary_path.split('/')[:-2]) + '/dmg'
            dir_to_app = dir_to_dmg + '/Servo.app'
            dir_to_resources = dir_to_app + '/Contents/Resources/'
            dir_to_root = '/'.join(binary_path.split('/')[:-3])
            if path.exists(dir_to_dmg):
                print("Cleaning up from previous packaging")
                delete(dir_to_dmg)
            browserhtml_path = find_dep_path_newest('browserhtml', binary_path)
            if browserhtml_path is None:
                print("Could not find browserhtml package; perhaps you haven't built Servo.")
                return 1

            print("Copying files")
            shutil.copytree(dir_to_root + '/resources', dir_to_resources)
            shutil.copytree(browserhtml_path, dir_to_resources + browserhtml_path.split('/')[-1])
            shutil.copy2(dir_to_root + '/Info.plist', dir_to_app + '/Contents/Info.plist')
            os.makedirs(dir_to_app + '/Contents/MacOS/')
            shutil.copy2(dir_to_build + '/servo', dir_to_app + '/Contents/MacOS/')

            print("Swapping prefs")
            delete(dir_to_resources + '/prefs.json')
            shutil.copy2(dir_to_resources + 'package-prefs.json', dir_to_resources + 'prefs.json')
            delete(dir_to_resources + '/package-prefs.json')

            print("Finding dylibs and relinking")
            need_checked = set([dir_to_app + '/Contents/MacOS/servo'])
            checked = set()
            while need_checked:
                checking = set(need_checked)
                need_checked = set()
                for f in checking:
                    # No need to check these for their dylibs
                    if '/System/Library' in f or '/usr/lib' in f:
                        continue
                    need_relinked = set(otool(f))
                    new_path = dir_to_app + '/Contents/MacOS/' + f.split('/')[-1]
                    if not path.exists(new_path):
                        shutil.copyfile(f, new_path)
                    for dylib in need_relinked:
                        if '/System/Library' in dylib or '/usr/lib' in dylib or 'servo' in dylib:
                            continue
                        install_name_tool(dylib, dylib.split('/')[-1], new_path)
                    need_checked.update(need_relinked)
                checked.update(checking)
                need_checked.difference_update(checked)

            print("Writing run-servo")
            bhtml_path = path.join('${0%/*}/../Resources', browserhtml_path.split('/')[-1], 'out', 'index.html')
            runservo = os.open(dir_to_app + '/Contents/MacOS/run-servo', os.O_WRONLY | os.O_CREAT, int("0755", 8))
            os.write(runservo, '#!/bin/bash\nexec ${0%/*}/servo ' + bhtml_path)
            os.close(runservo)

            print("Creating dmg")
            os.symlink('/Applications', dir_to_dmg + '/Applications')
            dmg_path = '/'.join(dir_to_build.split('/')[:-1]) + '/'
            time = datetime.utcnow().replace(microsecond=0).isoformat()
            time = time.replace(':', '-')
            dmg_path += time + "-servo-tech-demo.dmg"
            try:
                subprocess.check_call(['hdiutil', 'create', '-volname', 'Servo', dmg_path, '-srcfolder', dir_to_dmg])
            except subprocess.CalledProcessError as e:
                print("Packaging MacOS dmg exited with return value %d" % e.returncode)
                return e.returncode
            print("Cleaning up")
            delete(dir_to_dmg)
            print("Packaged Servo into " + dmg_path)
        elif is_windows():
            dir_to_package = path.dirname(binary_path)
            dir_to_root = self.get_top_dir()
            dir_to_msi = path.join(dir_to_package, 'msi')
            if path.exists(dir_to_msi):
                print("Cleaning up from previous packaging")
                delete(dir_to_msi)
            os.makedirs(dir_to_msi)
            top_path = dir_to_root
            browserhtml_path = find_dep_path_newest('browserhtml', binary_path)
            if browserhtml_path is None:
                print("Could not find browserhtml package; perhaps you haven't built Servo.")
                return 1
            browserhtml_path = path.join(browserhtml_path, "out")
            # generate Servo.wxs
            template_path = path.join(dir_to_root, "support", "windows", "Servo.wxs.mako")
            template = Template(open(template_path).read())
            wxs_path = path.join(dir_to_msi, "Servo.wxs")
            open(wxs_path, "w").write(template.render(
                exe_path=dir_to_package,
                top_path=top_path,
                browserhtml_path=browserhtml_path))
            # run candle and light
            print("Creating MSI")
            try:
                with cd(dir_to_msi):
                    subprocess.check_call(['candle', wxs_path])
            except subprocess.CalledProcessError as e:
                print("WiX candle exited with return value %d" % e.returncode)
                return e.returncode
            try:
                wxsobj_path = "{}.wixobj".format(path.splitext(wxs_path)[0])
                with cd(dir_to_msi):
                    subprocess.check_call(['light', wxsobj_path])
            except subprocess.CalledProcessError as e:
                print("WiX light exited with return value %d" % e.returncode)
                return e.returncode
            msi_path = path.join(dir_to_msi, "Servo.msi")
            print("Packaged Servo into {}".format(msi_path))
        else:
            dir_to_package = '/'.join(binary_path.split('/')[:-1])
            dir_to_root = '/'.join(binary_path.split('/')[:-3])
            shutil.copytree(dir_to_root + '/resources', dir_to_package + '/resources')
            browserhtml_path = find_dep_path_newest('browserhtml', binary_path)
            if browserhtml_path is None:
                print("Could not find browserhtml package; perhaps you haven't built Servo.")
                return 1
            print("Deleting unused files")
            keep = ['servo', 'resources', 'build']
            for f in os.listdir(dir_to_package + '/'):
                if f not in keep:
                    delete(dir_to_package + '/' + f)
            for f in os.listdir(dir_to_package + '/build/'):
                if 'browserhtml' not in f:
                    delete(dir_to_package + '/build/' + f)
            print("Writing runservo.sh")
            # TODO: deduplicate this arg list from post_build_commands
            servo_args = ['-w', '-b',
                          '--pref', 'dom.mozbrowser.enabled',
                          '--pref', 'dom.forcetouch.enabled',
                          '--pref', 'shell.builtin-key-shortcuts.enabled=false',
                          path.join('./build/' + browserhtml_path.split('/')[-1], 'out', 'index.html')]

            runservo = os.open(dir_to_package + '/runservo.sh', os.O_WRONLY | os.O_CREAT, int("0755", 8))
            os.write(runservo, "#!/usr/bin/env sh\n./servo " + ' '.join(servo_args))
            os.close(runservo)
            print("Creating tarball")
            tar_path = '/'.join(dir_to_package.split('/')[:-1]) + '/'
            time = datetime.utcnow().replace(microsecond=0).isoformat()
            time = time.replace(':', "-")
            tar_path += time + "-servo-tech-demo.tar.gz"
            with tarfile.open(tar_path, "w:gz") as tar:
                # arcname is to add by relative rather than absolute path
                tar.add(dir_to_package, arcname='servo/')
            print("Packaged Servo into " + tar_path)
Example #10
0
    def package(self,
                release=False,
                dev=False,
                android=None,
                debug=False,
                debugger=None,
                target=None,
                flavor=None):
        if android is None:
            android = self.config["build"]["android"]
        if target and android:
            print("Please specify either --target or --android.")
            sys.exit(1)
        if not android:
            android = self.handle_android_target(target)
        else:
            target = self.config["android"]["target"]
        env = self.build_env(target=target)
        binary_path = self.get_binary_path(release, dev, android=android)
        dir_to_root = self.get_top_dir()
        target_dir = path.dirname(binary_path)
        if android:
            android_target = self.config["android"]["target"]
            if "aarch64" in android_target:
                build_type = "Arm64"
            elif "armv7" in android_target:
                build_type = "Armv7"
            elif "i686" in android_target:
                build_type = "x86"
            else:
                build_type = "Arm"

            if dev:
                build_mode = "Debug"
            else:
                build_mode = "Release"

            flavor_name = "Main"
            if flavor is not None:
                flavor_name = flavor.title()

            variant = ":assemble" + flavor_name + build_type + build_mode
            apk_task_name = ":servoapp" + variant
            aar_task_name = ":servoview" + variant
            try:
                with cd(path.join("support", "android", "apk")):
                    subprocess.check_call([
                        "./gradlew", "--no-daemon", apk_task_name,
                        aar_task_name
                    ],
                                          env=env)
            except subprocess.CalledProcessError as e:
                print("Packaging Android exited with return value %d" %
                      e.returncode)
                return e.returncode
        elif is_macosx():
            print("Creating Servo.app")
            dir_to_dmg = path.join(target_dir, 'dmg')
            dir_to_app = path.join(dir_to_dmg, 'Servo.app')
            dir_to_resources = path.join(dir_to_app, 'Contents', 'Resources')
            if path.exists(dir_to_dmg):
                print("Cleaning up from previous packaging")
                delete(dir_to_dmg)

            print("Copying files")
            shutil.copytree(path.join(dir_to_root, 'resources'),
                            dir_to_resources)
            shutil.copy2(path.join(dir_to_root, 'Info.plist'),
                         path.join(dir_to_app, 'Contents', 'Info.plist'))

            content_dir = path.join(dir_to_app, 'Contents', 'MacOS')
            os.makedirs(content_dir)
            shutil.copy2(binary_path, content_dir)

            change_prefs(dir_to_resources, "macosx")

            print("Finding dylibs and relinking")
            copy_dependencies(path.join(content_dir, 'servo'), content_dir)

            print("Adding version to Credits.rtf")
            version_command = [binary_path, '--version']
            p = subprocess.Popen(version_command,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE,
                                 universal_newlines=True)
            version, stderr = p.communicate()
            if p.returncode != 0:
                raise Exception("Error occurred when getting Servo version: " +
                                stderr)
            version = "Nightly version: " + version

            import mako.template
            template_path = path.join(dir_to_resources, 'Credits.rtf.mako')
            credits_path = path.join(dir_to_resources, 'Credits.rtf')
            with open(template_path) as template_file:
                template = mako.template.Template(template_file.read())
                with open(credits_path, "w") as credits_file:
                    credits_file.write(template.render(version=version))
            delete(template_path)

            print("Creating dmg")
            os.symlink('/Applications', path.join(dir_to_dmg, 'Applications'))
            dmg_path = path.join(target_dir, "servo-tech-demo.dmg")

            if path.exists(dmg_path):
                print("Deleting existing dmg")
                os.remove(dmg_path)

            try:
                subprocess.check_call([
                    'hdiutil', 'create', '-volname', 'Servo', '-megabytes',
                    '900', dmg_path, '-srcfolder', dir_to_dmg
                ])
            except subprocess.CalledProcessError as e:
                print("Packaging MacOS dmg exited with return value %d" %
                      e.returncode)
                return e.returncode
            print("Cleaning up")
            delete(dir_to_dmg)
            print("Packaged Servo into " + dmg_path)

            print("Creating brew package")
            dir_to_brew = path.join(target_dir, 'brew_tmp')
            dir_to_tar = path.join(target_dir, 'brew')
            if not path.exists(dir_to_tar):
                os.makedirs(dir_to_tar)
            tar_path = path.join(dir_to_tar, "servo.tar.gz")
            if path.exists(dir_to_brew):
                print("Cleaning up from previous packaging")
                delete(dir_to_brew)
            if path.exists(tar_path):
                print("Deleting existing package")
                os.remove(tar_path)
            shutil.copytree(path.join(dir_to_root, 'resources'),
                            path.join(dir_to_brew, 'resources'))
            os.makedirs(path.join(dir_to_brew, 'bin'))
            shutil.copy2(binary_path, path.join(dir_to_brew, 'bin', 'servo'))
            # Note that in the context of Homebrew, libexec is reserved for private use by the formula
            # and therefore is not symlinked into HOMEBREW_PREFIX.
            os.makedirs(path.join(dir_to_brew, 'libexec'))
            copy_dependencies(path.join(dir_to_brew, 'bin', 'servo'),
                              path.join(dir_to_brew, 'libexec'))
            archive_deterministically(dir_to_brew,
                                      tar_path,
                                      prepend_path='servo/')
            delete(dir_to_brew)
            print("Packaged Servo into " + tar_path)
        elif is_windows():
            dir_to_msi = path.join(target_dir, 'msi')
            if path.exists(dir_to_msi):
                print("Cleaning up from previous packaging")
                delete(dir_to_msi)
            os.makedirs(dir_to_msi)

            print("Copying files")
            dir_to_temp = path.join(dir_to_msi, 'temp')
            dir_to_temp_servo = path.join(dir_to_temp, 'servo')
            dir_to_resources = path.join(dir_to_temp_servo, 'resources')
            shutil.copytree(path.join(dir_to_root, 'resources'),
                            dir_to_resources)
            shutil.copy(binary_path, dir_to_temp_servo)
            copy_windows_dependencies(target_dir, dir_to_temp_servo)

            change_prefs(dir_to_resources, "windows")

            # generate Servo.wxs
            import mako.template
            template_path = path.join(dir_to_root, "support", "windows",
                                      "Servo.wxs.mako")
            template = mako.template.Template(open(template_path).read())
            wxs_path = path.join(dir_to_msi, "Installer.wxs")
            open(wxs_path, "w").write(
                template.render(exe_path=target_dir,
                                dir_to_temp=dir_to_temp_servo,
                                resources_path=dir_to_resources))

            # run candle and light
            print("Creating MSI")
            try:
                with cd(dir_to_msi):
                    subprocess.check_call(['candle', wxs_path])
            except subprocess.CalledProcessError as e:
                print("WiX candle exited with return value %d" % e.returncode)
                return e.returncode
            try:
                wxsobj_path = "{}.wixobj".format(path.splitext(wxs_path)[0])
                with cd(dir_to_msi):
                    subprocess.check_call(['light', wxsobj_path])
            except subprocess.CalledProcessError as e:
                print("WiX light exited with return value %d" % e.returncode)
                return e.returncode
            print("Packaged Servo into " +
                  path.join(dir_to_msi, "Installer.msi"))

            # Download GStreamer installer. Only once.
            dir_to_gst_deps = path.join(dir_to_msi, 'Gstreamer.msi')
            gstreamer_msi_path = path.join(target_dir, 'Gstreamer.msi')
            if not os.path.exists(gstreamer_msi_path):
                print('Fetching GStreamer installer. This may take a while...')
                gstreamer_url = 'https://gstreamer.freedesktop.org/data/pkg/windows/1.14.2/gstreamer-1.0-x86-1.14.2.msi'
                urllib.urlretrieve(gstreamer_url, gstreamer_msi_path)
            shutil.copy(gstreamer_msi_path, dir_to_gst_deps)

            # Generate bundle with GStreamer and Servo installers.
            print("Creating bundle")
            shutil.copy(
                path.join(dir_to_root, 'support', 'windows', 'Servo.wxs'),
                dir_to_msi)
            bundle_wxs_path = path.join(dir_to_msi, 'Servo.wxs')
            try:
                with cd(dir_to_msi):
                    subprocess.check_call(
                        ['candle', bundle_wxs_path, '-ext', 'WixBalExtension'])
            except subprocess.CalledProcessError as e:
                print("WiX candle exited with return value %d" % e.returncode)
                return e.returncode
            try:
                wxsobj_path = "{}.wixobj".format(
                    path.splitext(bundle_wxs_path)[0])
                with cd(dir_to_msi):
                    subprocess.check_call(
                        ['light', wxsobj_path, '-ext', 'WixBalExtension'])
            except subprocess.CalledProcessError as e:
                print("WiX light exited with return value %d" % e.returncode)
                return e.returncode
            print("Packaged Servo into " + path.join(dir_to_msi, "Servo.msi"))

            print("Creating ZIP")
            shutil.make_archive(path.join(dir_to_msi, "Servo"), "zip",
                                dir_to_temp)
            print("Packaged Servo into " + path.join(dir_to_msi, "Servo.zip"))

            print("Cleaning up")
            delete(dir_to_temp)
        else:
            dir_to_temp = path.join(target_dir, 'packaging-temp')
            if path.exists(dir_to_temp):
                # TODO(aneeshusa): lock dir_to_temp to prevent simultaneous builds
                print("Cleaning up from previous packaging")
                delete(dir_to_temp)

            print("Copying files")
            dir_to_resources = path.join(dir_to_temp, 'resources')
            shutil.copytree(path.join(dir_to_root, 'resources'),
                            dir_to_resources)
            shutil.copy(binary_path, dir_to_temp)

            change_prefs(dir_to_resources, "linux")

            print("Creating tarball")
            tar_path = path.join(target_dir, 'servo-tech-demo.tar.gz')

            archive_deterministically(dir_to_temp,
                                      tar_path,
                                      prepend_path='servo/')

            print("Cleaning up")
            delete(dir_to_temp)
            print("Packaged Servo into " + tar_path)
Example #11
0
    def package(self, release=False, dev=False, android=None, magicleap=None, debug=False,
                debugger=None, target=None, flavor=None, maven=False):
        if android is None:
            android = self.config["build"]["android"]
        if target and android:
            print("Please specify either --target or --android.")
            sys.exit(1)
        if not android:
            android = self.handle_android_target(target)
        else:
            target = self.config["android"]["target"]
        env = self.build_env(target=target)
        binary_path = self.get_binary_path(release, dev, android=android, magicleap=magicleap)
        dir_to_root = self.get_top_dir()
        target_dir = path.dirname(binary_path)
        if magicleap:
            if platform.system() not in ["Darwin"]:
                raise Exception("Magic Leap builds are only supported on macOS.")
            if not env.get("MAGICLEAP_SDK"):
                raise Exception("Magic Leap builds need the MAGICLEAP_SDK environment variable")
            if not env.get("MLCERT"):
                raise Exception("Magic Leap builds need the MLCERT environment variable")
            mabu = path.join(env.get("MAGICLEAP_SDK"), "mabu")
            package = "./support/magicleap/Servo2D/Servo2D.package"
            if dev:
                build_type = "lumin_debug"
            else:
                build_type = "lumin_release"
            argv = [
                mabu,
                "-o", target_dir,
                "-t", build_type,
                # Servo SEGVs if we don't set the debuggable flag in the mpk's taildata
                # https://github.com/servo/servo/issues/22188
                "--add-tail-data-args=--debuggable",
                package
            ]
            try:
                subprocess.check_call(argv, env=env)
            except subprocess.CalledProcessError as e:
                print("Packaging Magic Leap exited with return value %d" % e.returncode)
                return e.returncode
        elif android:
            android_target = self.config["android"]["target"]
            if "aarch64" in android_target:
                build_type = "Arm64"
            elif "armv7" in android_target:
                build_type = "Armv7"
            elif "i686" in android_target:
                build_type = "x86"
            else:
                build_type = "Arm"

            if dev:
                build_mode = "Debug"
            else:
                build_mode = "Release"

            flavor_name = "Main"
            if flavor is not None:
                flavor_name = flavor.title()

            vr = flavor == "googlevr" or flavor == "oculusvr"

            dir_to_resources = path.join(self.get_top_dir(), 'target', 'android', 'resources')
            if path.exists(dir_to_resources):
                delete(dir_to_resources)

            shutil.copytree(path.join(dir_to_root, 'resources'), dir_to_resources)
            change_prefs(dir_to_resources, "android", vr=vr)

            variant = ":assemble" + flavor_name + build_type + build_mode
            apk_task_name = ":servoapp" + variant
            aar_task_name = ":servoview" + variant
            maven_task_name = ":servoview:uploadArchive"
            argv = ["./gradlew", "--no-daemon", apk_task_name, aar_task_name]
            if maven:
                argv.append(maven_task_name)
            try:
                with cd(path.join("support", "android", "apk")):
                    subprocess.check_call(argv, env=env)
            except subprocess.CalledProcessError as e:
                print("Packaging Android exited with return value %d" % e.returncode)
                return e.returncode
        elif is_macosx():
            print("Creating Servo.app")
            dir_to_dmg = path.join(target_dir, 'dmg')
            dir_to_app = path.join(dir_to_dmg, 'Servo.app')
            dir_to_resources = path.join(dir_to_app, 'Contents', 'Resources')
            if path.exists(dir_to_dmg):
                print("Cleaning up from previous packaging")
                delete(dir_to_dmg)

            print("Copying files")
            shutil.copytree(path.join(dir_to_root, 'resources'), dir_to_resources)
            shutil.copy2(path.join(dir_to_root, 'Info.plist'), path.join(dir_to_app, 'Contents', 'Info.plist'))

            content_dir = path.join(dir_to_app, 'Contents', 'MacOS')
            os.makedirs(content_dir)
            shutil.copy2(binary_path, content_dir)

            change_prefs(dir_to_resources, "macosx")

            print("Finding dylibs and relinking")
            copy_dependencies(path.join(content_dir, 'servo'), content_dir)

            print("Adding version to Credits.rtf")
            version_command = [binary_path, '--version']
            p = subprocess.Popen(version_command,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE,
                                 universal_newlines=True)
            version, stderr = p.communicate()
            if p.returncode != 0:
                raise Exception("Error occurred when getting Servo version: " + stderr)
            version = "Nightly version: " + version

            import mako.template
            template_path = path.join(dir_to_resources, 'Credits.rtf.mako')
            credits_path = path.join(dir_to_resources, 'Credits.rtf')
            with open(template_path) as template_file:
                template = mako.template.Template(template_file.read())
                with open(credits_path, "w") as credits_file:
                    credits_file.write(template.render(version=version))
            delete(template_path)

            print("Creating dmg")
            os.symlink('/Applications', path.join(dir_to_dmg, 'Applications'))
            dmg_path = path.join(target_dir, "servo-tech-demo.dmg")

            if path.exists(dmg_path):
                print("Deleting existing dmg")
                os.remove(dmg_path)

            try:
                subprocess.check_call(['hdiutil', 'create',
                                       '-volname', 'Servo',
                                       '-megabytes', '900',
                                       dmg_path,
                                       '-srcfolder', dir_to_dmg])
            except subprocess.CalledProcessError as e:
                print("Packaging MacOS dmg exited with return value %d" % e.returncode)
                return e.returncode
            print("Cleaning up")
            delete(dir_to_dmg)
            print("Packaged Servo into " + dmg_path)

            print("Creating brew package")
            dir_to_brew = path.join(target_dir, 'brew_tmp')
            dir_to_tar = path.join(target_dir, 'brew')
            if not path.exists(dir_to_tar):
                os.makedirs(dir_to_tar)
            tar_path = path.join(dir_to_tar, "servo.tar.gz")
            if path.exists(dir_to_brew):
                print("Cleaning up from previous packaging")
                delete(dir_to_brew)
            if path.exists(tar_path):
                print("Deleting existing package")
                os.remove(tar_path)
            shutil.copytree(path.join(dir_to_root, 'resources'), path.join(dir_to_brew, 'resources'))
            os.makedirs(path.join(dir_to_brew, 'bin'))
            shutil.copy2(binary_path, path.join(dir_to_brew, 'bin', 'servo'))
            # Note that in the context of Homebrew, libexec is reserved for private use by the formula
            # and therefore is not symlinked into HOMEBREW_PREFIX.
            os.makedirs(path.join(dir_to_brew, 'libexec'))
            copy_dependencies(path.join(dir_to_brew, 'bin', 'servo'), path.join(dir_to_brew, 'libexec'))
            archive_deterministically(dir_to_brew, tar_path, prepend_path='servo/')
            delete(dir_to_brew)
            print("Packaged Servo into " + tar_path)
        elif is_windows():
            dir_to_msi = path.join(target_dir, 'msi')
            if path.exists(dir_to_msi):
                print("Cleaning up from previous packaging")
                delete(dir_to_msi)
            os.makedirs(dir_to_msi)

            print("Copying files")
            dir_to_temp = path.join(dir_to_msi, 'temp')
            dir_to_temp_servo = path.join(dir_to_temp, 'servo')
            dir_to_resources = path.join(dir_to_temp_servo, 'resources')
            shutil.copytree(path.join(dir_to_root, 'resources'), dir_to_resources)
            shutil.copy(binary_path, dir_to_temp_servo)
            copy_windows_dependencies(target_dir, dir_to_temp_servo)

            change_prefs(dir_to_resources, "windows")

            # generate Servo.wxs
            import mako.template
            template_path = path.join(dir_to_root, "support", "windows", "Servo.wxs.mako")
            template = mako.template.Template(open(template_path).read())
            wxs_path = path.join(dir_to_msi, "Installer.wxs")
            open(wxs_path, "w").write(template.render(
                exe_path=target_dir,
                dir_to_temp=dir_to_temp_servo,
                resources_path=dir_to_resources))

            # run candle and light
            print("Creating MSI")
            try:
                with cd(dir_to_msi):
                    subprocess.check_call(['candle', wxs_path])
            except subprocess.CalledProcessError as e:
                print("WiX candle exited with return value %d" % e.returncode)
                return e.returncode
            try:
                wxsobj_path = "{}.wixobj".format(path.splitext(wxs_path)[0])
                with cd(dir_to_msi):
                    subprocess.check_call(['light', wxsobj_path])
            except subprocess.CalledProcessError as e:
                print("WiX light exited with return value %d" % e.returncode)
                return e.returncode
            dir_to_installer = path.join(dir_to_msi, "Installer.msi")
            print("Packaged Servo into " + dir_to_installer)

            # Download GStreamer installer. Only once.
            gstreamer_msi_path = path.join(dir_to_msi, 'Gstreamer.msi')
            if not os.path.exists(gstreamer_msi_path):
                print('Fetching GStreamer installer. This may take a while...')
                gstreamer_url = 'https://gstreamer.freedesktop.org/data/pkg/windows/1.14.2/gstreamer-1.0-x86-1.14.2.msi'
                urllib.urlretrieve(gstreamer_url, gstreamer_msi_path)

            # Generate bundle with GStreamer and Servo installers.
            print("Creating bundle")
            shutil.copy(path.join(dir_to_root, 'support', 'windows', 'Servo.wxs'), dir_to_msi)
            bundle_wxs_path = path.join(dir_to_msi, 'Servo.wxs')
            try:
                with cd(dir_to_msi):
                    subprocess.check_call(['candle', bundle_wxs_path, '-ext', 'WixBalExtension'])
            except subprocess.CalledProcessError as e:
                print("WiX candle exited with return value %d" % e.returncode)
                return e.returncode
            try:
                wxsobj_path = "{}.wixobj".format(path.splitext(bundle_wxs_path)[0])
                with cd(dir_to_msi):
                    subprocess.check_call(['light', wxsobj_path, '-ext', 'WixBalExtension'])
            except subprocess.CalledProcessError as e:
                print("WiX light exited with return value %d" % e.returncode)
                return e.returncode
            print("Packaged Servo into " + path.join(dir_to_msi, "Servo.msi"))

            print("Creating ZIP")
            shutil.make_archive(path.join(dir_to_msi, "Servo"), "zip", dir_to_temp)
            print("Packaged Servo into " + path.join(dir_to_msi, "Servo.zip"))

            print("Cleaning up")
            delete(dir_to_temp)
            delete(dir_to_installer)
        else:
            dir_to_temp = path.join(target_dir, 'packaging-temp')
            if path.exists(dir_to_temp):
                # TODO(aneeshusa): lock dir_to_temp to prevent simultaneous builds
                print("Cleaning up from previous packaging")
                delete(dir_to_temp)

            print("Copying files")
            dir_to_resources = path.join(dir_to_temp, 'resources')
            shutil.copytree(path.join(dir_to_root, 'resources'), dir_to_resources)
            shutil.copy(binary_path, dir_to_temp)

            change_prefs(dir_to_resources, "linux")

            print("Creating tarball")
            tar_path = path.join(target_dir, 'servo-tech-demo.tar.gz')

            archive_deterministically(dir_to_temp, tar_path, prepend_path='servo/')

            print("Cleaning up")
            delete(dir_to_temp)
            print("Packaged Servo into " + tar_path)
Example #12
0
    def package(self,
                release=False,
                dev=False,
                android=None,
                debug=False,
                debugger=None):
        env = self.build_env()
        if android is None:
            android = self.config["build"]["android"]
        binary_path = self.get_binary_path(release, dev, android=android)
        if android:
            if dev:
                env["NDK_DEBUG"] = "1"
                env["ANT_FLAVOR"] = "debug"
                dev_flag = "-d"
            else:
                env["ANT_FLAVOR"] = "release"
                dev_flag = ""

            target_dir = os.path.dirname(binary_path)
            output_apk = "{}.apk".format(binary_path)
            try:
                with cd(path.join("support", "android", "build-apk")):
                    subprocess.check_call([
                        "cargo", "run", "--", dev_flag, "-o", output_apk, "-t",
                        target_dir, "-r",
                        self.get_top_dir()
                    ],
                                          env=env)
            except subprocess.CalledProcessError as e:
                print("Packaging Android exited with return value %d" %
                      e.returncode)
                return e.returncode
        elif is_macosx():
            dir_to_build = '/'.join(binary_path.split('/')[:-1])
            dir_to_dmg = '/'.join(binary_path.split('/')[:-2]) + '/dmg'
            dir_to_app = dir_to_dmg + '/Servo.app'
            dir_to_resources = dir_to_app + '/Contents/Resources/'
            dir_to_root = '/'.join(binary_path.split('/')[:-3])
            if os.path.exists(dir_to_dmg):
                print("Cleaning up from previous packaging")
                delete(dir_to_dmg)
            browserhtml_path = find_dep_path_newest('browserhtml', binary_path)
            if browserhtml_path is None:
                print(
                    "Could not find browserhtml package; perhaps you haven't built Servo."
                )
                return 1

            print("Copying files")
            shutil.copytree(dir_to_root + '/resources', dir_to_resources)
            shutil.copytree(browserhtml_path,
                            dir_to_resources + browserhtml_path.split('/')[-1])
            shutil.copy2(dir_to_root + '/Info.plist',
                         dir_to_app + '/Contents/Info.plist')
            os.makedirs(dir_to_app + '/Contents/MacOS/')
            shutil.copy2(dir_to_build + '/servo',
                         dir_to_app + '/Contents/MacOS/')

            print("Swapping prefs")
            delete(dir_to_resources + '/prefs.json')
            shutil.copy2(dir_to_resources + 'package-prefs.json',
                         dir_to_resources + 'prefs.json')
            delete(dir_to_resources + '/package-prefs.json')

            print("Finding dylibs and relinking")
            need_checked = set([dir_to_app + '/Contents/MacOS/servo'])
            checked = set()
            while need_checked:
                checking = set(need_checked)
                need_checked = set()
                for f in checking:
                    # No need to check these for their dylibs
                    if '/System/Library' in f or '/usr/lib' in f:
                        continue
                    need_relinked = set(otool(f))
                    new_path = dir_to_app + '/Contents/MacOS/' + f.split(
                        '/')[-1]
                    if not os.path.exists(new_path):
                        shutil.copyfile(f, new_path)
                    for dylib in need_relinked:
                        if '/System/Library' in dylib or '/usr/lib' in dylib or 'servo' in dylib:
                            continue
                        install_name_tool(dylib,
                                          dylib.split('/')[-1], new_path)
                    need_checked.update(need_relinked)
                checked.update(checking)
                need_checked.difference_update(checked)

            print("Writing run-servo")
            bhtml_path = path.join('${0%/*}/../Resources',
                                   browserhtml_path.split('/')[-1], 'out',
                                   'index.html')
            runservo = os.open(dir_to_app + '/Contents/MacOS/run-servo',
                               os.O_WRONLY | os.O_CREAT, int("0755", 8))
            os.write(runservo, '#!/bin/bash\nexec ${0%/*}/servo ' + bhtml_path)
            os.close(runservo)

            print("Creating dmg")
            os.symlink('/Applications', dir_to_dmg + '/Applications')
            dmg_path = '/'.join(dir_to_build.split('/')[:-1]) + '/'
            dmg_path += datetime.utcnow().replace(microsecond=0).isoformat()
            dmg_path += "-servo-tech-demo.dmg"
            try:
                subprocess.check_call([
                    'hdiutil', 'create', '-volname', 'Servo', dmg_path,
                    '-srcfolder', dir_to_dmg
                ])
            except subprocess.CalledProcessError as e:
                print("Packaging MacOS dmg exited with return value %d" %
                      e.returncode)
                return e.returncode
            print("Cleaning up")
            delete(dir_to_dmg)
            print("Packaged Servo into " + dmg_path)
        else:
            dir_to_package = '/'.join(binary_path.split('/')[:-1])
            browserhtml_path = find_dep_path_newest('browserhtml', binary_path)
            if browserhtml_path is None:
                print(
                    "Could not find browserhtml package; perhaps you haven't built Servo."
                )
                return 1
            print("Deleting unused files")
            keep = ['servo', 'resources', 'build']
            for f in os.listdir(dir_to_package + '/'):
                if f not in keep:
                    delete(dir_to_package + '/' + f)
            for f in os.listdir(dir_to_package + '/build/'):
                if 'browserhtml' not in f:
                    delete(dir_to_package + '/build/' + f)
            print("Writing runservo.sh")
            # TODO: deduplicate this arg list from post_build_commands
            servo_args = [
                '-w', '-b', '--pref', 'dom.mozbrowser.enabled', '--pref',
                'dom.forcetouch.enabled', '--pref',
                'shell.builtin-key-shortcuts.enabled=false',
                path.join(browserhtml_path, 'out', 'index.html')
            ]

            runservo = os.open(dir_to_package + 'runservo.sh',
                               os.O_WRONLY | os.O_CREAT, int("0755", 8))
            os.write(runservo, "./servo " + ' '.join(servo_args))
            os.close(runservo)
            print("Creating tarball")
            tar_path = '/'.join(dir_to_package.split('/')[:-1]) + '/'
            tar_path += datetime.utcnow().replace(microsecond=0).isoformat()
            tar_path += "-servo-tech-demo.tar.gz"
            with tarfile.open(tar_path, "w:gz") as tar:
                # arcname is to add by relative rather than absolute path
                tar.add(dir_to_package, arcname='servo/')
            print("Packaged Servo into " + tar_path)
    def package(self, release=False, dev=False, android=None, debug=False, debugger=None, target=None):
        env = self.build_env()
        if android is None:
            android = self.config["build"]["android"]
        if target and android:
            print("Please specify either --target or --android.")
            sys.exit(1)
        if not android:
            android = self.handle_android_target(target)
        binary_path = self.get_binary_path(release, dev, android=android)
        dir_to_root = self.get_top_dir()
        target_dir = path.dirname(binary_path)
        if android:
            android_target = self.config["android"]["target"]
            if "aarch64" in android_target:
                build_type = "Arm64"
            elif "armv7" in android_target:
                build_type = "Armv7"
            else:
                build_type = "Arm"

            if dev:
                build_mode = "Debug"
            else:
                build_mode = "Release"

            task_name = "assemble" + build_type + build_mode
            try:
                with cd(path.join("support", "android", "apk")):
                    subprocess.check_call(["./gradlew", "--no-daemon", task_name], env=env)
            except subprocess.CalledProcessError as e:
                print("Packaging Android exited with return value %d" % e.returncode)
                return e.returncode
        elif is_macosx():
            print("Creating ServoShell.app")
            dir_to_dmg = path.join(target_dir, 'dmg')
            dir_to_app = path.join(dir_to_dmg, 'ServoShell.app')
            dir_to_resources = path.join(dir_to_app, 'Contents', 'Resources')
            if path.exists(dir_to_dmg):
                print("Cleaning up from previous packaging")
                delete(dir_to_dmg)

            mmtabbar_path = path.join(self.get_target_dir(), 'MMTabBarView', 'Release', 'MMTabBarView.framework')
            if path.exists(mmtabbar_path):
                dir_to_framework = path.join(dir_to_app, 'Contents', 'Frameworks', 'MMTabBarView.framework')
                shutil.copytree(mmtabbar_path, dir_to_framework)
                nibs_path = path.join(self.get_target_dir(), 'nibs')
                shutil.copytree(nibs_path, dir_to_resources + '/nibs')

            print("Copying files")
            shutil.copytree(path.join(dir_to_root, 'servo_resources'), path.join(dir_to_resources, 'servo_resources'))
            shutil.copytree(path.join(dir_to_root, 'shell_resources'), path.join(dir_to_resources, 'shell_resources'))

            content_dir = path.join(dir_to_app, 'Contents', 'MacOS')
            os.makedirs(content_dir)
            shutil.copy2(binary_path, content_dir)

            print("Finding dylibs and relinking")
            copy_dependencies(path.join(content_dir, 'servoshell'), content_dir)

            print("Adding version to Credits.rtf")
            version_command = [binary_path, '--version']
            p = subprocess.Popen(version_command,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE,
                                 universal_newlines=True)
            version, stderr = p.communicate()
            if p.returncode != 0:
                raise Exception("Error occurred when getting ServoShell version: " + stderr)

            import mako.template

            template_path = path.join(dir_to_root, "support", "macos", "Credits.rtf.mako")
            credits_path = path.join(dir_to_resources, 'Credits.rtf')
            with open(template_path) as template_file:
                template = mako.template.Template(template_file.read())
                with open(credits_path, "w") as credits_file:
                    credits_file.write(template.render(version=version))

            template_path = path.join(dir_to_root, "support", "macos", "Info.plist.mako")
            plist_path = path.join(dir_to_app, 'Contents', 'Info.plist')
            with open(template_path) as template_file:
                template = mako.template.Template(template_file.read())
                with open(plist_path, "w") as plist_file:
                    plist_file.write(template.render(version=version))

            print("Creating dmg")
            os.symlink('/Applications', path.join(dir_to_dmg, 'Applications'))
            dmg_path = path.join(target_dir, "servoshell.dmg")

            if path.exists(dmg_path):
                print("Deleting existing dmg")
                os.remove(dmg_path)

            try:
                subprocess.check_call(['hdiutil', 'create',
                                       '-volname', 'Servo',
                                       '-megabytes', '900',
                                       dmg_path,
                                       '-srcfolder', dir_to_dmg])
            except subprocess.CalledProcessError as e:
                print("Packaging MacOS dmg exited with return value %d" % e.returncode)
                return e.returncode
            print("Cleaning up")
            delete(dir_to_dmg)
            print("Packaged Servo into " + dmg_path)

        elif is_windows():
            dir_to_msi = path.join(target_dir, 'msi')
            if path.exists(dir_to_msi):
                print("Cleaning up from previous packaging")
                delete(dir_to_msi)
            os.makedirs(dir_to_msi)

            print("Copying files")
            dir_to_temp = path.join(dir_to_msi, 'temp')
            dir_to_temp_servo = path.join(dir_to_temp, 'servoshell')
            dir_to_resources = path.join(dir_to_temp_servo, 'resources')
            shutil.copytree(path.join(dir_to_root, 'shell_resources'), path.join(dir_to_resources, 'shell_resources'))
            shutil.copytree(path.join(dir_to_root, 'servo_resources'), path.join(dir_to_resources, 'servo_resources'))
            shutil.copy(binary_path, dir_to_temp_servo)
            shutil.copy("{}.manifest".format(binary_path), dir_to_temp_servo)
            copy_windows_dependencies(target_dir, dir_to_temp_servo)

            # generate Servo.wxs
            import mako.template
            template_path = path.join(dir_to_root, "support", "windows", "ServoShell.wxs.mako")
            template = mako.template.Template(open(template_path).read())
            wxs_path = path.join(dir_to_msi, "ServoShell.wxs")
            open(wxs_path, "w").write(template.render(
                exe_path=target_dir,
                dir_to_temp=dir_to_temp_servo,
                resources_path=dir_to_resources))

            # run candle and light
            print("Creating MSI: " + wxs_path)
            try:
                with cd(dir_to_msi):
                    subprocess.check_call(['candle', wxs_path])
            except subprocess.CalledProcessError as e:
                print("WiX candle exited with return value %d" % e.returncode)
                return e.returncode
            try:
                wxsobj_path = "{}.wixobj".format(path.splitext(wxs_path)[0])
                with cd(dir_to_msi):
                    subprocess.check_call(['light', wxsobj_path])
            except subprocess.CalledProcessError as e:
                print("WiX light exited with return value %d" % e.returncode)
                return e.returncode
            print("Packaged ServoShell into " + path.join(dir_to_msi, "ServoShell.msi"))

            print("Creating ZIP")
            shutil.make_archive(path.join(dir_to_msi, "ServoShell"), "zip", dir_to_temp)
            print("Packaged ServoShell into " + path.join(dir_to_msi, "ServoShell.zip"))

            print("Cleaning up")
            delete(dir_to_temp)
        else:
            dir_to_temp = path.join(target_dir, 'packaging-temp')
            if path.exists(dir_to_temp):
                # TODO(aneeshusa): lock dir_to_temp to prevent simultaneous builds
                print("Cleaning up from previous packaging")
                delete(dir_to_temp)

            print("Copying files")
            dir_to_resources = path.join(dir_to_temp, 'resources')

            shutil.copytree(path.join(dir_to_root, 'shell_resources'), path.join(dir_to_resources, 'shell_resources'))
            shutil.copytree(path.join(dir_to_root, 'servo_resources'), path.join(dir_to_resources, 'servo_resources'))

            shutil.copy(binary_path, dir_to_temp)

            print("Creating tarball")
            tar_path = path.join(target_dir, 'servoshell.tar.gz')

            archive_deterministically(dir_to_temp, tar_path, prepend_path='servoshell/')

            print("Cleaning up")
            delete(dir_to_temp)
            print("Packaged ServoShell into " + tar_path)
Example #14
0
    def package(self,
                release=False,
                dev=False,
                android=None,
                debug=False,
                debugger=None):
        env = self.build_env()
        if android is None:
            android = self.config["build"]["android"]
        binary_path = self.get_binary_path(release, dev, android=android)
        dir_to_root = self.get_top_dir()
        target_dir = path.dirname(binary_path)
        if android:
            if dev:
                env["NDK_DEBUG"] = "1"
                env["ANT_FLAVOR"] = "debug"
                dev_flag = "-d"
            else:
                env["ANT_FLAVOR"] = "release"
                dev_flag = ""

            output_apk = "{}.apk".format(binary_path)

            dir_to_apk = path.join(target_dir, "apk")
            if path.exists(dir_to_apk):
                print("Cleaning up from previous packaging")
                delete(dir_to_apk)
            shutil.copytree(
                path.join(dir_to_root, "support", "android", "apk"),
                dir_to_apk)

            blurdroid_path = find_dep_path_newest('blurdroid', binary_path)
            if blurdroid_path is None:
                print(
                    "Could not find blurdroid package; perhaps you haven't built Servo."
                )
                return 1
            else:
                dir_to_libs = path.join(dir_to_apk, "libs")
                if not path.exists(dir_to_libs):
                    os.makedirs(dir_to_libs)
                shutil.copy2(blurdroid_path + '/out/blurdroid.jar',
                             dir_to_libs)
            try:
                with cd(path.join("support", "android", "build-apk")):
                    subprocess.check_call([
                        "cargo", "run", "--", dev_flag, "-o", output_apk, "-t",
                        target_dir, "-r", dir_to_root
                    ],
                                          env=env)
            except subprocess.CalledProcessError as e:
                print("Packaging Android exited with return value %d" %
                      e.returncode)
                return e.returncode
        elif is_macosx():
            print("Creating Servo.app")
            dir_to_dmg = path.join(target_dir, 'dmg')
            dir_to_app = path.join(dir_to_dmg, 'Servo.app')
            dir_to_resources = path.join(dir_to_app, 'Contents', 'Resources')
            if path.exists(dir_to_dmg):
                print("Cleaning up from previous packaging")
                delete(dir_to_dmg)
            browserhtml_path = get_browserhtml_path(binary_path)

            print("Copying files")
            shutil.copytree(path.join(dir_to_root, 'resources'),
                            dir_to_resources)
            shutil.copytree(browserhtml_path,
                            path.join(dir_to_resources, 'browserhtml'))
            shutil.copy2(path.join(dir_to_root, 'Info.plist'),
                         path.join(dir_to_app, 'Contents', 'Info.plist'))

            content_dir = path.join(dir_to_app, 'Contents', 'MacOS')
            os.makedirs(content_dir)
            shutil.copy2(binary_path, content_dir)

            change_prefs(dir_to_resources, "macosx")

            print("Finding dylibs and relinking")
            copy_dependencies(path.join(content_dir, 'servo'), content_dir)

            print("Adding version to Credits.rtf")
            version_command = [binary_path, '--version']
            p = subprocess.Popen(version_command,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE,
                                 universal_newlines=True)
            version, stderr = p.communicate()
            if p.returncode != 0:
                raise Exception("Error occurred when getting Servo version: " +
                                stderr)
            version = "Nightly version: " + version

            template_path = path.join(dir_to_resources, 'Credits.rtf.mako')
            credits_path = path.join(dir_to_resources, 'Credits.rtf')
            with open(template_path) as template_file:
                template = mako.template.Template(template_file.read())
                with open(credits_path, "w") as credits_file:
                    credits_file.write(template.render(version=version))
            delete(template_path)

            print("Creating dmg")
            os.symlink('/Applications', path.join(dir_to_dmg, 'Applications'))
            dmg_path = path.join(target_dir, "servo-tech-demo.dmg")

            try:
                subprocess.check_call([
                    'hdiutil', 'create', '-volname', 'Servo', dmg_path,
                    '-srcfolder', dir_to_dmg
                ])
            except subprocess.CalledProcessError as e:
                print("Packaging MacOS dmg exited with return value %d" %
                      e.returncode)
                return e.returncode
            print("Cleaning up")
            delete(dir_to_dmg)
            print("Packaged Servo into " + dmg_path)

            print("Creating brew package")
            dir_to_brew = path.join(target_dir, 'brew_tmp')
            dir_to_tar = path.join(target_dir, 'brew')
            if not path.exists(dir_to_tar):
                os.makedirs(dir_to_tar)
            tar_path = path.join(dir_to_tar, "servo.tar.gz")
            if path.exists(dir_to_brew):
                print("Cleaning up from previous packaging")
                delete(dir_to_brew)
            if path.exists(tar_path):
                print("Deleting existing package")
                os.remove(tar_path)
            shutil.copytree(path.join(dir_to_root, 'resources'),
                            path.join(dir_to_brew, 'resources'))
            os.makedirs(path.join(dir_to_brew, 'bin'))
            shutil.copy2(binary_path, path.join(dir_to_brew, 'bin', 'servo'))
            # Note that in the context of Homebrew, libexec is reserved for private use by the formula
            # and therefore is not symlinked into HOMEBREW_PREFIX.
            os.makedirs(path.join(dir_to_brew, 'libexec'))
            copy_dependencies(path.join(dir_to_brew, 'bin', 'servo'),
                              path.join(dir_to_brew, 'libexec'))
            archive_deterministically(dir_to_brew,
                                      tar_path,
                                      prepend_path='servo/')
            delete(dir_to_brew)
            print("Packaged Servo into " + tar_path)
        elif is_windows():
            dir_to_msi = path.join(target_dir, 'msi')
            if path.exists(dir_to_msi):
                print("Cleaning up from previous packaging")
                delete(dir_to_msi)
            os.makedirs(dir_to_msi)
            browserhtml_path = get_browserhtml_path(binary_path)

            print("Copying files")
            dir_to_resources = path.join(dir_to_msi, 'resources')
            shutil.copytree(path.join(dir_to_root, 'resources'),
                            dir_to_resources)

            change_prefs(dir_to_resources, "windows")

            # generate Servo.wxs
            template_path = path.join(dir_to_root, "support", "windows",
                                      "Servo.wxs.mako")
            template = Template(open(template_path).read())
            wxs_path = path.join(dir_to_msi, "Servo.wxs")
            open(wxs_path, "w").write(
                template.render(exe_path=target_dir,
                                resources_path=dir_to_resources,
                                browserhtml_path=browserhtml_path))

            # run candle and light
            print("Creating MSI")
            try:
                with cd(dir_to_msi):
                    subprocess.check_call(['candle', wxs_path])
            except subprocess.CalledProcessError as e:
                print("WiX candle exited with return value %d" % e.returncode)
                return e.returncode
            try:
                wxsobj_path = "{}.wixobj".format(path.splitext(wxs_path)[0])
                with cd(dir_to_msi):
                    subprocess.check_call(['light', wxsobj_path])
            except subprocess.CalledProcessError as e:
                print("WiX light exited with return value %d" % e.returncode)
                return e.returncode
            msi_path = path.join(dir_to_msi, "Servo.msi")
            print("Packaged Servo into {}".format(msi_path))
        else:
            dir_to_temp = path.join(target_dir, 'packaging-temp')
            browserhtml_path = get_browserhtml_path(binary_path)
            if path.exists(dir_to_temp):
                # TODO(aneeshusa): lock dir_to_temp to prevent simultaneous builds
                print("Cleaning up from previous packaging")
                delete(dir_to_temp)

            print("Copying files")
            dir_to_resources = path.join(dir_to_temp, 'resources')
            shutil.copytree(path.join(dir_to_root, 'resources'),
                            dir_to_resources)
            shutil.copytree(browserhtml_path,
                            path.join(dir_to_temp, 'browserhtml'))
            shutil.copy(binary_path, dir_to_temp)

            change_prefs(dir_to_resources, "linux")

            print("Creating tarball")
            tar_path = path.join(target_dir, 'servo-tech-demo.tar.gz')

            archive_deterministically(dir_to_temp,
                                      tar_path,
                                      prepend_path='servo/')

            print("Cleaning up")
            delete(dir_to_temp)
            print("Packaged Servo into " + tar_path)
Example #15
0
    def package(self, release=False, dev=False, android=None, debug=False, debugger=None):
        env = self.build_env()
        if android is None:
            android = self.config["build"]["android"]
        binary_path = self.get_binary_path(release, dev, android=android)
        dir_to_root = self.get_top_dir()
        target_dir = path.dirname(binary_path)
        if android:
            if dev:
                env["NDK_DEBUG"] = "1"
                env["ANT_FLAVOR"] = "debug"
                dev_flag = "-d"
            else:
                env["ANT_FLAVOR"] = "release"
                dev_flag = ""

            output_apk = "{}.apk".format(binary_path)

            dir_to_apk = path.join(target_dir, "apk")
            if path.exists(dir_to_apk):
                print("Cleaning up from previous packaging")
                delete(dir_to_apk)
            shutil.copytree(path.join(dir_to_root, "support", "android", "apk"), dir_to_apk)

            blurdroid_path = find_dep_path_newest('blurdroid', binary_path)
            if blurdroid_path is None:
                print("Could not find blurdroid package; perhaps you haven't built Servo.")
                return 1
            else:
                dir_to_libs = path.join(dir_to_apk, "libs")
                if not path.exists(dir_to_libs):
                    os.makedirs(dir_to_libs)
                shutil.copy2(blurdroid_path + '/out/blurdroid.jar', dir_to_libs)
            try:
                with cd(path.join("support", "android", "build-apk")):
                    subprocess.check_call(["cargo", "run", "--", dev_flag, "-o", output_apk, "-t", target_dir,
                                           "-r", dir_to_root], env=env)
            except subprocess.CalledProcessError as e:
                print("Packaging Android exited with return value %d" % e.returncode)
                return e.returncode
        elif is_macosx():
            print("Creating Servo.app")
            dir_to_dmg = path.join(target_dir, 'dmg')
            dir_to_app = path.join(dir_to_dmg, 'Servo.app')
            dir_to_resources = path.join(dir_to_app, 'Contents', 'Resources')
            if path.exists(dir_to_dmg):
                print("Cleaning up from previous packaging")
                delete(dir_to_dmg)
            browserhtml_path = get_browserhtml_path(binary_path)

            print("Copying files")
            shutil.copytree(path.join(dir_to_root, 'resources'), dir_to_resources)
            shutil.copytree(browserhtml_path, path.join(dir_to_resources, 'browserhtml'))
            shutil.copy2(path.join(dir_to_root, 'Info.plist'), path.join(dir_to_app, 'Contents', 'Info.plist'))

            content_dir = path.join(dir_to_app, 'Contents', 'MacOS')
            os.makedirs(content_dir)
            shutil.copy2(binary_path, content_dir)

            change_prefs(dir_to_resources, "macosx")

            print("Finding dylibs and relinking")
            copy_dependencies(path.join(content_dir, 'servo'), content_dir)

            print("Adding version to Credits.rtf")
            version_command = [binary_path, '--version']
            p = subprocess.Popen(version_command,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE,
                                 universal_newlines=True)
            version, stderr = p.communicate()
            if p.returncode != 0:
                raise Exception("Error occurred when getting Servo version: " + stderr)
            version = "Nightly version: " + version

            template_path = path.join(dir_to_resources, 'Credits.rtf.mako')
            credits_path = path.join(dir_to_resources, 'Credits.rtf')
            with open(template_path) as template_file:
                template = mako.template.Template(template_file.read())
                with open(credits_path, "w") as credits_file:
                    credits_file.write(template.render(version=version))
            delete(template_path)

            print("Creating dmg")
            os.symlink('/Applications', path.join(dir_to_dmg, 'Applications'))
            dmg_path = path.join(target_dir, "servo-tech-demo.dmg")

            try:
                subprocess.check_call(['hdiutil', 'create', '-volname', 'Servo', dmg_path, '-srcfolder', dir_to_dmg])
            except subprocess.CalledProcessError as e:
                print("Packaging MacOS dmg exited with return value %d" % e.returncode)
                return e.returncode
            print("Cleaning up")
            delete(dir_to_dmg)
            print("Packaged Servo into " + dmg_path)

            print("Creating brew package")
            dir_to_brew = path.join(target_dir, 'brew_tmp')
            dir_to_tar = path.join(target_dir, 'brew')
            if not path.exists(dir_to_tar):
                os.makedirs(dir_to_tar)
            tar_path = path.join(dir_to_tar, "servo.tar.gz")
            if path.exists(dir_to_brew):
                print("Cleaning up from previous packaging")
                delete(dir_to_brew)
            if path.exists(tar_path):
                print("Deleting existing package")
                os.remove(tar_path)
            shutil.copytree(path.join(dir_to_root, 'resources'), path.join(dir_to_brew, 'resources'))
            os.makedirs(path.join(dir_to_brew, 'bin'))
            shutil.copy2(binary_path, path.join(dir_to_brew, 'bin', 'servo'))
            # Note that in the context of Homebrew, libexec is reserved for private use by the formula
            # and therefore is not symlinked into HOMEBREW_PREFIX.
            os.makedirs(path.join(dir_to_brew, 'libexec'))
            copy_dependencies(path.join(dir_to_brew, 'bin', 'servo'), path.join(dir_to_brew, 'libexec'))
            archive_deterministically(dir_to_brew, tar_path, prepend_path='servo/')
            delete(dir_to_brew)
            print("Packaged Servo into " + tar_path)
        elif is_windows():
            dir_to_msi = path.join(target_dir, 'msi')
            if path.exists(dir_to_msi):
                print("Cleaning up from previous packaging")
                delete(dir_to_msi)
            os.makedirs(dir_to_msi)
            browserhtml_path = get_browserhtml_path(binary_path)

            print("Copying files")
            dir_to_resources = path.join(dir_to_msi, 'resources')
            shutil.copytree(path.join(dir_to_root, 'resources'), dir_to_resources)

            change_prefs(dir_to_resources, "windows")

            # generate Servo.wxs
            template_path = path.join(dir_to_root, "support", "windows", "Servo.wxs.mako")
            template = Template(open(template_path).read())
            wxs_path = path.join(dir_to_msi, "Servo.wxs")
            open(wxs_path, "w").write(template.render(
                exe_path=target_dir,
                resources_path=dir_to_resources,
                browserhtml_path=browserhtml_path))

            # run candle and light
            print("Creating MSI")
            try:
                with cd(dir_to_msi):
                    subprocess.check_call(['candle', wxs_path])
            except subprocess.CalledProcessError as e:
                print("WiX candle exited with return value %d" % e.returncode)
                return e.returncode
            try:
                wxsobj_path = "{}.wixobj".format(path.splitext(wxs_path)[0])
                with cd(dir_to_msi):
                    subprocess.check_call(['light', wxsobj_path])
            except subprocess.CalledProcessError as e:
                print("WiX light exited with return value %d" % e.returncode)
                return e.returncode
            msi_path = path.join(dir_to_msi, "Servo.msi")
            print("Packaged Servo into {}".format(msi_path))
        else:
            dir_to_temp = path.join(target_dir, 'packaging-temp')
            browserhtml_path = get_browserhtml_path(binary_path)
            if path.exists(dir_to_temp):
                # TODO(aneeshusa): lock dir_to_temp to prevent simultaneous builds
                print("Cleaning up from previous packaging")
                delete(dir_to_temp)

            print("Copying files")
            dir_to_resources = path.join(dir_to_temp, 'resources')
            shutil.copytree(path.join(dir_to_root, 'resources'), dir_to_resources)
            shutil.copytree(browserhtml_path, path.join(dir_to_temp, 'browserhtml'))
            shutil.copy(binary_path, dir_to_temp)

            change_prefs(dir_to_resources, "linux")

            print("Creating tarball")
            tar_path = path.join(target_dir, 'servo-tech-demo.tar.gz')

            archive_deterministically(dir_to_temp, tar_path, prepend_path='servo/')

            print("Cleaning up")
            delete(dir_to_temp)
            print("Packaged Servo into " + tar_path)