Skip to content
Snippets Groups Projects
build_tor_macos.py 5.06 KiB
Newer Older
#!/usr/bin/env python3
import os
from shutil import copytree, rmtree
from subprocess import check_call
import hashlib

import utils
akwizgran's avatar
akwizgran committed
from utils import get_version, get_build_versions, reset_time, create_sources_jar, \
    get_sources_file_name, get_output_dir, get_sha256, pack, create_pom_file
from pathlib import Path
import tarfile

PLATFORM = "macos"
BUILD_DIR = "tor-browser-build"


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

    # get versions of upstream repository and Tor browser for comparison
    versions = get_build_versions(version)
    print("Building Tor from upstream repository at commit %s" % versions['upstream']['commit'])

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

    # clone tor-browser-build repo
    check_call(['git', 'clone', versions['upstream']['url'], BUILD_DIR])
    check_call(['git', 'checkout', versions['upstream']['commit']], cwd=Path(BUILD_DIR))
    check_call(['git', 'submodule', 'init'], cwd=Path(BUILD_DIR))
    check_call(['git', 'submodule', 'update'], cwd=Path(BUILD_DIR))

    # create sources jar before building
    jar_name = create_sources_jar(versions, PLATFORM, BUILD_DIR)

    return versions, jar_name


def build():
    versions, jar_name = setup()

    copytree('pre-out', os.path.join(BUILD_DIR, 'out'))
    copytree('pre-clones', os.path.join(BUILD_DIR, 'git_clones'))

    build_arch(versions, 'aarch64')
    build_arch(versions, 'x86_64')

    package_macos(versions, jar_name)
    return versions


def build_arch(versions, arch):
    target = PLATFORM + '-' + arch
    libevent_version = versions['upstream']['libevent']
    # build using rbm
    check_call(['./rbm/rbm', 'build', 'tor', '--target', 'release', '--target', 'torbrowser-' + target], cwd=Path(BUILD_DIR))
    # extract tar.gz file
    arch_dir = Path('output') / PLATFORM / arch
    arch_dir.mkdir(parents=True, exist_ok=True)
    tar_file = next(Path(BUILD_DIR).glob('out/tor/tor-*-' + target + '-*.tar.gz'))
    tar = tarfile.open(tar_file, "r:gz")
    tar.extractall(path=arch_dir)
    tar.close()
    # move contents out of tor/ directory
    (arch_dir / 'tor').rename(arch_dir / 'tordir')
    for file in (arch_dir / 'tordir').glob('*'):
        file.rename(arch_dir / file.name)
    (arch_dir / 'tordir').rmdir
    rmtree(arch_dir / 'data')
    # print hashsums
    tor_file = arch_dir / 'tor'
    libevent_file = arch_dir / ('libevent-' + libevent_version + '.dylib')
    for file in [tor_file, libevent_file]:
        sha256hash = get_sha256(file)
        print("%s: %s" % (file, sha256hash))


def package_macos(versions, jar_name):
    libevent_version = versions['upstream']['libevent']
    # 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-' + libevent_version + '.dylib'),
        os.path.join(output_dir, 'x86_64', 'tor'),
        os.path.join(output_dir, 'x86_64', 'libevent-' + libevent_version + '.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 compare_output_with_upstream(versions):
    compare_with_upstream(versions, "aarch64")
    compare_with_upstream(versions, "x86_64")


def compare_with_upstream(versions, arch):
    print('comparing hashsums for {0}'.format(arch))
    tor_browser_version = versions['upstream']['tor-browser']
    libevent_version = versions['upstream']['libevent']
    check_call(['wget', '-c', ('https://archive.torproject.org/tor-package-archive/torbrowser/{0}/'
                + 'tor-expert-bundle-{0}-macos-{1}.tar.gz').format(tor_browser_version, arch)])
    check_call(['tar', 'xvfz', 'tor-expert-bundle-{0}-macos-{1}.tar.gz'.format(tor_browser_version, arch),
                '--one-top-level=upstream-' + arch, '--strip-components=1',
                'tor/tor', 'tor/libevent-' + libevent_version + '.dylib'])
    hash_tor_upstream = get_sha256(os.path.join('upstream-' + arch, 'tor'))
    hash_libevent_upstream = get_sha256(os.path.join('upstream-' + arch, 'libevent-' + libevent_version + '.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-' + libevent_version + '.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)

if __name__ == "__main__":
    versions = build()
    compare_output_with_upstream(versions)