gecko-dev/testing/docker/rust-build/repack_rust.py
Ralph Giles c3d36f874d Bug 1289605 - Update gecko-rust-build to v0.3.0. r=dustin
- Separate build, package, and upload steps into separate scripts.
- Rewrite repack in python to use rust's internal install scripts.
- Add support for cargo as well as the rust compiler and std library.

MozReview-Commit-ID: EI9M8ayEptA

--HG--
extra : rebase_source : 4457c074396e5c733158d304c2aebe0f811a9d7e
2016-07-26 14:49:09 -07:00

177 lines
5.8 KiB
Python

#!/bin/env python
'''
This script downloads and repacks official rust language builds
with the necessary tool and target support for the Firefox
build environment.
'''
import os.path
import requests
import subprocess
import toml
def fetch_file(url):
'''Download a file from the given url if it's not already present.'''
filename = os.path.basename(url)
if os.path.exists(filename):
return
r = requests.get(url, stream=True)
r.raise_for_status()
with open(filename, 'wb') as fd:
for chunk in r.iter_content(4096):
fd.write(chunk)
def fetch(url):
'''Download and verify a package url.'''
base = os.path.basename(url)
print('Fetching %s...' % base)
fetch_file(url + '.asc')
fetch_file(url)
fetch_file(url + '.sha256')
fetch_file(url + '.asc.sha256')
print('Verifying %s...' % base)
subprocess.check_call(['shasum', '-c', base + '.sha256'])
subprocess.check_call(['shasum', '-c', base + '.asc.sha256'])
subprocess.check_call(['gpg', '--verify', base + '.asc', base])
subprocess.check_call(['keybase', 'pgp', 'verify',
'-d', base + '.asc',
'-i', base,
])
def install(filename, target):
'''Run a package's installer script against the given target directory.'''
print(' Unpacking %s...' % filename)
subprocess.check_call(['tar', 'xf', filename])
basename = filename.split('.tar')[0]
print(' Installing %s...' % basename)
install_cmd = [os.path.join(basename, 'install.sh')]
install_cmd += ['--prefix=' + os.path.abspath(target)]
install_cmd += ['--disable-ldconfig']
subprocess.check_call(install_cmd)
print(' Cleaning %s...' % basename)
subprocess.check_call(['rm', '-rf', basename])
def package(manifest, pkg, target):
'''Pull out the package dict for a particular package and target
from the given manifest.'''
version = manifest['pkg'][pkg]['version']
info = manifest['pkg'][pkg]['target'][target]
return (version, info)
def fetch_package(manifest, pkg, host):
version, info = package(manifest, pkg, host)
print('%s %s\n %s\n %s' % (pkg, version, info['url'], info['hash']))
if not info['available']:
print('%s marked unavailable for %s' % (pkg, host))
raise AssertionError
fetch(info['url'])
return info
def fetch_std(manifest, targets):
stds = []
for target in targets:
info = fetch_package(manifest, 'rust-std', target)
stds.append(info)
return stds
def tar_for_host(host):
if 'linux' in host:
tar_options = 'cJf'
tar_ext = '.tar.xz'
else:
tar_options = 'cjf'
tar_ext = '.tar.bz2'
return tar_options, tar_ext
def repack(host, targets, channel='stable', suffix=''):
print("Repacking rust for %s..." % host)
url = 'https://static.rust-lang.org/dist/channel-rust-' + channel + '.toml'
req = requests.get(url)
req.raise_for_status()
manifest = toml.loads(req.content)
if manifest['manifest-version'] != '2':
print('ERROR: unrecognized manifest version %s.' % manifest['manifest-version'])
return
print('Using manifest for rust %s as of %s.' % (channel, manifest['date']))
print('Fetching packages...')
rustc = fetch_package(manifest, 'rustc', host)
cargo = fetch_package(manifest, 'cargo', host)
stds = fetch_std(manifest, targets)
print('Installing packages...')
tar_basename = 'rustc-' + host
if suffix:
tar_basename += '-' + suffix
tar_basename += '-repack'
install_dir = 'rustc'
subprocess.check_call(['rm', '-rf', install_dir])
install(os.path.basename(rustc['url']), install_dir)
install(os.path.basename(cargo['url']), install_dir)
for std in stds:
install(os.path.basename(std['url']), install_dir)
pass
print('Tarring %s...' % tar_basename)
tar_options, tar_ext = tar_for_host(host)
subprocess.check_call(['tar', tar_options, tar_basename + tar_ext, install_dir])
subprocess.check_call(['rm', '-rf', install_dir])
def repack_cargo(host, channel='nightly'):
print("Repacking cargo for %s..." % host)
# Cargo doesn't seem to have a .toml manifest.
base_url = 'https://static.rust-lang.org/cargo-dist/'
req = requests.get(os.path.join(base_url, 'channel-cargo-' + channel))
req.raise_for_status()
file = ''
for line in req.iter_lines():
if line.find(host) != -1:
file = line.strip()
if not file:
print('No manifest entry for %s!' % host)
return
manifest = {
'date': req.headers['Last-Modified'],
'pkg': {
'cargo': {
'version': channel,
'target': {
host: {
'url': os.path.join(base_url, file),
'hash': None,
'available': True,
},
},
},
},
}
print('Using manifest for cargo %s.' % channel)
print('Fetching packages...')
cargo = fetch_package(manifest, 'cargo', host)
print('Installing packages...')
install_dir = 'cargo'
subprocess.check_call(['rm', '-rf', install_dir])
install(os.path.basename(cargo['url']), install_dir)
tar_basename = 'cargo-%s-repack' % host
print('Tarring %s...' % tar_basename)
tar_options, tar_ext = tar_for_host(host)
subprocess.check_call(['tar', tar_options, tar_basename + tar_ext, install_dir])
subprocess.check_call(['rm', '-rf', install_dir])
# rust platform triples
android="armv7-linux-androideabi"
linux64="x86_64-unknown-linux-gnu"
linux32="i686-unknown-linux-gnu"
mac64="x86_64-apple-darwin"
mac32="i686-apple-darwin"
win64="x86_64-pc-windows-msvc"
win32="i686-pc-windows-msvc"
if __name__ == '__main__':
repack(mac64, [mac64, mac32])
repack(win32, [win32])
repack(win64, [win64])
repack(linux64, [linux64, linux32])
repack(linux64, [linux64, mac64, mac32], suffix='mac-cross')
repack(linux64, [linux64, android], suffix='android-cross')
repack_cargo(mac64)
repack_cargo(win32)
repack_cargo(win64)
repack_cargo(linux64)