amigaos-cross-toolchain6/toolchain-m68k

435 lines
13 KiB
Python
Executable File

#!/usr/bin/python -B
# Build cross toolchain for AmigaOS <= 3.9 / M68k target.
from fnmatch import fnmatch
from logging import info
from os import environ
import argparse
import logging
import platform
import sys
URLS = \
['http://soulsphere.org/projects/lhasa/lhasa-0.3.0.tar.gz',
'ftp://ftp.gnu.org/gnu/m4/m4-1.4.17.tar.gz',
'ftp://ftp.gnu.org/gnu/gawk/gawk-3.1.8.tar.gz',
'ftp://ftp.gnu.org/gnu/autoconf/autoconf-2.13.tar.gz',
'ftp://ftp.gnu.org/gnu/bison/bison-1.35.tar.gz',
'ftp://ftp.gnu.org/gnu/texinfo/texinfo-4.12.tar.gz',
'ftp://ftp.gnu.org/gnu/binutils/binutils-2.9.1.tar.gz',
'ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3/gcc-core-2.95.3.tar.gz',
'ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3/gcc-g++-2.95.3.tar.gz',
('http://fossies.org/linux/misc/old/flex-2.5.4a.tar.gz',
'flex-2.5.4.tar.gz'),
'git://github.com/cahirwpz/libnix',
'git://github.com/cahirwpz/fd2sfd',
'git://github.com/adtools/sfdc',
('http://www.haage-partner.de/download/AmigaOS/NDK39.lha', 'NDK_3.9.lha'),
('ftp://ftp.exotica.org.uk/mirrors/geekgadgets/amiga/m68k/snapshots/' +
'990529/bin/libamiga-bin.tgz', 'libamiga.tar.gz'),
('ftp://ftp.exotica.org.uk/mirrors/geekgadgets/amiga/m68k/snapshots/' +
'990529/src/libm-5.4-src.tgz', 'libm-5.4.tar.gz'),
('http://sourceforge.net/projects/amiga/files/ixemul.library/48.2/' +
'ixemul-src.lha/download', 'ixemul-48.2.lha'),
'http://sun.hasenbraten.de/vasm/release/vasm.tar.gz',
'http://sun.hasenbraten.de/vlink/release/vlink.tar.gz',
'http://www.ibaug.de/vbcc/vbcc.tar.gz',
('http://mail.pb-owl.de/~frank/vbcc/current/vbcc_target_m68k-amigaos.lha',
'vclib.lha')]
from common import * # NOQA
@recipe('target-prepare')
def prepare_target():
info('preparing target')
with cwd('{target}'):
mkdir('bin', 'doc', 'etc', 'lib', 'm68k-amigaos', 'os-include',
'os-include/lvo', 'os-lib', 'os-lib/fd', 'os-lib/sfd',
'vbcc-include', 'vbcc-lib')
with cwd('{target}/m68k-amigaos'):
symlink('../os-include', 'include')
symlink('../lib', 'lib')
@recipe('{NDK}-install')
def install_ndk():
info('installing ndk')
copytree('{sources}/{NDK}/Include/include_h', '{target}/os-include')
copytree('{sources}/{NDK}/Include/include_i', '{target}/os-include')
copytree('{sources}/{NDK}/Include/fd', '{target}/os-lib/fd')
copytree('{sources}/{NDK}/Include/sfd', '{target}/os-lib/sfd')
copytree('{sources}/{NDK}/Include/linker_libs', '{target}/os-lib',
exclude=['README'])
copytree('{sources}/{NDK}/Documentation/Autodocs', '{target}/doc')
for name in find('{target}/os-lib/sfd', include=['*.sfd']):
base = path.basename(name).split('_')[0]
execute('sfdc', '--target=m68k-amigaos', '--mode=proto',
'--output={target}/os-include/proto/' + base + '.h', name)
execute('sfdc', '--target=m68k-amigaos', '--mode=macros',
'--output={target}/os-include/inline/' + base + '.h', name)
execute('sfdc', '--target=m68k-amigaos', '--mode=lvo',
'--output={target}/os-include/lvo/' + base + '_lib.i', name)
@recipe('libamiga-install')
def install_libamiga():
info('installing libamiga')
copytree('{sources}/libamiga/lib', '{target}/lib')
@recipe('vbcc-build')
def build_vbcc():
copytree('{sources}/vbcc', '{build}/vbcc')
mkdir('{build}/vbcc/bin')
config = textfile(
'y', 'y', 'signed char',
'y', 'unsigned char',
'n', 'y', 'signed short',
'n', 'y', 'unsigned short',
'n', 'y', 'signed int',
'n', 'y', 'unsigned int',
'n', 'y', 'signed long',
'n', 'y', 'unsigned long',
'n', 'y', 'float',
'n', 'y', 'double')
make('vbcc', TARGET='m68k', ETCDIR='\\"{target}/etc\\"', CONFIG=config)
remove(config)
@recipe('vlink-build')
def build_vlink():
mkdir('{build}/vlink/objects')
make('vlink')
@recipe('vbcc-install')
def install_vbcc_toolchain():
info('installing vasm')
copy('{build}/vasm/vasmm68k_mot', '{target}/bin')
copy('{build}/vasm/vobjdump', '{target}/bin')
vasm = textfile(
'#!/bin/sh',
'',
'vasmm68k_mot -I{target}/os-include "$@"')
chmod(vasm, 0755)
move(vasm, '{target}/bin/vasm')
info('installing vlink')
copy('{build}/vlink/vlink', '{target}/bin')
info('installing vbcc')
copy('{build}/vbcc/bin/vbccm68k', '{target}/bin')
copy('{build}/vbcc/bin/vc', '{target}/bin')
copy('{build}/vbcc/bin/vprof', '{target}/bin')
info('installing vbcc_target_m68k-amigaos')
copytree('{sources}/vclib/targets/m68k-amigaos/include',
'{target}/vbcc-include')
copytree('{sources}/vclib/targets/m68k-amigaos/lib',
'{target}/vbcc-lib')
config = textfile(
('-cc=vbccm68k -quiet -hunkdebug %s -o= %s %s -O=%ld' +
' -I{target}/vbcc-include -I{target}/os-include'),
('-ccv=vbccm68k -hunkdebug %s -o= %s %s -O=%ld' +
' -I{target}/vbcc-include -I{target}/os-include'),
('-as=vasmm68k_mot -quiet -Fhunk -phxass -opt-fconst -nowarn=62' +
' -I{target}/os-include %s -o %s'),
('-asv=vasmm68k_mot -Fhunk -phxass -opt-fconst -nowarn=62' +
' -I{target}/os-include %s -o %s'),
'-rm=rm %s',
'-rmv=rm -v %s',
('-ld=vlink -bamigahunk -x -Bstatic -Cvbcc -nostdlib' +
' {target}/vbcc-lib/startup.o %s %s' +
' -L{target}/vbcc-lib -L{target}/vbcc-include -lvc -o %s'),
('-l2=vlink -bamigahunk -x -Bstatic -Cvbcc -nostdlib %s %s' +
' -L{target}/vbcc-lib -L{target}/vbcc-include -o %s'),
('-ldv=vlink -bamigahunk -t -x -Bstatic -Cvbcc -nostdlib'
' {target}/vbcc-lib/startup.o %s %s' +
' -L{target}/vbcc-lib -L{target}/vbcc-include -lvc -o %s'),
('-l2v=vlink -bamigahunk -t -x -Bstatic -Cvbcc -nostdlib %s %s' +
' -L{target}/vbcc-lib -L{target}/vbcc-include -o %s'),
'-ldnodb=-s -Rshort',
'-ul=-l%s',
'-cf=-F%s',
'-ml=500')
move(config, '{target}/etc/vc.config')
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'
"""
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++'
"""
On 64-bit architecture GNU Assembler crashes writing out an object, due to
(probably) miscalculated structure sizes. There could be some other bugs
lurking there in 64-bit mode, but I have little incentive chasing them.
Just compile everything in 32-bit mode and forget about the issues.
"""
ARCH = '-m32' if platform.machine() == 'x86_64' else ''
environ['CC'] = ' '.join([find_executable(CC), ARCH])
environ['CXX'] = ' '.join([find_executable(CXX), ARCH])
find_executable('patch')
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('{lha}')
configure('{lha}',
'--disable-shared',
'--prefix={host}',
copy_source=True)
make('{lha}')
make('{lha}', 'install')
unpack('{m4}')
configure('{m4}', '--prefix={host}')
make('{m4}')
make('{m4}', 'install')
unpack('{gawk}')
configure('{gawk}', '--prefix={host}')
make('{gawk}')
make('{gawk}', 'install')
unpack('{flex}')
configure('{flex}', '--prefix={host}')
make('{flex}')
make('{flex}', 'install')
unpack('{bison}')
configure('{bison}', '--prefix={host}')
make('{bison}')
make('{bison}', 'install')
unpack('{texinfo}')
configure('{texinfo}', '--prefix={host}')
make('{texinfo}')
make('{texinfo}', 'install')
unpack('{autoconf}')
configure('{autoconf}', '--prefix={host}')
make('{autoconf}')
make('{autoconf}', 'install')
prepare_target()
unpack('vasm', work_dir='{build}')
make('vasm', CPU='m68k', SYNTAX='mot')
unpack('vlink', work_dir='{build}')
build_vlink()
unpack('vbcc')
patch('vbcc')
build_vbcc()
unpack('vclib', top_dir='vbcc_target_m68k-amigaos')
install_vbcc_toolchain()
"""
Older gcc compilers (i.e. 2.95.3 and 3.4.6) and binutils have to be tricked
into thinking that they're being compiled on Linux IA-32 machine. Theirs
config.guess script knows nothing about x86-64 or darwin.
"""
unpack('{binutils}')
patch('{binutils}')
configure('{binutils}',
'--prefix={target}',
'--host=i686-linux-gnu',
'--target=m68k-amigaos')
make('{binutils}')
make('{binutils}', 'install')
unpack('{ixemul}', top_dir='ixemul')
patch('{ixemul}')
unpack('{gcc_core}', top_dir='{gcc}', dst_dir='{gcc}')
unpack('{gcc_gpp}', top_dir='{gcc}', dst_dir='{gcc}')
patch('{gcc}')
with env(CC=environ['CC'] + ' -std=gnu89',
CXX=environ['CXX'] + ' -std=gnu++98'):
configure('{gcc}',
'--prefix={target}',
'--host=i686-linux-gnu',
'--build=i686-linux-gnu',
'--target=m68k-amigaos',
'--enable-languages=c',
'--with-headers={sources}/{ixemul}/include')
make('{gcc}', MAKEINFO='makeinfo', CFLAGS_FOR_TARGET='-noixemul')
make('{gcc}', 'install', MAKEINFO='makeinfo', CFLAGS_FOR_TARGET='-noixemul')
unpack('fd2sfd')
patch('fd2sfd')
configure('fd2sfd', '--prefix={target}', copy_source=True)
make('fd2sfd')
make('fd2sfd', 'install')
unpack('sfdc')
patch('sfdc')
configure('sfdc', '--prefix={target}', copy_source=True)
make('sfdc')
make('sfdc', 'install')
unpack('{NDK}')
patch('{NDK}')
install_ndk()
unpack('libamiga', top_dir='.')
install_libamiga()
unpack('libnix')
configure('libnix',
'--prefix={target}',
'--host=i686-linux-gnu',
'--target=m68k-amigaos')
make('libnix',
CC='m68k-amigaos-gcc',
CPP='m68k-amigaos-gcc -E',
AR='m68k-amigaos-ar',
AS='m68k-amigaos-as',
RANLIB='m68k-amigaos-ranlib',
LD='m68k-amigaos-ld')
make('libnix', 'install')
copy('{sources}/libnix/sources/headers/stabs.h',
'{target}/m68k-amigaos/sys-include')
unpack('{libm}', top_dir='contrib/libm')
with env(CC='m68k-amigaos-gcc -noixemul',
AR='m68k-amigaos-ar',
RANLIB='m68k-amigaos-ranlib'):
configure('{libm}',
'--prefix={target}',
'--host=i686-linux-gnu',
'--target=m68k-amigaos')
make('{libm}')
make('{libm}', 'install')
with cwd('{sources}'):
remove('{gpp}')
symlink('{gcc}', '{gpp}')
with env(CC=environ['CC'] + ' -std=gnu89',
CXX=environ['CXX'] + ' -std=gnu++98'):
configure('{gpp}',
'--prefix={target}',
'--host=i686-linux-gnu',
'--build=i686-linux-gnu',
'--target=m68k-amigaos',
'--enable-languages=c++',
'--with-headers={sources}/{ixemul}/include')
make('{gpp}', MAKEINFO='makeinfo', CFLAGS_FOR_TARGET='-noixemul')
make('{gpp}', 'install', MAKEINFO='makeinfo', CFLAGS_FOR_TARGET='-noixemul')
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 (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('--binutils', choices=['2.9.1'], default='2.9.1',
help='desired binutils version')
parser.add_argument('--gcc', choices=['2.95.3'], default='2.95.3',
help='desired gcc version')
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)
setvar(lha='lhasa-0.3.0',
m4='m4-1.4.17',
gawk='gawk-3.1.8',
flex='flex-2.5.4',
bison='bison-1.35',
autoconf='autoconf-2.13',
texinfo='texinfo-4.12',
NDK='NDK_3.9',
ixemul='ixemul-48.2',
libm='libm-5.4',
binutils='binutils-{binutils_ver}',
gcc_core='gcc-core-{gcc_ver}',
gcc_gpp='gcc-g++-{gcc_ver}',
gcc='gcc-{gcc_ver}',
gpp='g++-{gcc_ver}',
patches=path.join('{top}', 'patches'),
stamps=path.join('{top}', '.build-m68k', 'stamps'),
build=path.join('{top}', '.build-m68k', 'build'),
sources=path.join('{top}', '.build-m68k', 'sources'),
host=path.join('{top}', '.build-m68k', 'host'),
tmpdir=path.join('{top}', '.build-m68k', 'tmp'),
target=path.join('{top}', 'm68k-amigaos'),
archives=path.join('{top}', '.build-m68k', 'archives'))
if args.prefix is not None:
setvar(target=args.prefix)
if not path.exists('{target}'):
mkdir('{target}')
eval(args.action + "()")