From e4aec07f01311838bea640c7c88e1f5bbe93e916 Mon Sep 17 00:00:00 2001 From: Paul I Date: Sun, 22 Jul 2018 15:10:52 +0300 Subject: [PATCH] Meson: move some code from meson.py to src/meson.build (#588) --- meson.py | 57 ------------------------------------ scripts/meson_parse_qmake.py | 32 ++++++++++++++++++++ src/meson.build | 57 ++++++++++++++++++++++++------------ src/meson_options.txt | 7 ----- 4 files changed, 70 insertions(+), 83 deletions(-) create mode 100644 scripts/meson_parse_qmake.py diff --git a/meson.py b/meson.py index 9301f811..91ff119d 100644 --- a/meson.py +++ b/meson.py @@ -6,9 +6,6 @@ import pprint import subprocess import sys -VARS = {'QT':[], 'SOURCES':[], 'HEADERS':[], 'FORMS':[], 'RESOURCES':[], - 'VERSION':[], 'ICON':[]} - ROOT = None log = None r2_meson_mod = None @@ -35,34 +32,6 @@ def set_global_vars(): r2_meson_mod.set_global_variables() -def parse_qmake_file(): - log.info('Parsing qmake file') - with open(os.path.join(ROOT, 'src', 'Cutter.pro')) as qmake_file: - lines = qmake_file.readlines() - var_name = None - end_of_def = True - for line in lines: - words = line.split() - if not words: - continue - if words[0].startswith('#'): - continue - if not var_name and words[0] in VARS: - var_name = words[0] - words = words[2:] - if not var_name: - continue - end_of_def = words[-1] != '\\' - if not end_of_def: - words = words[:-1] - for word in words: - VARS[var_name].append(word) - if end_of_def: - var_name = None - qt_mod_translation = { "webenginewidgets": "WebEngineWidgets" } - VARS['QT'] = list(map(lambda s: qt_mod_translation.get(s, str.title(s)), VARS['QT'])) - log.debug('Variables: \n%s', pprint.pformat(VARS, compact=True)) - def win_dist(args): build = os.path.join(ROOT, args.dir) dist = os.path.join(ROOT, args.dist) @@ -77,16 +46,8 @@ def win_dist(args): def build(args): cutter_builddir = os.path.join(ROOT, args.dir) - if not args.webengine: - VARS['QT'].remove('WebEngineWidgets') if not os.path.exists(cutter_builddir): defines = [] - defines.append('-Dversion=%s' % VARS['VERSION'][0]) - defines.append('-Dqt_modules=%s' % ','.join(VARS['QT'])) - defines.append('-Dsources=%s' % ','.join(VARS['SOURCES'])) - defines.append('-Dheaders=%s' % ','.join(VARS['HEADERS'])) - defines.append('-Dui_files=%s' % ','.join(VARS['FORMS'])) - defines.append('-Dqresources=%s' % ','.join(VARS['RESOURCES'])) defines.append('-Denable_jupyter=%s' % str(args.jupyter).lower()) defines.append('-Denable_webengine=%s' % str(args.webengine).lower()) if os.name == 'nt': @@ -103,21 +64,6 @@ def build(args): project = os.path.join(cutter_builddir, 'Cutter.sln') r2_meson_mod.msbuild(project, '/m') -def create_sp_dir(): - sp_dir = os.path.join(ROOT, 'src', 'subprojects') - sp_r2_dir = os.path.join(sp_dir, 'radare2') - if not os.path.exists(sp_r2_dir): - os.makedirs(sp_dir, exist_ok=True) - r2_dir = os.path.join(ROOT, 'radare2') - try: - os.symlink(r2_dir, sp_r2_dir, target_is_directory=True) - except OSError as e: - log.error('%s', e) - if os.name == 'nt': - log.info('Execute command as Administrator:\n' - 'MKLINK /D "%s" "%s"', sp_r2_dir, r2_dir) - sys.exit(1) - def main(): set_global_vars() @@ -140,9 +86,6 @@ def main(): log.debug('Arguments: %s', args) - create_sp_dir() - parse_qmake_file() - build(args) if hasattr(args, 'dist') and args.dist: diff --git a/scripts/meson_parse_qmake.py b/scripts/meson_parse_qmake.py new file mode 100644 index 00000000..2141dec3 --- /dev/null +++ b/scripts/meson_parse_qmake.py @@ -0,0 +1,32 @@ +import os +import sys + +name = sys.argv[1] +value = [] +if name not in ('QT', 'SOURCES', 'HEADERS', 'FORMS', 'RESOURCES', 'VERSION', 'ICON'): + sys.exit(1) +root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) +with open(os.path.join(root, 'src', 'Cutter.pro')) as f: + text = f.read() +text = text.replace('\\\n', '') +nbraces = 0 +for line in text.split('\n'): + line = line.strip() + if not line or all(char in line for char in ('{', '}')): + continue + if line.startswith('}'): + nbraces -= 1 + continue + if line.endswith('{'): + nbraces += 1 + continue + if nbraces > 0 or '=' not in line: + continue + words = line.split() + if words[0] == name and '=' in words[1]: + value.extend(words[2:]) +if name == 'QT': + value = [str.title(s) for s in value] +if not value: + sys.exit(1) +print(';'.join(value), end='') diff --git a/src/meson.build b/src/meson.build index db24f643..eeeb480a 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,6 +1,9 @@ -#TODO: icon -project('Cutter', 'cpp', default_options: 'cpp_std=c++11') +project('Cutter', 'cpp', default_options: 'cpp_std=c++11', meson_version: '>=0.47.0') +qt5_mod = import('qt5') +py3_exe = import('python3').find_python() + +qt_modules = [] feature_define_args = [] if get_option('enable_jupyter') message('Jupyter support enabled') @@ -10,21 +13,45 @@ if get_option('enable_jupyter') message('QtWebEngine support enabled') add_project_arguments('-DCUTTER_ENABLE_QTWEBENGINE', language: 'cpp') feature_define_args += ['-DCUTTER_ENABLE_QTWEBENGINE'] + qt_modules += 'WebEngineWidgets' endif endif -qt5_mod = import('qt5') +parse_cmd = [py3_exe, '../scripts/meson_parse_qmake.py'] -version = get_option('version') +qt_modules += run_command(parse_cmd + ['QT'], check: true).stdout().split(';') +sources = run_command(parse_cmd + ['SOURCES'], check: true).stdout().split(';') +headers = run_command(parse_cmd + ['HEADERS'], check: true).stdout().split(';') +ui_files = run_command(parse_cmd + ['FORMS'], check: true).stdout().split(';') +qresources = run_command(parse_cmd + ['RESOURCES'], check: true).stdout().split(';') +version = run_command(parse_cmd + ['VERSION'], check: true).stdout() -qt_modules = get_option('qt_modules') -sources = get_option('sources') -headers = get_option('headers') -ui_files = get_option('ui_files') -qresources = get_option('qresources') +sp_dir = join_paths(meson.source_root(), 'subprojects') +sp_r2_dir = join_paths(sp_dir, 'radare2') +exists_cmd = '__import__("sys").exit(__import__("os").path.exists("@0@"))'.format(sp_r2_dir) +if run_command(py3_exe, '-c', exists_cmd).returncode() == 0 + r2_src_dir = join_paths(meson.source_root(), '..', 'radare2') + if host_machine.system() == 'windows' + sp_dir = '\\'.join(sp_dir.split('/')) + sp_r2_dir = '\\'.join(sp_r2_dir.split('/')) + r2_src_dir = '\\'.join(r2_src_dir.split('/')) + link_cmd = ['CMD', '/C', 'MKDIR', sp_dir, '&', 'MKLINK', '/D', sp_r2_dir, r2_src_dir] + else + link_cmd = ['sh', '-c', 'mkdir @0@ ; ln -s @1@ @2@'.format(sp_dir, r2_src_dir, sp_r2_dir)] + endif + run_command(link_cmd, check: true) +endif + +r2 = subproject('radare2') +libr2_dep = r2.get_variable('libr2_dep') qt5dep = dependency('qt5', modules: qt_modules) +deps = [libr2_dep, qt5dep] +if get_option('enable_jupyter') + deps += [dependency('python3')] +endif + moc_files = qt5_mod.preprocess( moc_headers: headers, ui_files: ui_files, @@ -40,20 +67,12 @@ if host_machine.system() == 'windows' add_project_arguments('-D_CRT_SECURE_NO_WARNINGS', language: 'cpp') platform_inc = include_directories('../radare2/libr/include/msvc') # Workaround for https://github.com/mesonbuild/meson/issues/2327 - qt_lib = run_command('qmake', '-query', 'QT_HOST_LIBS').stdout().strip() - add_project_link_arguments(join_paths(qt_lib, 'qtmain.lib'), language: 'cpp') + qt_host_libs = run_command('qmake', '-query', 'QT_HOST_LIBS').stdout().strip() + add_project_link_arguments(join_paths(qt_host_libs, 'qtmain.lib'), language: 'cpp') endif add_project_arguments('-DAPP_VERSION="@0@"'.format(version), language: 'cpp') -r2 = subproject('radare2') -libr2_dep = r2.get_variable('libr2_dep') - -deps = [libr2_dep, qt5dep] -if get_option('enable_jupyter') - deps += [dependency('python3')] -endif - cutter_exe = executable( 'Cutter', moc_files, diff --git a/src/meson_options.txt b/src/meson_options.txt index 44d8152b..6bf9abbc 100644 --- a/src/meson_options.txt +++ b/src/meson_options.txt @@ -1,9 +1,2 @@ -option('version', type: 'string') -option('qt_modules', type: 'array') -option('sources', type: 'array') -option('headers', type: 'array') -option('ui_files', type: 'array') -option('qresources', type: 'array') - option('enable_jupyter', type: 'boolean', value: false) option('enable_webengine', type: 'boolean', value: false)