diff --git a/.gitignore b/.gitignore index 7e05e3b..5e506aa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,11 @@ *.lha *.tar.gz *.tar.bz2 +*.zip *~ *.o .DS_Store +.ropeproject archives/*/ sources/ stamps/ diff --git a/build-ppc.py b/build-ppc.py index b0c97f5..abbc6c1 100755 --- a/build-ppc.py +++ b/build-ppc.py @@ -1,23 +1,14 @@ -#!/usr/bin/env python +#!/usr/bin/env python -B # Build cross toolchain for AmigaOS 4.x / PowerPC target. -from argparse import ArgumentParser -from contextlib import contextmanager -from fnmatch import fnmatch from glob import glob -from logging import debug, info, error -from os import getcwd, environ, path -import distutils.spawn +from logging import info +from os import environ +import argparse import logging -import os -import platform import shutil -import subprocess -import sys -import tarfile -import urllib2 -import zipfile +import platform URLS = \ ['ftp://ftp.gnu.org/gnu/gmp/gmp-5.1.3.tar.bz2', @@ -36,264 +27,8 @@ URLS = \ ('http://github.com/adtools/sfdc/archive/master.zip', 'sfdc-master.zip'), ('http://clib2.cvs.sourceforge.net/viewvc/clib2/?view=tar', 'clib2.tar.gz')] -VARS = { - 'lha': 'lhasa-0.3.0', - 'gmp': 'gmp-5.1.3', - 'mpfr': 'mpfr-3.1.3', - 'mpc': 'mpc-1.0.3', - 'isl': 'isl-0.12.2', - 'cloog': 'cloog-0.18.4', - 'binutils': 'binutils-{binutils_ver}', - 'gcc': 'gcc-{gcc_ver}', - 'patches': path.join('{top}', 'patches'), - 'stamps': path.join('{top}', 'stamps'), - 'build': path.join('{top}', 'build'), - 'sources': path.join('{top}', 'sources'), - 'host': path.join('{top}', 'host'), - 'target': path.join('{top}', 'target'), - 'archives': path.join('{top}', 'archives/ppc'), -} - -def fill_in(value): - if type(value) == str: - return value.format(**VARS) - return value - - -def fill_in_args(fn): - def wrapper(*args, **kwargs): - args = list(fill_in(arg) for arg in args) - kwargs = dict((key, fill_in(value)) for key, value in kwargs.items()) - return fn(*args, **kwargs) - return wrapper - - -def flatten(*args): - queue = list(args) - - while queue: - item = queue.pop(0) - if type(item) == list: - queue = item + queue - elif type(item) == tuple: - queue = list(item) + queue - else: - yield item - - -chdir = fill_in_args(os.chdir) -path.exists = fill_in_args(path.exists) -path.join = fill_in_args(path.join) - - -@fill_in_args -def panic(*args): - error(*args) - sys.exit(1) - - -@fill_in_args -def cmpver(op, v1, v2): - assert op in ['eq', 'lt', 'gt'] - - v1 = [int(x) for x in v1.split('.')] - v2 = [int(x) for x in v2.split('.')] - - def _cmp(l1, l2): - if not len(l1) and not len(l2): - return 0 - if not len(l1): - return -1 - if not len(l2): - return 1 - - if l1[0] < l2[0]: - return -1 - if l1[0] > l2[0]: - return 1 - if l1[0] == l2[0]: - return _cmp(l1[1:], l2[1:]) - - res = _cmp(v1, v2) - - return ((op == 'eq' and res == 0) or - (op == 'lt' and res < 0) or - (op == 'gt' and res > 0)) - - -@fill_in_args -def relpath(name): - if not path.isabs(name): - name = path.abspath(name) - return path.relpath(name, fill_in('{top}')) - - -@fill_in_args -def find_executable(name): - return (distutils.spawn.find_executable(name) or - panic('Executable "%s" not found!', name)) - - -@fill_in_args -def find_files(pattern): - found = [] - for root, dirs, files in os.walk('.', topdown=True): - for name in files: - if fnmatch(name, pattern): - found.append(path.join(root, name)) - return found - - -@fill_in_args -def touch(name): - try: - os.utime(name, None) - except: - open(name, 'a').close() - - -@fill_in_args -def rmtree(*names): - for name in flatten(names): - if path.isdir(name): - debug('rmtree "%s"', relpath(name)) - shutil.rmtree(name) - - -@fill_in_args -def remove(*names): - for name in flatten(names): - if path.isfile(name): - debug('remove "%s"', relpath(name)) - os.remove(name) - - -@fill_in_args -def mkdir(*names): - for name in flatten(names): - debug('makedir "%s"', relpath(name)) - os.makedirs(name) - - -@fill_in_args -def copytree(src, dst, **kwargs): - debug('copytree "%s" to "%s"', relpath(src), relpath(dst)) - shutil.copytree(src, dst, **kwargs) - - -@fill_in_args -def rename(src, dst): - debug('rename "%s" to "%s"', relpath(src), relpath(dst)) - os.rename(src, dst) - - -@fill_in_args -def symlink(src, name): - debug('symlink "%s" from "%s"', src, relpath(name)) - os.symlink(src, name) - - -@fill_in_args -def execute(*cmd): - debug('execute "%s"', " ".join(cmd)) - try: - subprocess.check_call(cmd) - except subprocess.CalledProcessError as ex: - panic('command "%s" failed with %d', " ".join(list(ex.cmd)), ex.returncode) - - -@fill_in_args -def download(url, name): - u = urllib2.urlopen(url) - meta = u.info() - size = int(meta.getheaders('Content-Length')[0]) - info('download: %s (size: %d)' % (name, size)) - - with open(name, 'wb') as f: - done = 0 - block = 8192 - while True: - buf = u.read(block) - if not buf: - break - done += len(buf) - f.write(buf) - status = r"%10d [%3.2f%%]" % (done, done * 100. / size) - status = status + chr(8) * (len(status) + 1) - print status, - - print "" - - -@fill_in_args -def unarc(name): - info('extract files from "%s"' % relpath(name)) - - if name.endswith('.lha'): - execute('lha', '-xq', name) - else: - if name.endswith('.tar.gz') or name.endswith('.tar.bz2'): - module = tarfile - elif name.endswith('.zip'): - module = zipfile - else: - raise RuntimeError('Unrecognized archive: "%s"', name) - - arc = module.open(name, 'r') - for item in arc: - debug('extract "%s"' % item.name) - arc.extract(item) - arc.close() - - -@contextmanager -def cwd(name): - old = getcwd() - if not path.exists(name): - mkdir(name) - try: - debug('enter directory "%s"', relpath(name)) - chdir(name) - yield - finally: - chdir(old) - - -@contextmanager -def env(**kwargs): - backup = {} - try: - for key, value in kwargs.items(): - debug('changing environment variable "%s" to "%s"', key, value) - old = environ.get(key, None) - environ[key] = fill_in(value) - backup[key] = old - yield - finally: - for key, value in backup.items(): - debug('restoring old value of environment variable "%s"', key) - if value is None: - del environ[key] - else: - environ[key] = value - - -def check_stamp(fn): - def wrapper(*args, **kwargs): - name = fn.func_name.replace('_', '-') - if len(args) > 0: - name = name + "-" + str(args[0]) - stamp = path.join('{stamps}', name) - if not path.exists('{stamps}'): - mkdir('{stamps}') - if not path.exists(stamp): - fn(*args, **kwargs) - touch(stamp) - else: - info('already done "%s"', name) - - return wrapper +from common import * # NOQA @check_stamp @@ -524,7 +259,7 @@ def clean(): if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG, format='%(levelname)s: %(message)s') - parser = ArgumentParser(description='Build cross toolchain.') + parser = argparse.ArgumentParser(description='Build cross toolchain.') parser.add_argument('action', choices=['doit', 'clean'], default='doit', help='perform action') parser.add_argument('--binutils', choices=['2.18', '2.23.2'], default='2.18', @@ -547,12 +282,27 @@ if __name__ == "__main__": 'gcc_ver': args.gcc }) + VARS.update({ + 'lha': 'lhasa-0.3.0', + 'gmp': 'gmp-5.1.3', + 'mpfr': 'mpfr-3.1.3', + 'mpc': 'mpc-1.0.3', + 'isl': 'isl-0.12.2', + 'cloog': 'cloog-0.18.4', + 'binutils': 'binutils-{binutils_ver}', + 'gcc': 'gcc-{gcc_ver}', + 'patches': path.join('{top}', 'patches'), + 'stamps': path.join('{top}', 'stamps'), + 'build': path.join('{top}', 'build'), + 'sources': path.join('{top}', 'sources'), + 'host': path.join('{top}', 'host'), + 'target': path.join('{top}', 'target'), + 'archives': path.join('{top}', 'archives', 'ppc'), + }) + if args.prefix is not None: VARS['target'] = args.prefix - for key, value in VARS.items(): - VARS[key] = fill_in(value) - if not path.exists('{target}'): mkdir('{target}') diff --git a/common.py b/common.py new file mode 100644 index 0000000..bfd3e7b --- /dev/null +++ b/common.py @@ -0,0 +1,266 @@ +#!/usr/bin/env python -B + +from logging import debug, info, error +from os import path +from fnmatch import fnmatch +import contextlib +import distutils.spawn +import shutil +import os +import subprocess +import sys +import tarfile +import urllib2 +import zipfile + + +VARS = {} + + +def fill_in(value): + global VARS + + if type(value) == str: + return value.format(**VARS) + return value + + +def fill_in_args(fn): + def wrapper(*args, **kwargs): + args = list(fill_in(arg) for arg in args) + kwargs = dict((key, fill_in(value)) for key, value in kwargs.items()) + return fn(*args, **kwargs) + return wrapper + + +def flatten(*args): + queue = list(args) + + while queue: + item = queue.pop(0) + if type(item) == list: + queue = item + queue + elif type(item) == tuple: + queue = list(item) + queue + else: + yield item + + +chdir = fill_in_args(os.chdir) +path.exists = fill_in_args(path.exists) +path.join = fill_in_args(path.join) + + +@fill_in_args +def panic(*args): + error(*args) + sys.exit(1) + + +@fill_in_args +def cmpver(op, v1, v2): + assert op in ['eq', 'lt', 'gt'] + + v1 = [int(x) for x in v1.split('.')] + v2 = [int(x) for x in v2.split('.')] + + def _cmp(l1, l2): + if not len(l1) and not len(l2): + return 0 + if not len(l1): + return -1 + if not len(l2): + return 1 + + if l1[0] < l2[0]: + return -1 + if l1[0] > l2[0]: + return 1 + if l1[0] == l2[0]: + return _cmp(l1[1:], l2[1:]) + + res = _cmp(v1, v2) + + return ((op == 'eq' and res == 0) or + (op == 'lt' and res < 0) or + (op == 'gt' and res > 0)) + + +@fill_in_args +def relpath(name): + if not path.isabs(name): + name = path.abspath(name) + return path.relpath(name, fill_in('{top}')) + + +@fill_in_args +def find_executable(name): + return (distutils.spawn.find_executable(name) or + panic('Executable "%s" not found!', name)) + + +@fill_in_args +def find_files(pattern): + found = [] + for root, dirs, files in os.walk('.', topdown=True): + for name in files: + if fnmatch(name, pattern): + found.append(path.join(root, name)) + return found + + +@fill_in_args +def touch(name): + try: + os.utime(name, None) + except: + open(name, 'a').close() + + +@fill_in_args +def rmtree(*names): + for name in flatten(names): + if path.isdir(name): + debug('rmtree "%s"', relpath(name)) + shutil.rmtree(name) + + +@fill_in_args +def remove(*names): + for name in flatten(names): + if path.isfile(name): + debug('remove "%s"', relpath(name)) + os.remove(name) + + +@fill_in_args +def mkdir(*names): + for name in flatten(names): + debug('makedir "%s"', relpath(name)) + os.makedirs(name) + + +@fill_in_args +def copytree(src, dst, **kwargs): + debug('copytree "%s" to "%s"', relpath(src), relpath(dst)) + shutil.copytree(src, dst, **kwargs) + + +@fill_in_args +def rename(src, dst): + debug('rename "%s" to "%s"', relpath(src), relpath(dst)) + os.rename(src, dst) + + +@fill_in_args +def symlink(src, name): + debug('symlink "%s" from "%s"', src, relpath(name)) + os.symlink(src, name) + + +@fill_in_args +def execute(*cmd): + debug('execute "%s"', " ".join(cmd)) + try: + subprocess.check_call(cmd) + except subprocess.CalledProcessError as ex: + panic('command "%s" failed with %d', " ".join(list(ex.cmd)), ex.returncode) + + +@fill_in_args +def download(url, name): + u = urllib2.urlopen(url) + meta = u.info() + size = int(meta.getheaders('Content-Length')[0]) + info('download: %s (size: %d)' % (name, size)) + + with open(name, 'wb') as f: + done = 0 + block = 8192 + while True: + buf = u.read(block) + if not buf: + break + done += len(buf) + f.write(buf) + status = r"%10d [%3.2f%%]" % (done, done * 100. / size) + status = status + chr(8) * (len(status) + 1) + print status, + + print "" + + +@fill_in_args +def unarc(name): + info('extract files from "%s"' % relpath(name)) + + if name.endswith('.lha'): + execute('lha', '-xq', name) + else: + if name.endswith('.tar.gz') or name.endswith('.tar.bz2'): + module = tarfile + elif name.endswith('.zip'): + module = zipfile + else: + raise RuntimeError('Unrecognized archive: "%s"', name) + + arc = module.open(name, 'r') + for item in arc: + debug('extract "%s"' % item.name) + arc.extract(item) + arc.close() + + +@contextlib.contextmanager +def cwd(name): + old = os.getcwd() + if not path.exists(name): + mkdir(name) + try: + debug('enter directory "%s"', relpath(name)) + chdir(name) + yield + finally: + chdir(old) + + +@contextlib.contextmanager +def env(**kwargs): + backup = {} + try: + for key, value in kwargs.items(): + debug('changing environment variable "%s" to "%s"', key, value) + old = os.environ.get(key, None) + os.environ[key] = fill_in(value) + backup[key] = old + yield + finally: + for key, value in backup.items(): + debug('restoring old value of environment variable "%s"', key) + if value is None: + del os.environ[key] + else: + os.environ[key] = value + + +def check_stamp(fn): + @fill_in_args + def wrapper(*args, **kwargs): + name = fn.func_name.replace('_', '-') + if len(args) > 0: + name = name + "-" + str(args[0]) + stamp = path.join('{stamps}', name) + if not path.exists('{stamps}'): + mkdir('{stamps}') + if not path.exists(stamp): + fn(*args, **kwargs) + touch(stamp) + else: + info('already done "%s"', name) + + return wrapper + + +__all__ = ['VARS', 'panic', 'cmpver', 'find_executable', 'execute', + 'rmtree', 'mkdir', 'copytree', 'touch', 'unarc', 'download', 'cwd', + 'remove', 'rename', 'find_files', 'env', 'path', 'check_stamp']