radare2/sys/meson.py

169 lines
5.5 KiB
Python

## Meson build for radare2
import argparse
import inspect
import logging
import os
import subprocess
import sys
ROOT = None
BUILDDIR = 'build'
MESON = None
PYTHON = None
BACKENDS = ['ninja', 'vs2015', 'vs2017']
log = None
def setGlobalVariables():
""" Set global variables """
global log
global ROOT
global MESON
global PYTHON
if os.name == 'posix':
cmd = 'which meson'
else:
cmd = 'where meson.py'
MESON = os.popen(cmd).read().split('\n')[0]
#if os.name == 'nt' and ' ' in MESON:
# MESON = '"{}"'.format(MESON)
PYTHON = sys.executable
#if os.name == 'nt' and ' ' in PYTHON:
# PYTHON = '"{}"'.format(PYTHON)
ROOT = os.path.abspath(inspect.getfile(inspect.currentframe()) +
os.path.join(os.path.pardir, os.path.pardir, os.path.pardir))
#if os.name == 'nt' and ' ' in ROOT:
# ROOT = '"{}"'.format(ROOT)
logging.basicConfig(format='[Meson][%(levelname)s]: %(message)s',
level=logging.DEBUG)
log = logging.getLogger('r2-meson')
log.debug('Root:{} Meson:{} Python:{}'.format(ROOT, MESON, PYTHON))
def meson(root, build, prefix=None, backend=None, release=False, shared=False):
""" Start meson build (i.e. python meson.py ./ build) """
command = [PYTHON, MESON, root, build]
if prefix:
command += ['--prefix={}'.format(prefix)]
if backend:
command += ['--backend={}'.format(backend)]
if release:
command += ['--buildtype=release']
if shared:
command += ['--default-library', 'shared']
else:
command += ['--default-library', 'static']
log.debug('Invoking meson: {}'.format(command))
ret = subprocess.call(command)
if ret != 0:
log.error('Meson error. Exiting.')
sys.exit(1)
def ninja(folder):
""" Start ninja build (i.e. ninja -C build) """
command = ['ninja', '-C', os.path.join(ROOT, folder)]
log.debug('Invoking ninja: {}'.format(command))
ret = subprocess.call(command)
if ret != 0:
log.error('Ninja error. Exiting.')
sys.exit(1)
def build_sdb(args):
""" Build and generate sdb files """
log.info('Building SDB')
log.debug('TODO Merge scripts')
return os.system('{python} {path}'.format(python=PYTHON,
path=os.path.join(ROOT, 'sys', 'meson_sdb.py')))
def build_r2(args):
""" Build radare2 """
log.info('Building radare2')
if args.backend != 'ninja':
if not os.path.exists(args.dir):
meson(ROOT, args.dir, args.prefix, args.backend, args.release,
args.shared)
if args.xp:
log.info('Running XP compat script')
log.debug('TODO Merge this script')
meson_extra = os.path.join(ROOT, 'sys', 'meson_extra.py')
os.system('python {meson_extra}'.format(meson_extra=meson_extra))
if not args.project:
log.info('Starting msbuild')
project = os.path.join(ROOT, args.dir, 'radare2.sln')
subprocess.call(['msbuild', project])
else:
if not os.path.exists(args.dir):
meson(ROOT, args.dir, args.prefix, args.backend, args.release,
args.shared)
ninja(args.dir)
def build(args):
""" Prepare requirements and build radare2 """
# Prepare capstone
capstone_path = os.path.join(ROOT, 'shlr', 'capstone')
if not os.path.isdir(capstone_path):
log.info('Cloning capstone')
subprocess.call('git clone -b next --depth 10 https://github.com/aquynh/capstone.git'.split() + [capstone_path])
# Build radare2
build_r2(args)
# Build sdb
build_sdb(args)
def install(args):
""" Install radare2 """
log.warning('Install not implemented yet.')
return
# TODO
#if os.name == 'posix':
# os.system('DESTDIR="{destdir}" ninja -C {build} install'
# .format(destdir=destdir, build=args.dir))
def main():
# Create logger and get applications paths
setGlobalVariables()
# Create parser
parser = argparse.ArgumentParser(description='Mesonbuild scripts for radare2')
parser.add_argument('--project', action='store_true',
help='Create a visual studio project and do not build.')
parser.add_argument('--release', action='store_true',
help='Set the build as Release (remove debug info)')
parser.add_argument('--backend', action='store', choices=BACKENDS,
default='ninja', help='Choose build backend')
parser.add_argument('--shared', action='store_true',
help='Link dynamically (shared library) rather than statically')
parser.add_argument('--prefix', action='store', default=None,
help='Set project installation prefix (default: /usr/local)')
parser.add_argument('--install', action='store_true',
help='Install radare2 after building')
parser.add_argument('--dir', action='store', default=BUILDDIR,
help='Destination build directory (default: {})'.format(BUILDDIR),
required=False)
parser.add_argument('--xp', action='store_true',
help='Adds support for Windows XP')
args = parser.parse_args()
# Check arguments
if args.project and args.backend == 'ninja':
log.error('--project is not compatible with --backend ninja')
sys.exit(1)
if args.xp and args.backend == 'ninja':
log.error('--xp is not compatible with --backend ninja')
sys.exit(1)
# Build it!
log.debug('Arguments: {}'.format(args))
build(args)
if args.install:
install(args)
if __name__ == '__main__':
main()