#!/usr/bin/python2.7 -B # Build cross toolchain for AmigaOS 4.x / PowerPC target. from fnmatch import fnmatch from logging import info, getLogger from os import environ import argparse import logging import platform import sys URLS = \ ['https://ftp.gnu.org/gnu/gmp/gmp-5.1.3.tar.bz2', 'https://ftp.gnu.org/gnu/mpc/mpc-1.0.3.tar.gz', 'https://ftp.gnu.org/gnu/mpfr/mpfr-3.1.3.tar.bz2', 'https://ftp.gnu.org/gnu/texinfo/texinfo-4.12.tar.gz', 'http://isl.gforge.inria.fr/isl-0.12.2.tar.bz2', 'http://www.bastoul.net/cloog/pages/download/cloog-0.18.4.tar.gz', 'https://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz', ('http://hyperion-entertainment.biz/index.php/downloads' + '?view=download&format=raw&file=69', 'SDK_53.24.lha'), ('svn://svn.code.sf.net/p/adtools/code/trunk/binutils', 'binutils-2.18'), ('svn://svn.code.sf.net/p/adtools/code/trunk/gcc', 'gcc-4.2.4'), ('svn://svn.code.sf.net/p/adtools/code/branches/binutils/2.23.2', 'binutils-2.23.2'), ('svn://svn.code.sf.net/p/adtools/code/branches/gcc/4.9.x', 'gcc-4.9.1')] from common import * # NOQA def update_autotools(dst): remove(path.join(dst, 'config.guess'), path.join(dst, 'config.sub')) copy('{sources}/{automake}/lib/config.guess', path.join(dst, 'config.guess')) copy('{sources}/{automake}/lib/config.sub', path.join(dst, 'config.sub')) @recipe('{sdk}-prepare') def prepare_sdk(): info('preparing AmigaOS 4.x SDK') target = path.join('{prefix}', 'ppc-amigaos/SDK') unpack('{sdk}', work_dir='{archives}', top_dir='SDK_Install', dst_dir='SDK') unpack('SDK/base', top_dir='Include', dst_dir=path.join(target, 'include')) unpack('SDK/clib2', top_dir='clib2', dst_dir=path.join(target, 'clib2')) unpack('SDK/newlib', top_dir='newlib', dst_dir=path.join(target, 'newlib')) def download(): with cwd('{archives}'): for url in URLS: if type(url) == tuple: url, name = url[0], url[1] else: name = path.basename(url) fetch(name, url) def build(): for var in environ.keys(): if var not in ['_', 'LOGNAME', 'HOME', 'SHELL', 'TMPDIR', 'PWD']: del environ[var] PATH = ['/usr/bin', '/bin'] environ['PATH'] = ":".join(PATH) environ['LANG'] = 'C' environ['TERM'] = 'xterm' add_site_dir('{prefix}') """ Make sure we always choose known compiler (from the distro) and not one in user's path that could shadow the original one. """ if platform.system() == 'Darwin': CC, CXX = 'clang', 'clang++' else: CC, CXX = 'gcc', 'g++' CC = find_executable(CC) CXX = find_executable(CXX) FLAGS = '-g -O2' if getLogger().isEnabledFor(logging.DEBUG): FLAGS += ' -Wall' else: FLAGS += ' -w' environ['MAKEFLAGS'] = '--silent' environ['CC'] = CC environ['CXX'] = CXX environ['PATH'] = ':'.join([path.join('{prefix}', 'bin'), path.join('{host}', 'bin'), environ['PATH']]) setvar(cc=environ['CC'], cxx=environ['CXX']) """ When we have a working compiler in our path, we shoule also check if the required programs, headers and libraries are present. """ find_executable('patch') find_executable('bison') find_executable('flex') find_executable('make') find_executable('svn') py_ver = 'python%d.%d' % (sys.version_info.major, sys.version_info.minor) require_header([path.join(py_ver, 'Python.h')], lang='c', errmsg='python-dev package missing') execute('git', 'submodule', 'init', 'submodules/python-lhafile'); execute('git', 'submodule', 'update', 'submodules/python-lhafile'); unpack('python-lha', work_dir='{build}') pysetup('python-lha') download() unpack('{automake}') unpack('{texinfo}') update_autotools('{sources}/{texinfo}/build-aux') configure('{texinfo}', '--prefix={host}') make('{texinfo}', parallel=True) make('{texinfo}', 'install') unpack('{gmp}') update_autotools('{sources}/{gmp}') configure('{gmp}', '--disable-shared', '--prefix={host}') make('{gmp}', parallel=True) make('{gmp}', 'install') unpack('{mpfr}') update_autotools('{sources}/{mpfr}') configure('{mpfr}', '--disable-shared', '--prefix={host}', '--with-gmp={host}') make('{mpfr}', parallel=True) make('{mpfr}', 'install') unpack('{mpc}') update_autotools('{sources}/{mpc}') configure('{mpc}', '--disable-shared', '--prefix={host}', '--with-gmp={host}', '--with-mpfr={host}') make('{mpc}', parallel=True) make('{mpc}', 'install') unpack('{isl}') update_autotools('{sources}/{isl}') configure('{isl}', '--disable-shared', '--prefix={host}', '--with-gmp-prefix={host}') make('{isl}', parallel=True) make('{isl}', 'install') unpack('{cloog}') update_autotools('{sources}/{cloog}') configure('{cloog}', '--disable-shared', '--prefix={host}', '--with-isl=system', '--with-gmp-prefix={host}', '--with-isl-prefix={host}') make('{cloog}', parallel=True) make('{cloog}', 'install') with env(CFLAGS='-Wno-error'): update_autotools('{archives}/{binutils}') configure('{binutils}', '--prefix={prefix}', '--target={target}', from_dir='{archives}/{binutils}') make('{binutils}', parallel=True) make('{binutils}', 'install') prepare_sdk() gcc_env = {} if cmpver('eq', '{gcc_ver}', '4.2.4'): gcc_env.update(CFLAGS='-std=gnu89', CC=find_executable(CC) + ' -m32', CXX=find_executable(CXX) + ' -m32') update_autotools('{archives}/{gcc}') with env(**gcc_env): configure('{gcc}', '--prefix={prefix}', '--target={target}', '--with-bugurl="http://sf.net/p/adtools"', '--with-gmp={host}', '--with-mpfr={host}', '--with-isl={host}', '--with-cloog={host}', '--enable-languages=c,c++', '--enable-haifa', '--enable-sjlj-exceptions', '--disable-libstdcxx-pch', '--disable-tls', from_dir='{archives}/{gcc}') make('{gcc}') make('{gcc}', 'install') def clean(): rmtree('{stamps}') rmtree('{sources}') rmtree('{host}') rmtree('{build}') rmtree('{tmpdir}') if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG, format='%(levelname)s: %(message)s') if not sys.version_info[:2] == (2, 7): panic('I need Python 2.7 to run!') if not any(fnmatch(platform.system(), pat) for pat in ['Darwin', 'Linux', 'CYGWIN_NT*', 'MSYS_NT*']): panic('Build on %s not supported!', platform.system()) if platform.machine() not in ['i686', 'x86_64']: panic('Build on %s architecture not supported!', platform.machine()) parser = argparse.ArgumentParser(description='Build cross toolchain.') parser.add_argument('action', choices=['build', 'clean', 'download'], default='build', help='perform action') parser.add_argument('args', metavar='ARGS', type=str, nargs='*', help='action arguments') parser.add_argument('--binutils', choices=['2.18', '2.23.2'], default='2.18', help='desired binutils version') parser.add_argument('--gcc', choices=['4.2.4', '4.9.1'], default='4.2.4', help='desired gcc version') parser.add_argument('-q', '--quiet', action='store_true') parser.add_argument('--prefix', type=str, default=None, help='installation directory') args = parser.parse_args() setvar(top=path.abspath(path.dirname(sys.argv[0])), binutils_ver=args.binutils, gcc_ver=args.gcc, py_ver='python%d.%d' % (sys.version_info.major, sys.version_info.minor)) setvar(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', texinfo='texinfo-4.12', automake='automake-1.15', binutils='binutils-{binutils_ver}', sdk='SDK_53.24', gcc='gcc-{gcc_ver}', gpp='g++-{gcc_ver}', target='ppc-amigaos', python=sys.executable, sitedir=path.join('lib', '{py_ver}', 'site-packages'), patches=path.join('{top}', 'patches'), stamps=path.join('{top}', '.build-ppc', 'stamps'), build=path.join('{top}', '.build-ppc', 'build'), sources=path.join('{top}', '.build-ppc', 'sources'), host=path.join('{top}', '.build-ppc', 'host'), tmpdir=path.join('{top}', '.build-ppc', 'tmp'), prefix=path.join('{top}', 'ppc-amigaos'), archives=path.join('{top}', '.build-ppc', 'archives'), submodules=path.join('{top}', 'submodules')) if args.quiet: getLogger().setLevel(logging.INFO) if args.prefix is not None: setvar(prefix=args.prefix) if not path.exists('{prefix}'): mkdir('{prefix}') action = args.action.replace('-', '_') globals()[action].__call__(*args.args)