#!/usr/bin/python -B

# Build development cross toolchain for m68k-elf target.

from fnmatch import fnmatch
from os import environ
import argparse
import logging
import platform

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',
   'http://isl.gforge.inria.fr/isl-0.12.2.tar.bz2',
   'http://www.bastoul.net/cloog/pages/download/cloog-0.18.4.tar.gz',
   'git://sourceware.org/git/binutils',
   'git://gcc.gnu.org/git/gcc']


from common import * # NOQA


def build():
  for var in environ.keys():
    if var not in ['_', 'LOGNAME', 'HOME', 'SHELL', 'TMPDIR', 'PWD']:
      del environ[var]

  environ['PATH'] = '/usr/bin:/bin'
  environ['LANG'] = 'C'
  environ['TERM'] = 'xterm'

  if platform.system() == 'Darwin':
    cc, cxx = 'clang', 'clang++'
  else:
    cc, cxx = 'gcc', 'g++'

  environ['CC'] = find_executable(cc)
  environ['CXX'] = find_executable(cxx)

  find_executable('bison')
  find_executable('flex')
  find_executable('make')
  find_executable('git')

  environ['PATH'] = ":".join([path.join('{target}', 'bin'),
                              path.join('{host}', 'bin'),
                              environ['PATH']])

  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)

  unpack('{gmp}')
  configure('{gmp}',
            '--disable-shared',
            '--prefix={host}')
  make('{gmp}')
  make('{gmp}', 'install')

  unpack('{mpfr}')
  configure('{mpfr}',
            '--disable-shared',
            '--prefix={host}',
            '--with-gmp={host}')
  make('{mpfr}')
  make('{mpfr}', 'install')

  unpack('{mpc}')
  configure('{mpc}',
            '--disable-shared',
            '--prefix={host}',
            '--with-gmp={host}',
            '--with-mpfr={host}')
  make('{mpc}')
  make('{mpc}', 'install')

  unpack('{isl}')
  configure('{isl}',
            '--disable-shared',
            '--prefix={host}',
            '--with-gmp-prefix={host}')
  make('{isl}')
  make('{isl}', 'install')

  unpack('{cloog}')
  configure('{cloog}',
            '--disable-shared',
            '--prefix={host}',
            '--with-isl=system',
            '--with-gmp-prefix={host}',
            '--with-isl-prefix={host}')
  make('{cloog}')
  make('{cloog}', 'install')

  with env(CFLAGS='-Wno-error'):
    configure('binutils',
              '--prefix={target}',
              '--with-isl={host}',
              '--target=m68k-elf',
              from_dir='{archives}/binutils')
    make('binutils')
    make('binutils', 'install')

    configure('gcc',
              '--target=m68k-elf',
              '--with-gmp={host}',
              '--with-mpfr={host}',
              '--with-isl={host}',
              '--with-cloog={host}',
              '--prefix={target}',
              '--enable-languages=c',
              '--without-headers',
              from_dir='{archives}/gcc')
    make('gcc', 'all-gcc')
    make('gcc', 'install-gcc')


def clean():
  rmtree('{stamps}')
  rmtree('{host}')
  rmtree('{build}')


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 (platform.system() in ['Darwin', 'Linux'] or
          fnmatch(platform.system(), 'CYGWIN*')):
    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'], default='build',
                      help='perform action')
  parser.add_argument('--prefix', type=str, default=None,
                      help='installation directory')
  args = parser.parse_args()

  setvar(top=path.abspath('.'))

  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',
         patches=path.join('{top}', 'patches'),
         stamps=path.join('{top}', '.build-dev', 'stamps'),
         build=path.join('{top}', '.build-dev', 'build'),
         sources=path.join('{top}', '.build-dev', 'sources'),
         host=path.join('{top}', '.build-dev', 'host'),
         tmpdir=path.join('{top}', '.build-dev', 'tmp'),
         target=path.join('{top}', 'm68k-elf'),
         archives=path.join('{top}', '.build-dev', 'archives'))

  if args.prefix is not None:
    setvar(target=args.prefix)

  if not path.exists('{target}'):
    mkdir('{target}')

  eval(args.action + "()")
