Skip to content
Snippets Groups Projects
build_tor_macos.py 4.3 KiB
Newer Older
Sebastian's avatar
Sebastian committed
#!/usr/bin/env python3
import os
from shutil import copytree
Sebastian's avatar
Sebastian committed
from subprocess import check_call
import hashlib
Sebastian's avatar
Sebastian committed

import utils
from utils import get_version, get_build_versions, reset_time, \
    get_sources_file_name, get_output_dir, get_sha256, pack, create_pom_file

PLATFORM = "macos"
BUILD_DIR = "tor-browser-build"
UPSTREAM_VERSION = "12.0.6"
Sebastian's avatar
Sebastian committed


def setup(platform):
    # get Tor version from command or show usage information
    version = get_version()

    # get Tor version and versions of its dependencies
    versions = get_build_versions(version)
    print("Building Tor %s" % versions['tor']['commit'])

    # remove output from previous build
    output_dir = get_output_dir(platform)
    print(output_dir)
    os.makedirs(output_dir, exist_ok=True)

    # prepare using shell scripts
    check_call(['./prepare_docker_in_docker.sh'])
    check_call(['./prepare_tor_macos.sh'])
Sebastian's avatar
Sebastian committed
    # create sources jar before building
    jar_name = create_sources_jar(versions, platform)

    return versions, jar_name


Sebastian's avatar
Sebastian committed
    versions, jar_name = setup(PLATFORM)

    copytree('pre-out', os.path.join(BUILD_DIR, 'out'))
    copytree('pre-clones', os.path.join(BUILD_DIR, 'git_clones'))
Sebastian's avatar
Sebastian committed

    # build using shell script
    check_call(['./build_tor_macos.sh'])

    package_macos(versions, jar_name)

Sebastian's avatar
Sebastian committed
def package_macos(versions, jar_name):
    # zip binaries together
    output_dir = get_output_dir(PLATFORM)
    file_list = [
        os.path.join(output_dir, 'aarch64', 'tor'),
        os.path.join(output_dir, 'aarch64', 'libevent-2.1.7.dylib'),
        os.path.join(output_dir, 'x86_64', 'tor'),
        os.path.join(output_dir, 'x86_64', 'libevent-2.1.7.dylib'),
    ]
    zip_name = pack(versions, file_list, PLATFORM)
    pom_name = create_pom_file(versions, PLATFORM)
    print("%s:" % PLATFORM)
    for file in file_list + [zip_name, jar_name, pom_name]:
        sha256hash = get_sha256(file)
        print("%s: %s" % (file, sha256hash))


def create_sources_jar(versions, platform):
    output_dir = get_output_dir(platform)
    jar_files = []
    for root, dir_names, filenames in os.walk(BUILD_DIR):
        for f in filenames:
            if '/.git' in root:
                continue
            if '/rbm/.git' in root:
                continue
Sebastian's avatar
Sebastian committed
            jar_files.append(os.path.join(root, f))
    for file in jar_files:
        reset_time(file, versions)
    jar_name = get_sources_file_name(versions, platform)
    jar_path = os.path.abspath(jar_name)
    rel_paths = [os.path.relpath(f, BUILD_DIR) for f in sorted(jar_files)]
    # create jar archive with first files
    jar_step = 5000
    check_call(['jar', 'cf', jar_path] + rel_paths[0:jar_step], cwd=BUILD_DIR)
    # add subsequent files in steps, because the command line can't handle all at once
    for i in range(jar_step, len(rel_paths), jar_step):
        check_call(['jar', 'uf', jar_path] + rel_paths[i:i + jar_step], cwd=BUILD_DIR)
    return jar_name


def compare_output_with_upstream():
    compare_with_upstream("aarch64")
    compare_with_upstream("x86_64")


def compare_with_upstream(arch):
    check_call(['wget', '-c', ('https://archive.torproject.org/tor-package-archive/torbrowser/{0}/'
                + 'tor-expert-bundle-{0}-macos-{1}.tar.gz').format(UPSTREAM_VERSION, arch)])
    check_call(['tar', 'xvfz', 'tor-expert-bundle-{0}-macos-{1}.tar.gz'.format(UPSTREAM_VERSION, arch),
                '--one-top-level=upstream-' + arch, '--strip-components=1',
                'tor/tor', 'tor/libevent-2.1.7.dylib'])
    hash_tor_upstream = get_sha256(os.path.join('upstream-' + arch, 'tor'))
    hash_libevent_upstream = get_sha256(os.path.join('upstream-' + arch, 'libevent-2.1.7.dylib'))
    print('upstream tor: {0}'.format(hash_tor_upstream))
    print('upstream libevent: {0}'.format(hash_libevent_upstream))

    hash_tor_built = get_sha256(os.path.join('output', 'macos', arch, 'tor'))
    hash_libevent_built = get_sha256(os.path.join('output', 'macos', arch, 'libevent-2.1.7.dylib'))
    print('built tor: {0}'.format(hash_tor_built))
    print('built libevent: {0}'.format(hash_libevent_built))

    if hash_tor_upstream != hash_tor_built:
        print("tor hash does not match")
        exit(1)

    if hash_libevent_upstream != hash_libevent_built:
        print("libevent hash does not match")
        exit(1)

Sebastian's avatar
Sebastian committed
if __name__ == "__main__":
    compare_output_with_upstream()