2016-09-30 17:24:12 +00:00
#!/usr/bin/python2.7 -B
2015-08-23 20:28:40 +00:00
# Build cross toolchain for AmigaOS <= 3.9 / M68k target.
2015-08-31 06:29:07 +00:00
from fnmatch import fnmatch
2016-10-01 13:40:03 +00:00
from glob import glob
2017-03-22 19:35:41 +00:00
from logging import info, getLogger
2015-08-23 20:28:40 +00:00
from os import environ
2017-02-18 19:17:10 +00:00
import os
2015-08-23 20:28:40 +00:00
import argparse
2017-09-06 06:03:54 +00:00
from argparse import RawTextHelpFormatter
2015-08-23 20:28:40 +00:00
import logging
import platform
2015-09-07 21:09:43 +00:00
import re
import string
2015-08-23 20:28:40 +00:00
import sys
URLS = \
2016-10-02 10:41:41 +00:00
['ftp://ftp.gnu.org/gnu/m4/m4-1.4.17.tar.gz',
2015-08-23 20:28:40 +00:00
'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',
2016-10-02 10:41:41 +00:00
'ftp://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz',
2017-03-22 19:35:41 +00:00
('ftp://ftp.uk.freesbie.org/sites/distfiles.gentoo.org/distfiles/' +
'flex-2.5.4a.tar.gz', 'flex-2.5.4.tar.gz'),
2015-08-23 20:28:40 +00:00
('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://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',
2015-09-09 20:52:29 +00:00
'http://aminet.net/dev/asm/ira.lha',
2016-10-02 19:16:01 +00:00
'http://sun.hasenbraten.de/~frank/projects/download/vdam68k.tar.gz',
2017-08-20 19:10:18 +00:00
('http://server.owl.de/~frank/vbcc/2017-08-14/vbcc_target_m68k-amigaos.lha',
2015-08-29 10:03:59 +00:00
'vclib.lha')]
2015-08-23 20:28:40 +00:00
2015-09-07 21:09:43 +00:00
MULTILIB = [('', []),
('libb', ['-fbaserel', '-DSMALL_DATA']),
('libm020', ['-m68020']),
('libb/libm020', ['-fbaserel', '-DSMALL_DATA', '-m68020']),
('libm020/libm881', ['-m68020', '-m68881']),
('libb/libm020/libm881',
['-fbaserel', '-DSMALL_DATA', '-m68020', '-m68881']),
('libb32/libm020', ['-fbaserel32', '-DSMALL_DATA', '-m68020'])]
2015-08-23 20:28:40 +00:00
from common import * # NOQA
2015-09-02 08:46:05 +00:00
@recipe('target-prepare')
2015-08-23 20:28:40 +00:00
def prepare_target():
info('preparing target')
2016-10-09 11:02:15 +00:00
with cwd('{prefix}'):
mkdir('bin', 'etc', '{target}')
with cwd('{prefix}/{target}'):
2017-01-10 22:21:22 +00:00
mkdir('bin', 'ndk/include/inline', 'ndk/include/lvo',
2016-10-09 11:02:15 +00:00
'ndk/lib', 'ndk/lib/fd', 'ndk/lib/sfd')
2015-08-23 20:28:40 +00:00
2015-09-02 08:46:05 +00:00
@recipe('{NDK}-install')
2015-08-23 20:28:40 +00:00
def install_ndk():
info('installing ndk')
2017-03-22 19:35:41 +00:00
copytree('{sources}/{NDK}/Include/include_h', '{prefix}/{target}/ndk/include')
copytree('{sources}/{NDK}/Include/include_i', '{prefix}/{target}/ndk/include')
copytree('{sources}/{NDK}/Include/fd', '{prefix}/{target}/ndk/lib/fd')
copytree('{sources}/{NDK}/Include/sfd', '{prefix}/{target}/ndk/lib/sfd')
copytree('{sources}/{NDK}/Include/linker_libs', '{prefix}/{target}/ndk/lib',
2015-08-23 20:28:40 +00:00
exclude=['README'])
2017-03-22 19:35:41 +00:00
copytree('{sources}/{NDK}/Documentation/Autodocs', '{prefix}/{target}/ndk/doc')
2015-08-23 20:28:40 +00:00
2017-03-22 19:35:41 +00:00
for name in find('{prefix}/{target}/ndk/lib/sfd', include=['*.sfd']):
2015-08-23 20:28:40 +00:00
base = path.basename(name).split('_')[0]
execute('sfdc', '--target=m68k-amigaos', '--mode=proto',
2017-03-22 19:35:41 +00:00
'--output={prefix}/{target}/ndk/include/proto/%s.h' % base, name)
2015-08-23 20:28:40 +00:00
execute('sfdc', '--target=m68k-amigaos', '--mode=macros',
2017-03-22 19:35:41 +00:00
'--output={prefix}/{target}/ndk/include/inline/%s.h' % base, name)
2015-08-23 20:28:40 +00:00
execute('sfdc', '--target=m68k-amigaos', '--mode=lvo',
2017-03-22 19:35:41 +00:00
'--output={prefix}/{target}/ndk/include/lvo/%s_lib.i' % base, name)
2015-08-23 20:28:40 +00:00
2017-03-24 16:07:50 +00:00
copytree('{prefix}/{target}/ndk/include', '{prefix}/{target}/sys-include')
2015-08-23 20:28:40 +00:00
2016-04-24 11:21:24 +00:00
@recipe('headers-install')
def headers_install():
2017-03-25 10:45:34 +00:00
info('installing libnix + NDK header files')
2016-04-24 11:21:24 +00:00
2017-03-25 10:45:34 +00:00
copytree('submodules/libnix/sources/headers', '{prefix}/{target}/libnix/include')
2016-04-24 11:21:24 +00:00
2017-01-10 21:37:47 +00:00
@recipe('fd2sfd-install')
def install_fd2sfd():
info('installing fd2sfd')
copy('{build}/fd2sfd/fd2sfd', '{prefix}/bin')
2017-01-10 22:21:22 +00:00
copy('{build}/fd2sfd/cross/share/{target}/alib.h',
'{prefix}/{target}/ndk/include/inline')
2017-01-10 21:37:47 +00:00
2016-10-23 10:56:47 +00:00
@recipe('fd2pragma-install')
def install_fd2pragma():
info('installing fd2pragma')
copy('{build}/fd2pragma/fd2pragma', '{prefix}/bin')
2017-01-10 22:21:22 +00:00
for header in ['macros.h', 'stubs.h']:
copy(path.join('{build}/fd2pragma/Include/inline', header),
'{prefix}/{target}/ndk/include/inline')
2016-10-23 10:56:47 +00:00
2015-09-09 20:52:29 +00:00
@recipe('tools-install')
def install_tools():
info('installing extra tools')
2017-03-22 19:35:41 +00:00
copy('{build}/ira/ira', '{prefix}/bin')
copy('{build}/vdam68k/vda68k', '{prefix}/bin')
2015-09-09 20:52:29 +00:00
2016-10-02 10:41:41 +00:00
@recipe('{libamiga}-install')
2015-08-23 20:28:40 +00:00
def install_libamiga():
info('installing libamiga')
2017-10-18 20:14:31 +00:00
if fill_in('{gcc}') == 'gcc-3.4.6':
copytree('{sources}/{libamiga}/lib', '{prefix}/{target}/lib')
else:
copytree('{sources}/{libamiga}/lib', '{prefix}/{target}/libnix/lib')
2015-08-29 10:03:59 +00:00
2016-10-02 10:41:41 +00:00
@recipe('{clib2}-install')
2016-04-17 15:48:02 +00:00
def install_clib2():
info('installing clib2')
2017-03-22 19:35:41 +00:00
with cwd('{prefix}/{target}/clib2'):
2016-10-02 10:41:41 +00:00
copytree('{build}/{clib2}/lib', 'lib')
copytree('{build}/{clib2}/include', 'include')
2016-04-17 15:48:02 +00:00
2015-09-02 08:46:05 +00:00
@recipe('vbcc-build')
2015-08-29 10:03:59 +00:00
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',
2016-01-15 15:30:51 +00:00
'n', 'y', 'signed long long',
'n', 'y', 'unsigned long long',
2015-08-29 10:03:59 +00:00
'n', 'y', 'float',
'n', 'y', 'double')
2017-03-22 19:35:41 +00:00
make('vbcc', TARGET='m68k', ETCDIR='\\"{prefix}/etc/\\"', CONFIG=config)
2015-08-29 10:03:59 +00:00
remove(config)
2015-09-02 08:46:05 +00:00
@recipe('vlink-build')
2015-08-29 10:03:59 +00:00
def build_vlink():
mkdir('{build}/vlink/objects')
2015-09-02 08:46:05 +00:00
make('vlink')
2015-08-29 10:03:59 +00:00
2015-09-02 08:46:05 +00:00
@recipe('vbcc-install')
2015-08-29 10:03:59 +00:00
def install_vbcc_toolchain():
info('installing vasm')
2017-03-22 19:35:41 +00:00
copy('{build}/vasm/vasmm68k_mot', '{prefix}/{target}/bin')
copy('{build}/vasm/vobjdump', '{prefix}/bin')
2015-08-29 10:03:59 +00:00
vasm = textfile(
'#!/bin/sh',
'',
2017-03-22 19:35:41 +00:00
'{prefix}/{target}/bin/vasmm68k_mot -I{prefix}/{target}/ndk/include "$@"')
2015-08-29 10:03:59 +00:00
chmod(vasm, 0755)
2017-03-22 19:35:41 +00:00
move(vasm, '{prefix}/bin/vasm')
2015-08-29 10:03:59 +00:00
info('installing vlink')
2017-03-22 19:35:41 +00:00
copy('{build}/vlink/vlink', '{prefix}/bin')
2015-08-29 10:03:59 +00:00
info('installing vbcc')
2017-03-22 19:35:41 +00:00
copy('{build}/vbcc/bin/vbccm68k', '{prefix}/{target}/bin')
copy('{build}/vbcc/bin/vc', '{prefix}/bin')
copy('{build}/vbcc/bin/vprof', '{prefix}/bin')
2015-08-29 10:03:59 +00:00
info('installing vbcc_target_m68k-amigaos')
copytree('{sources}/vclib/targets/m68k-amigaos/include',
2017-03-22 19:35:41 +00:00
'{prefix}/{target}/vbcc/include')
2015-08-29 10:03:59 +00:00
copytree('{sources}/vclib/targets/m68k-amigaos/lib',
2017-03-22 19:35:41 +00:00
'{prefix}/{target}/vbcc/lib')
2015-08-29 10:25:29 +00:00
config = textfile(
2017-03-22 19:35:41 +00:00
('-cc={prefix}/{target}/bin/vbccm68k -hunkdebug %s -o= %s %s -O=%ld' +
' -quiet -I{prefix}/{target}/vbcc/include -I{prefix}/{target}/ndk/include'),
('-ccv={prefix}/{target}/bin/vbccm68k -hunkdebug %s -o= %s %s -O=%ld' +
' -I{prefix}/{target}/vbcc/include -I{prefix}/{target}/ndk/include'),
('-as={prefix}/{target}/bin/vasmm68k_mot -Fhunk -phxass -opt-fconst' +
' -nowarn=62 -quiet -I{prefix}/{target}/ndk/include %s -o %s'),
('-asv={prefix}/{target}/bin/vasmm68k_mot -Fhunk -phxass -opt-fconst' +
' -nowarn=62 -I{prefix}/{target}/ndk/include %s -o %s'),
2015-08-29 10:25:29 +00:00
'-rm=rm %s',
'-rmv=rm -v %s',
2017-03-22 19:35:41 +00:00
('-ld={prefix}/bin/vlink -bamigahunk -x -Bstatic -Cvbcc -nostdlib' +
' {prefix}/{target}/vbcc/lib/startup.o %s %s' +
' -L{prefix}/{target}/vbcc/lib' +
' -L{prefix}/{target}/vbcc/include -lvc -o %s'),
('-l2={prefix}/bin/vlink -bamigahunk -x -Bstatic -Cvbcc -nostdlib' +
' %s %s -L{prefix}/{target}/vbcc/lib' +
' -L{prefix}/{target}/vbcc/include -o %s'),
('-ldv={prefix}/bin/vlink -bamigahunk -t -x -Bstatic -Cvbcc -nostdlib' +
' {prefix}/{target}/vbcc/lib/startup.o %s %s' +
' -L{prefix}/{target}/vbcc/lib' +
' -L{prefix}/{target}/vbcc/include -lvc -o %s'),
('-l2v={prefix}/bin/vlink -bamigahunk -t -x -Bstatic -Cvbcc -nostdlib' +
' %s %s -L{prefix}/{target}/vbcc/lib' +
' -L{prefix}/{target}/vbcc/include -o %s'),
2015-08-29 10:25:29 +00:00
'-ldnodb=-s -Rshort',
'-ul=-l%s',
'-cf=-F%s',
'-ml=500')
2017-03-22 19:35:41 +00:00
chmod(config, 0644)
move(config, '{prefix}/etc/vc.config')
2015-08-23 20:28:40 +00:00
2016-09-30 17:24:12 +00:00
def update_autotools(dst):
2016-10-02 10:41:41 +00:00
copy('{sources}/{automake}/lib/config.guess', path.join(dst, 'config.guess'))
copy('{sources}/{automake}/lib/config.sub', path.join(dst, 'config.sub'))
2016-09-30 17:24:12 +00:00
2016-10-01 13:40:03 +00:00
def touch_genfiles(dst):
"""
For binutils and gcc we want to make sure C source & headers file doesn't get
regenerated. Otherwise it can cause weird errors later in the build process
(e.g. in ldexp.c:560)
"""
2017-03-22 19:35:41 +00:00
for name in find(dst, include=['*.l', '*.y', '*.in', '*.ac']):
2016-10-01 13:40:03 +00:00
basename = path.splitext(name)[0]
2017-03-22 19:35:41 +00:00
# do not touch files - reset the src file stamp instead!
2017-04-04 20:43:48 +00:00
if not ('/isl' in name or '/gmp' in name or '/mpfr' in name or '/mpc' in name):
os.utime(name, (1, 1))
2016-10-01 13:40:03 +00:00
2017-02-18 17:18:42 +00:00
def download():
2017-02-18 15:15:33 +00:00
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)
2017-03-24 16:07:50 +00:00
def shallowCheckout(murl, mpath, mbranch):
2018-01-25 13:24:31 +00:00
print "%s - %s - %s" % (murl, mpath, mbranch)
2017-03-24 16:07:50 +00:00
if murl == None:
return
if path.exists(path.join(mpath, '.git')):
return
2018-02-10 08:27:35 +00:00
if mbranch == None:
execute('git', 'clone', murl, mpath)
2017-03-24 16:07:50 +00:00
else:
2018-02-10 08:27:35 +00:00
execute('git', 'clone', murl, '-b', mbranch, mpath)
2017-06-26 12:50:27 +00:00
2017-03-24 16:07:50 +00:00
2017-02-18 17:18:42 +00:00
def update():
2017-02-18 15:15:33 +00:00
execute('git', 'submodule', 'init');
2017-03-24 16:07:50 +00:00
with open('.gitmodules') as f:
content = f.readlines()
mpath = None
murl = None
mbranch = None
for x in content:
x = x.strip()
if x.startswith('['):
shallowCheckout(murl, mpath, mbranch)
mpath = None
murl = None
mbranch = None
elif x.startswith('url'):
murl = x.partition('=')[2].strip()
elif x.startswith('path'):
mpath = x.partition('=')[2].strip()
elif x.startswith('branch'):
mbranch = x.partition('=')[2].strip()
2018-01-25 13:24:31 +00:00
shallowCheckout(murl, mpath, mbranch)
execute('git', 'submodule', 'update')
2017-02-18 15:15:33 +00:00
2015-09-02 08:46:05 +00:00
def build():
2017-03-22 15:07:34 +00:00
_build(True)
def xbuild():
_build(False)
def _build(pull):
2015-08-23 20:53:35 +00:00
for var in environ.keys():
if var not in ['_', 'LOGNAME', 'HOME', 'SHELL', 'TMPDIR', 'PWD']:
del environ[var]
2016-09-30 17:24:12 +00:00
PATH = ['/usr/bin', '/bin']
if fnmatch(platform.system(), 'MSYS_NT*'):
PATH.append('/usr/bin/core_perl') # pod2text, pod2man
environ['PATH'] = ":".join(PATH)
2015-08-23 20:53:35 +00:00
environ['LANG'] = 'C'
environ['TERM'] = 'xterm'
2017-03-22 15:07:34 +00:00
if pull:
download()
update()
2016-10-02 10:41:41 +00:00
2015-09-10 07:19:25 +00:00
add_site_dir('{host}')
2015-08-23 20:53:35 +00:00
"""
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++'
2016-03-05 19:12:47 +00:00
CC = find_executable(CC)
CXX = find_executable(CXX)
2017-03-23 09:10:34 +00:00
FLAGS = os.path.expandvars('$FLAGS')
if FLAGS == '$FLAGS':
FLAGS = '-g'
2017-03-22 19:35:41 +00:00
if getLogger().isEnabledFor(logging.DEBUG):
FLAGS += ' -Wall'
else:
FLAGS += ' -w'
environ['MAKEFLAGS'] = '--silent'
2016-03-05 19:12:47 +00:00
2017-08-20 19:10:18 +00:00
mkdir(path.join('{prefix}', 'bin'))
2016-09-30 17:24:12 +00:00
environ['CC'] = CC
environ['CXX'] = CXX
2017-03-22 19:35:41 +00:00
environ['PATH'] = ':'.join([path.join('{prefix}', 'bin'),
2015-08-23 20:53:35 +00:00
environ['PATH']])
2015-08-23 20:28:40 +00:00
2016-02-16 09:39:38 +00:00
setvar(cc=environ['CC'], cxx=environ['CXX'])
2016-01-18 21:35:50 +00:00
2016-01-18 18:14:54 +00:00
"""
2016-02-16 09:39:38 +00:00
When we have a working compiler in our path, we shoule also check if the
required programs, headers and libraries are present.
2016-01-18 18:14:54 +00:00
"""
2017-03-24 16:07:50 +00:00
if not args.nodeps:
if checkstamps('{binutils}'):
removemodule('{binutils}')
if checkstamps('{gcc}'):
removemodule('{libnix}')
removemodule('{clib2}')
removemodule('{libdebug}')
removemodule('{libm}')
if checkstamps('{libnix}'):
2017-03-22 15:07:34 +00:00
removemodule('{libnix}')
2017-03-25 10:45:34 +00:00
rmtree(path.join('{build}', '{gcc}', '{target}'))
for f in glob(path.join('{stamps}', '{gcc}' + '-make*')):
remove(f)
2017-07-07 21:02:38 +00:00
for f in glob(path.join('{stamps}', 'mui*')):
remove(f)
for f in glob(path.join('{stamps}', 'mmu*')):
remove(f)
2017-03-25 10:45:34 +00:00
remove(path.join('{stamps}', 'headers-install'))
2017-03-24 16:07:50 +00:00
if checkstamps('{clib2}'):
2017-03-22 15:07:34 +00:00
removemodule('{clib2}')
2017-03-24 16:07:50 +00:00
if checkstamps('{libdebug}'):
2017-03-22 15:07:34 +00:00
removemodule('{libdebug}')
2017-03-24 16:07:50 +00:00
if checkstamps('{libm}'):
2017-03-22 15:07:34 +00:00
removemodule('{libm}')
2016-02-16 09:39:38 +00:00
find_executable('perl')
2016-09-30 17:24:12 +00:00
find_executable('pod2text')
find_executable('pod2man')
2016-05-10 07:23:11 +00:00
find_executable('gperf')
2016-02-16 09:39:38 +00:00
find_executable('patch')
find_executable('make')
find_executable('git')
find_executable('yacc')
2016-09-30 17:24:12 +00:00
require_header(['ncurses.h', 'ncurses/ncurses.h'],
lang='c', errmsg='libncurses-dev package missing')
2016-02-16 09:39:38 +00:00
2016-10-02 10:41:41 +00:00
unpack('{automake}')
2016-02-16 09:39:38 +00:00
py_ver = 'python%d.%d' % (sys.version_info.major, sys.version_info.minor)
2016-10-02 13:54:05 +00:00
require_header([path.join(py_ver, 'Python.h')],
lang='c', errmsg='python-dev package missing')
unpack('python-lha', work_dir='{build}')
python_setup('python-lha')
2016-01-18 18:14:54 +00:00
2017-06-20 17:16:04 +00:00
if not args.mytools:
unpack('{m4}')
configure('{m4}', '--prefix={host}')
make('{m4}')
make('{m4}', 'install')
unpack('{gawk}')
patch('{gawk}')
update_autotools('{sources}/{gawk}')
configure('{gawk}', '--prefix={host}')
make('{gawk}')
make('{gawk}', 'install')
unpack('{flex}')
configure('{flex}', '--prefix={host}')
# flex build is broken with multiple threads
nt = fill_in('{numThreads}')
setvar(numThreads='1')
make('{flex}')
make('{flex}', 'install')
setvar(numThreads=nt)
unpack('{bison}')
update_autotools('{sources}/{bison}/config')
configure('{bison}', '--prefix={host}')
make('{bison}')
make('{bison}', 'install')
unpack('{texinfo}')
update_autotools('{sources}/{texinfo}/build-aux')
configure('{texinfo}', '--prefix={host}')
make('{texinfo}')
make('{texinfo}', 'install')
unpack('{autoconf}')
update_autotools('{sources}/{autoconf}')
configure('{autoconf}', '--prefix={host}')
make('{autoconf}')
make('{autoconf}', 'install')
2015-08-23 20:28:40 +00:00
prepare_target()
2015-08-29 10:03:59 +00:00
unpack('vasm', work_dir='{build}')
2017-02-18 22:03:11 +00:00
make('vasm', CPU='m68k', SYNTAX='mot')
2015-08-29 10:03:59 +00:00
unpack('vlink', work_dir='{build}')
build_vlink()
unpack('vbcc')
patch('vbcc')
build_vbcc()
unpack('vclib', top_dir='vbcc_target_m68k-amigaos')
install_vbcc_toolchain()
2016-10-02 10:41:41 +00:00
update_autotools('{submodules}/fd2sfd')
unpack('fd2sfd', work_dir='{build}')
2017-03-22 19:35:41 +00:00
configure('fd2sfd', '--prefix={prefix}', from_dir='{build}/fd2sfd')
2017-02-18 22:03:11 +00:00
make('fd2sfd')
2017-01-10 21:37:47 +00:00
install_fd2sfd()
2015-09-03 20:29:43 +00:00
2017-03-22 19:35:41 +00:00
unpack('fd2pragma', work_dir='{build}')
make('fd2pragma')
install_fd2pragma()
2015-09-03 20:29:43 +00:00
unpack('sfdc')
2017-03-22 19:35:41 +00:00
configure('sfdc', '--prefix={prefix}', copy_source=True)
2017-02-18 22:03:11 +00:00
make('sfdc')
make('sfdc', 'install')
2015-09-03 20:29:43 +00:00
unpack('{NDK}')
patch('{NDK}')
install_ndk()
2016-09-30 17:24:12 +00:00
"""
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.
"""
2017-03-27 19:05:45 +00:00
ARCH = '-m32' if args.m32 else ''
2016-10-02 19:16:55 +00:00
CC = ' '.join([CC, ARCH, '-std=gnu11'])
CXX = ' '.join([CXX, ARCH, '-std=gnu++11'])
2016-09-30 17:24:12 +00:00
2015-08-23 20:28:40 +00:00
"""
2017-03-22 19:35:41 +00:00
Older gcc compilers (i.e. 2.95.3, 3.4.6) and binutils have to be tricked
2015-08-23 20:28:40 +00:00
into thinking that they're being compiled on Linux IA-32 machine. Theirs
config.guess script knows nothing about x86-64 or darwin.
"""
2017-03-22 19:35:41 +00:00
with env(CC=CC, CXX=CXX, CFLAGS=FLAGS, CXXFLAGS=FLAGS):
2016-05-10 07:23:11 +00:00
configure('{binutils}',
2017-03-22 19:35:41 +00:00
'--prefix={prefix}',
'--infodir={prefix}/{target}/info',
'--mandir={prefix}/share/man',
2017-06-09 08:00:08 +00:00
'--host=i686-linux-gnu' if fill_in('{binutils}') != 'binutils-2.14' or platform.system() == 'Darwin' or fnmatch(platform.system(), "CYGWIN*") else '--prefix={prefix}',
2016-10-02 10:41:41 +00:00
'--target=m68k-amigaos',
from_dir='{submodules}/{binutils}')
2016-10-02 19:16:55 +00:00
touch_genfiles('{submodules}/{binutils}')
2017-02-18 22:03:11 +00:00
make('{binutils}')
2017-03-22 19:35:41 +00:00
make('{binutils}', 'install-binutils')
make('{binutils}', 'install-gas')
make('{binutils}', 'install-ld')
make('{binutils}', 'install-info')
2015-08-23 20:28:40 +00:00
2018-01-25 13:24:31 +00:00
copytree('{submodules}/{ixemul}/include/', '{prefix}/{target}/sys-include')
2015-08-23 20:28:40 +00:00
2017-06-20 17:16:04 +00:00
if fill_in('{gcc}') == 'gcc-3.4.6':
with cwd('{archives}'):
fetch('gcc-3.4.6.tar.bz2', 'https://ftp.gnu.org/gnu/gcc/gcc-3.4.6/gcc-3.4.6.tar.bz2')
unpack('{gcc}', top_dir='gcc-3.4.6')
patch('{gcc}')
remove(path.join('{sources}', '{gcc}', 'gcc/cp/cfns.h'))
2017-10-11 21:43:40 +00:00
remove(path.join('{sources}', '{gcc}', 'gcc/c-parse.c'))
2017-06-20 17:16:04 +00:00
2017-03-22 19:35:41 +00:00
with env(CC=CC, CXX=CXX, CFLAGS=FLAGS, CXXFLAGS=FLAGS):
2015-08-31 08:37:22 +00:00
configure('{gcc}',
2017-03-22 19:35:41 +00:00
'--prefix={prefix}',
'--infodir={prefix}/{target}/info',
'--mandir={prefix}/share/man',
2017-03-28 21:34:33 +00:00
'--host=i686-linux-gnu' if fill_in('{gcc}') != 'gcc-6' or args.m32 else '--prefix={prefix}',
'--build=i686-linux-gnu' if fill_in('{gcc}') != 'gcc-6' or args.m32 else '--prefix={prefix}',
2015-08-31 08:37:22 +00:00
'--target=m68k-amigaos',
2017-06-20 17:16:04 +00:00
'--enable-languages=c,c++,objc' if fill_in('{gcc}') != 'gcc-3.4.6' else '--enable-languages=c,c++',
2016-05-18 22:07:12 +00:00
'--enable-version-specific-runtime-libs',
2017-02-17 16:48:21 +00:00
'--disable-libssp',
2018-01-25 13:24:31 +00:00
'--with-headers={submodules}/{ixemul}/include',
2017-06-20 17:16:04 +00:00
from_dir='{submodules}/{gcc}' if fill_in('{gcc}') != 'gcc-3.4.6' else '{sources}/{gcc}')
touch_genfiles('{submodules}/{gcc}' if fill_in('{gcc}') != 'gcc-3.4.6' else '{sources}/{gcc}')
2017-02-18 22:03:11 +00:00
make('{gcc}', 'all-gcc',
2017-07-11 11:05:21 +00:00
MAKEINFO='makeinfo', CFLAGS_FOR_TARGET='-noixemul -Os')
2017-02-18 22:03:11 +00:00
make('{gcc}', 'install-gcc',
2017-07-11 11:05:21 +00:00
MAKEINFO='makeinfo', CFLAGS_FOR_TARGET='-noixemul -Os')
2015-08-23 20:28:40 +00:00
2016-05-18 22:07:12 +00:00
headers_install()
2016-10-02 10:41:41 +00:00
unpack('{libamiga}', top_dir='.')
2015-08-23 20:28:40 +00:00
install_libamiga()
2017-06-20 17:16:04 +00:00
if fill_in('{gcc}') != 'gcc-3.4.6':
with env(CC=CC, CXX=CXX, CFLAGS=FLAGS, CXXFLAGS=FLAGS):
2017-07-11 11:05:21 +00:00
make('{gcc}', 'all-target-libgcc', MAKEINFO='makeinfo', CFLAGS_FOR_TARGET='-noixemul -Os')
make('{gcc}', 'install-target-libgcc', MAKEINFO='makeinfo', CFLAGS_FOR_TARGET='-noixemul -Os')
2017-05-13 10:36:12 +00:00
2017-06-20 17:16:04 +00:00
configure('{libnix}',
2017-10-18 20:01:04 +00:00
'--prefix={prefix}/{target}/libnix' if fill_in('{gcc}') == 'gcc-6' else '--prefix={prefix}/{target}',
2017-05-07 15:52:45 +00:00
'--host=i686-linux-gnu',
'--target=m68k-amigaos',
from_dir='{submodules}/{libnix}')
2017-06-20 17:16:04 +00:00
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')
2017-02-18 22:03:11 +00:00
make('{libnix}', 'install')
2015-08-23 20:28:40 +00:00
2016-10-02 10:41:41 +00:00
copy('{submodules}/{libnix}/sources/headers/stabs.h',
2017-03-22 19:35:41 +00:00
'{prefix}/{target}/libnix/include')
2015-08-23 20:28:40 +00:00
unpack('{libm}', top_dir='contrib/libm')
2016-09-30 17:24:12 +00:00
update_autotools('{sources}/{libm}')
2015-08-23 20:28:40 +00:00
with env(CC='m68k-amigaos-gcc -noixemul',
AR='m68k-amigaos-ar',
RANLIB='m68k-amigaos-ranlib'):
configure('{libm}',
2017-03-22 19:35:41 +00:00
'--prefix={prefix}/{target}/libnix',
2015-08-23 20:28:40 +00:00
'--host=i686-linux-gnu',
'--target=m68k-amigaos')
2017-02-18 22:03:11 +00:00
make('{libm}')
make('{libm}', 'install')
2015-08-23 20:28:40 +00:00
2016-04-24 08:18:04 +00:00
with env(CC='m68k-amigaos-gcc -noixemul',
AR='m68k-amigaos-ar',
RANLIB='m68k-amigaos-ranlib'):
2017-03-22 19:35:41 +00:00
touch_genfiles('{submodules}/{libdebug}')
2016-04-24 08:18:04 +00:00
configure('{libdebug}',
2017-03-22 19:35:41 +00:00
'--prefix={prefix}/{target}/libnix',
2016-10-02 10:41:41 +00:00
'--host=m68k-amigaos',
from_dir='{submodules}/{libdebug}')
2017-02-18 22:03:11 +00:00
make('{libdebug}')
make('{libdebug}', 'install')
2016-04-24 08:18:04 +00:00
2016-10-02 10:41:41 +00:00
unpack('{clib2}', work_dir='{build}', top_dir='library')
make('{clib2}', makefile='GNUmakefile.68k')
2016-05-18 22:07:12 +00:00
install_clib2()
2017-03-22 19:35:41 +00:00
with env(CC=CC, CXX=CXX, CFLAGS=FLAGS, CXXFLAGS=FLAGS):
make('{gcc}', 'all-target',
MAKEINFO='makeinfo', CFLAGS_FOR_TARGET='-noixemul')
make('{gcc}', 'install-target',
MAKEINFO='makeinfo', CFLAGS_FOR_TARGET='-noixemul')
2015-08-23 20:28:40 +00:00
2015-09-09 20:52:29 +00:00
unpack('ira', top_dir='.', work_dir='{build}')
2015-09-11 07:32:30 +00:00
patch('ira', work_dir='{build}')
2015-09-09 20:52:29 +00:00
make('ira')
2017-03-23 09:50:20 +00:00
unpack('vdam68k', top_dir='vda/M68k', work_dir='{build}')
2016-10-02 19:16:01 +00:00
make('vdam68k')
2015-09-09 20:52:29 +00:00
install_tools()
2015-08-23 20:28:40 +00:00
def clean():
rmtree('{stamps}')
rmtree('{sources}')
rmtree('{host}')
rmtree('{build}')
2015-08-29 10:03:59 +00:00
rmtree('{tmpdir}')
2015-08-23 20:28:40 +00:00
2015-09-07 21:09:43 +00:00
def read_sdk(filename):
phase = 'info'
info = {}
files = []
for line in open(filename):
line = line.strip()
if phase == 'info':
if line == '':
phase = 'files'
else:
fields = [field.strip() for field in line.split(':', 1)]
info[string.lower(fields[0])] = fields[1]
elif phase == 'files':
if ':' in line:
fields = [field.strip() for field in re.split('[: ]+', line)]
files.append(tuple(fields))
elif '=' in line:
fields = [field.strip() for field in line.split('=')]
files.append(tuple(['file'] + fields))
else:
files.append(('file', line))
return (info, files)
def list_sdk():
print 'Available SDKs:'
2016-10-01 13:40:03 +00:00
for filename in find('{top}/sdk', include=['*.sdk']):
2015-09-07 21:09:43 +00:00
info, _ = read_sdk(filename)
name = path.splitext(path.basename(filename))[0]
print ' - %s %s : %s' % (name, info['version'], info['short'])
def add_stubs(src):
obj = re.sub(r'\.c$', r'.o', src)
for libdir, cflags in MULTILIB:
2017-03-22 19:35:41 +00:00
lib = path.join('{prefix}/{target}/libnix/lib',
2017-02-12 11:50:15 +00:00
libdir, 'libnix/libstubs.a')
2015-09-07 21:09:43 +00:00
info('stubs: "%s" -> "%s"', obj, lib)
cflags = list(cflags) + ['-noixemul', '-c', '-o', obj, src]
2017-07-11 11:05:21 +00:00
execute('m68k-amigaos-gcc', '-Wall', '-Os', '-fomit-frame-pointer', *cflags)
2015-09-07 21:09:43 +00:00
execute('m68k-amigaos-ar', 'rs', lib, obj)
remove(obj)
def add_lib(src, libname):
obj = re.sub(r'\.a$', r'.o', libname)
for libdir, cflags in MULTILIB:
2017-01-18 20:29:30 +00:00
lib = path.join('{prefix}/{target}/lib', libdir, libname)
2015-09-07 21:09:43 +00:00
info('lib: "%s" -> "%s"', obj, lib)
cflags = list(cflags) + ['-noixemul', '-c', '-o', obj, src]
2017-07-11 11:05:21 +00:00
execute('m68k-amigaos-gcc', '-Wall', '-Os', '-fomit-frame-pointer', *cflags)
2015-09-07 21:09:43 +00:00
execute('m68k-amigaos-ar', 'rcs', lib, obj)
remove(obj)
@recipe('install-sdk', 1)
2017-01-11 21:34:35 +00:00
def process_sdk(sdk, lib_name, files):
with cwd(path.join('{sources}', sdk)):
2015-09-07 21:09:43 +00:00
for f in files:
kind = f[0]
if kind == 'fd2sfd':
2015-09-08 07:44:46 +00:00
fd, protos = f[1:]
2016-04-16 07:22:28 +00:00
sfd = path.splitext(path.basename(fd))[0]
2016-04-16 09:58:02 +00:00
if not fd.endswith('_lib.fd'):
2016-04-16 07:22:28 +00:00
sfd = sfd + '_lib.sfd'
else:
sfd = sfd + '.sfd'
2015-09-08 07:44:46 +00:00
info('fd2sfd: "%s" "%s" -> "%s"', fd, protos, sfd)
2015-09-07 21:09:43 +00:00
execute('fd2sfd', '-o', sfd, fd, protos)
2017-01-18 20:29:30 +00:00
copy(sfd, path.join('{prefix}/{target}/lib/sfd', sfd))
2015-09-07 21:09:43 +00:00
elif kind == 'sfdc':
source = f[1]
2016-04-16 07:22:28 +00:00
basename = re.sub(r'_lib.sfd$', r'', path.basename(source))
2015-09-07 21:09:43 +00:00
2017-01-18 20:29:30 +00:00
proto = path.join('{prefix}/{target}/include/proto', basename + '.h')
inline = path.join('{prefix}/{target}/include/inline', basename + '.h')
lvo = path.join('{prefix}/{target}/include/lvo', basename + '.i')
2015-09-07 21:09:43 +00:00
2015-09-08 07:44:46 +00:00
info('sfdc: "%s" -> "%s"', source, proto)
2015-09-07 21:09:43 +00:00
execute('sfdc', '--quiet', '--target=m68k-amigaos', '--mode=proto',
'--output=' + proto, source)
2015-09-08 07:44:46 +00:00
info('sfdc: "%s" -> "%s"', source, inline)
2015-09-07 21:09:43 +00:00
execute('sfdc', '--quiet', '--target=m68k-amigaos', '--mode=macros',
'--output=' + inline, source)
2015-09-08 07:44:46 +00:00
info('sfdc: "%s" -> "%s"', source, lvo)
2015-09-07 21:09:43 +00:00
execute('sfdc', '--quiet', '--target=m68k-amigaos', '--mode=lvo',
'--output=' + lvo, source)
elif kind == 'stubs':
filename = f[1]
2016-04-16 07:22:28 +00:00
c_file = re.sub(r'_lib\.sfd$', r'.c', path.basename(filename))
2015-09-07 21:09:43 +00:00
2015-09-08 07:44:46 +00:00
info('stubs: "%s" -> "%s"', filename, c_file)
2015-09-07 21:09:43 +00:00
execute('sfdc', '--quiet', '--target=m68k-amigaos', '--mode=autoopen',
'--output=' + c_file, filename)
2017-02-18 13:57:07 +00:00
# remove d0 from clobber since it's the return value, also remove __inline
execute('perl', '-pi', '-e', 's/: \\"d0\\",/:/g', c_file)
execute('perl', '-pi', '-e', 's/__inline//g', c_file)
2015-09-07 21:09:43 +00:00
add_stubs(c_file)
elif kind == 'lib':
filename = f[1]
2015-09-08 07:44:46 +00:00
c_file = re.sub(r'_lib.sfd$', r'.c', path.basename(filename))
2017-01-11 21:34:35 +00:00
lib_file = 'lib' + lib_name + '.a'
2015-09-07 21:09:43 +00:00
info('lib: %s -> %s', filename, c_file)
execute('sfdc', '--quiet', '--target=m68k-amigaos', '--mode=stubs',
'--output=' + c_file, filename)
2017-02-18 13:57:07 +00:00
# remove d0 from clobber since it's the return value, also remove __inline
execute('perl', '-pi', '-e', 's/: \\"d0\\",/:/g', c_file)
execute('perl', '-pi', '-e', 's/__inline//g', c_file)
2015-09-08 07:44:46 +00:00
add_lib(c_file, lib_file)
2015-09-07 21:09:43 +00:00
elif kind == 'file':
source = f[1]
try:
name = f[2]
except:
name = path.basename(f[1])
if any(name.endswith(ext) for ext in ['.doc', '.html', '.pdf', '.ps']):
2016-10-09 11:02:15 +00:00
copy(source, path.join('{prefix}/{target}/doc', name))
2015-09-07 21:09:43 +00:00
elif name.endswith('.guide'):
2016-10-09 11:02:15 +00:00
copy(source, path.join('{prefix}/{target}/guide', name))
2015-09-07 21:09:43 +00:00
elif any(name.endswith(ext) for ext in ['.h', '.i']):
lastdir = path.basename(path.dirname(f[1]))
2017-01-18 20:29:30 +00:00
mkdir(path.join('{prefix}/{target}/include', lastdir))
copy(source, path.join('{prefix}/{target}/include', lastdir, name))
2015-09-07 21:09:43 +00:00
elif name.endswith('.fd'):
2017-01-18 20:29:30 +00:00
copy(source, path.join('{prefix}/{target}/lib/fd', name))
2015-09-07 21:09:43 +00:00
elif name.endswith('.sfd'):
2017-01-18 20:29:30 +00:00
copy(source, path.join('{prefix}/{target}/lib/sfd', name))
2015-09-07 21:09:43 +00:00
def install_sdk(*names):
2017-03-22 19:35:41 +00:00
environ['PATH'] = ":".join([path.join('{prefix}', 'bin'),
2015-09-07 21:09:43 +00:00
path.join('{host}', 'bin'),
environ['PATH']])
2015-09-08 07:12:48 +00:00
add_site_dir('{host}')
2017-01-18 20:29:30 +00:00
with cwd('{prefix}/{target}'):
mkdir('doc', 'guide', 'include/proto', 'include/inline', 'include/lvo',
'lib/fd', 'lib/sfd')
for d, _ in MULTILIB:
mkdir(path.join('lib', d))
2015-09-07 21:09:43 +00:00
for name in names:
filename = path.join('{top}/sdk', name + '.sdk')
if not path.exists(filename):
panic('No SDK description file for "%s".', name)
desc, files = read_sdk(filename)
2017-01-11 21:34:35 +00:00
pkg = name + '-' + desc['version']
_, ext = path.splitext(path.basename(desc['url']))
2015-09-07 21:09:43 +00:00
with cwd('{archives}'):
2017-01-11 21:34:35 +00:00
fetch(pkg + ext, desc['url'])
2015-09-07 21:09:43 +00:00
2017-01-11 21:34:35 +00:00
unpack(pkg, top_dir='.')
2015-09-07 21:09:43 +00:00
2017-01-11 21:34:35 +00:00
if path.isdir(path.join('{patches}', pkg)):
patch(pkg, work_dir=path.join('{sources}', pkg))
2015-09-07 21:09:43 +00:00
2017-01-11 21:34:35 +00:00
process_sdk(pkg, name, files)
2015-09-07 21:09:43 +00:00
2016-05-10 08:49:38 +00:00
def test():
install_sdk('mmu', 'mui')
2017-03-22 19:35:41 +00:00
environ['PATH'] = ":".join([path.join('{prefix}', 'bin'),
2016-05-10 08:49:38 +00:00
environ['PATH']])
with cwd(path.join('{top}', 'examples')):
execute('make', 'clean')
execute('make')
2015-08-23 20:28:40 +00:00
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG, format='%(levelname)s: %(message)s')
2015-08-31 06:29:07 +00:00
if not sys.version_info[:2] == (2, 7):
panic('I need Python 2.7 to run!')
2016-10-01 13:40:03 +00:00
if not any(fnmatch(platform.system(), pat)
for pat in ['Darwin', 'Linux', 'CYGWIN_NT*', 'MSYS_NT*']):
2015-08-31 06:29:07 +00:00
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())
2017-09-06 06:03:54 +00:00
parser = argparse.ArgumentParser(description='Build cross toolchain.', formatter_class=RawTextHelpFormatter)
2015-09-07 21:09:43 +00:00
parser.add_argument('action',
2017-03-22 19:35:41 +00:00
choices=['build', 'xbuild', 'list-sdk', 'install-sdk', 'clean',
2017-02-18 17:18:42 +00:00
'test', 'update', 'download'],
2017-09-06 06:03:54 +00:00
default='build', help='\n'
'build: download, update and build the tool chain (use --threads n to speed up the build)\n'
'xbuild: build the tool chain (use --threads n to speed up the build)\n'
'clean: remove the build artifacts\n'
'update: updates the submodules using git\n'
'download: download the archives\n'
'list-sdk: list the available sdks\n'
'install-sdk: install the specified sdk\n'
'test: build mui and mmu sdk, then build the example files\n'
'\n')
2015-09-07 21:09:43 +00:00
parser.add_argument('args', metavar='ARGS', type=str, nargs='*',
help='action arguments')
2017-01-31 19:53:22 +00:00
parser.add_argument('--binutils', choices=['2.9.1', '2.14'], default='2.14',
2015-08-23 20:28:40 +00:00
help='desired binutils version')
2017-01-31 19:53:22 +00:00
parser.add_argument('--gcc', choices=['2.95.3', '3.4.6', '6'], default='6',
2015-08-23 20:28:40 +00:00
help='desired gcc version')
2017-03-22 19:35:41 +00:00
parser.add_argument('-q', '--quiet', action='store_true')
2015-08-23 20:28:40 +00:00
parser.add_argument('--prefix', type=str, default=None,
help='installation directory')
2017-01-31 19:53:22 +00:00
parser.add_argument('--threads', type=str, default='1',
help='number of threads for make')
2017-03-24 16:07:50 +00:00
parser.add_argument('--nodeps', action='store_true', help='disable dependency checking')
2017-03-27 19:05:45 +00:00
parser.add_argument('--m32', action='store_true', help='force compiling with 32bit (add -m32)')
2017-06-20 17:16:04 +00:00
parser.add_argument('--mytools', action='store_true', help='do not build tools (m4, gawk, flex, bison, automake, autoconf, texinfo), use the installed ones')
2015-08-23 20:28:40 +00:00
args = parser.parse_args()
setvar(top=path.abspath(path.dirname(sys.argv[0])),
binutils_ver=args.binutils,
2017-01-31 19:53:22 +00:00
gcc_ver=args.gcc,
numThreads=args.threads)
2017-09-06 06:03:54 +00:00
2015-09-08 07:12:48 +00:00
setvar(m4='m4-1.4.17',
2015-08-23 20:28:40 +00:00
gawk='gawk-3.1.8',
flex='flex-2.5.4',
bison='bison-1.35',
2016-10-02 10:41:41 +00:00
automake='automake-1.15',
2015-08-23 20:28:40 +00:00
autoconf='autoconf-2.13',
texinfo='texinfo-4.12',
NDK='NDK_3.9',
2018-01-25 13:24:31 +00:00
ixemul='ixemul',
2016-10-02 10:41:41 +00:00
clib2='clib2',
2015-08-23 20:28:40 +00:00
libm='libm-5.4',
2016-10-02 10:41:41 +00:00
libnix='libnix',
libamiga='libamiga',
2016-04-24 08:18:04 +00:00
libdebug='libdebug',
2015-08-23 20:28:40 +00:00
binutils='binutils-{binutils_ver}',
gcc='gcc-{gcc_ver}',
gpp='g++-{gcc_ver}',
2017-03-22 19:35:41 +00:00
target='m68k-amigaos',
2015-08-23 20:28:40 +00:00
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'),
2015-08-29 10:03:59 +00:00
tmpdir=path.join('{top}', '.build-m68k', 'tmp'),
2017-03-22 19:35:41 +00:00
prefix=path.join('{top}', 'm68k-amigaos'),
2016-10-02 10:41:41 +00:00
archives=path.join('{top}', '.build-m68k', 'archives'),
submodules=path.join('{top}', 'submodules'))
2015-08-23 20:28:40 +00:00
2017-03-22 19:35:41 +00:00
if args.quiet:
getLogger().setLevel(logging.INFO)
2015-08-23 20:28:40 +00:00
if args.prefix is not None:
2017-03-22 19:35:41 +00:00
setvar(prefix=args.prefix)
2015-08-23 20:28:40 +00:00
2017-03-22 19:35:41 +00:00
if not path.exists('{prefix}'):
mkdir('{prefix}')
2015-08-23 20:28:40 +00:00
2015-09-07 21:09:43 +00:00
action = args.action.replace('-', '_')
globals()[action].__call__(*args.args)