Build Python Bindings with meson

This commit is contained in:
Florian Märkl 2019-02-17 14:51:31 +01:00
parent aaf88e85aa
commit 804bd5ef08
6 changed files with 80 additions and 9 deletions

View File

@ -20,7 +20,7 @@ for name, value in vars.items():
pattern = "\\$\\$({}|\\{{{}\\}})".format(name, name) pattern = "\\$\\$({}|\\{{{}\\}})".format(name, name)
print(pattern) print(pattern)
content = re.sub(pattern, re.escape(str(value)), content) content = re.sub(pattern, str(value), content)
with open(out_filename, "w") as f: with open(out_filename, "w") as f:
f.write(content) f.write(content)

View File

@ -0,0 +1,12 @@
# 😠 https://github.com/mesonbuild/meson/issues/2320
bindings_src_files = run_command([py3_exe,
join_paths(meson.current_source_dir(), '../src_list.py'),
'meson']).stdout().split(';')
bindings_target = custom_target('bindings',
input: bindings_txt,
depend_files: [bindings_h, bindings_xml],
output: bindings_src_files,
command: [shiboken_exe, '--project-file=@INPUT@'])

20
src/bindings/meson.build Normal file
View File

@ -0,0 +1,20 @@
bindings_xml = configure_file(input: 'bindings.xml',
output: 'bindings.xml',
copy: true)
conf_json = '''{"BINDINGS_SRC_DIR":"@0@",
"BINDINGS_BUILD_DIR":"@1@",
"BINDINGS_INCLUDE_DIRS":"@2@",
"PYSIDE_TYPESYSTEMS":"@3@"}'''.format(
meson.current_source_dir(),
meson.current_build_dir(),
':'.join(bindings_generate_inc),
pyside_dep.get_pkgconfig_variable('typesystemdir'))
bindings_txt = configure_file(input: 'bindings.txt.in',
output: 'bindings.txt',
command: configure_qmake_cmd + ['@INPUT@', '@OUTPUT0@', conf_json])
bindings_h = files('bindings.h')
subdir('CutterBindings')

17
src/bindings/src_list.py Executable file → Normal file
View File

@ -8,7 +8,7 @@ import sys
script_path = os.path.dirname(os.path.realpath(__file__)) script_path = os.path.dirname(os.path.realpath(__file__))
def get_cpp_files_gen(args): def get_cpp_files_gen(args, include_package=True):
ts_tree = et.parse(os.path.join(script_path, "bindings.xml")) ts_tree = et.parse(os.path.join(script_path, "bindings.xml"))
ts_root = ts_tree.getroot() ts_root = ts_tree.getroot()
@ -20,10 +20,13 @@ def get_cpp_files_gen(args):
cpp_files_gen = [f"{package.lower()}_module_wrapper.cpp"] cpp_files_gen = [f"{package.lower()}_module_wrapper.cpp"]
cpp_files_gen.extend([f"{typename.lower()}_wrapper.cpp" for typename in types]) cpp_files_gen.extend([f"{typename.lower()}_wrapper.cpp" for typename in types])
if include_package:
cpp_files_gen = [os.path.join(package, f) for f in cpp_files_gen]
if len(args) > 0: if len(args) > 0:
return [os.path.join(args[0], package, f) for f in cpp_files_gen] cpp_files_gen = [os.path.join(args[0], f) for f in cpp_files_gen]
else:
return [os.path.join(package, f) for f in cpp_files_gen] return cpp_files_gen
def cmd_cmake(args): def cmd_cmake(args):
@ -34,7 +37,11 @@ def cmd_qmake(args):
sys.stdout.write("\n".join(get_cpp_files_gen(args)) + "\n") sys.stdout.write("\n".join(get_cpp_files_gen(args)) + "\n")
cmds = {"cmake": cmd_cmake, "qmake": cmd_qmake} def cmd_meson(args):
sys.stdout.write(";".join(get_cpp_files_gen(args, include_package=False)))
cmds = {"cmake": cmd_cmake, "qmake": cmd_qmake, "meson": cmd_meson}
if len(sys.argv) < 2 or sys.argv[1] not in cmds: if len(sys.argv) < 2 or sys.argv[1] not in cmds:
print(f"""usage: {sys.argv[0]} [{"/".join(cmds.keys())}] [base path]""") print(f"""usage: {sys.argv[0]} [{"/".join(cmds.keys())}] [base path]""")

View File

@ -8,6 +8,12 @@ feature_define_args = []
if get_option('enable_python') if get_option('enable_python')
message('Python is enabled') message('Python is enabled')
feature_define_args += ['-DCUTTER_ENABLE_PYTHON'] feature_define_args += ['-DCUTTER_ENABLE_PYTHON']
if get_option('enable_python_bindings')
message('Python Bindings are enabled')
feature_define_args += ['-DCUTTER_ENABLE_PYTHON_BINDINGS']
endif
if get_option('enable_jupyter') if get_option('enable_jupyter')
message('Jupyter support enabled') message('Jupyter support enabled')
feature_define_args += ['-DCUTTER_ENABLE_JUPYTER'] feature_define_args += ['-DCUTTER_ENABLE_JUPYTER']
@ -22,6 +28,7 @@ endif
add_project_arguments(feature_define_args, language: 'cpp') add_project_arguments(feature_define_args, language: 'cpp')
parse_cmd = [py3_exe, join_paths(meson.current_source_dir(), '../scripts/meson_parse_qmake.py')] parse_cmd = [py3_exe, join_paths(meson.current_source_dir(), '../scripts/meson_parse_qmake.py')]
configure_qmake_cmd = [py3_exe, join_paths(meson.current_source_dir(), '../scripts/meson_configure_qmake_in.py')]
qt_modules += run_command(parse_cmd + ['QT'], check: true).stdout().split(';') qt_modules += run_command(parse_cmd + ['QT'], check: true).stdout().split(';')
sources = run_command(parse_cmd + ['SOURCES'], check: true).stdout().split(';') sources = run_command(parse_cmd + ['SOURCES'], check: true).stdout().split(';')
@ -38,7 +45,7 @@ conf_json = '''{"CUTTER_VERSION_MAJOR":@0@,
version_major, version_minor, version_patch) version_major, version_minor, version_patch)
configure_file(input: 'CutterConfig.h.in', configure_file(input: 'CutterConfig.h.in',
output: 'CutterConfig.h', output: 'CutterConfig.h',
command: [py3_exe, join_paths(meson.current_source_dir(), '../scripts/meson_configure_qmake_in.py'), '@INPUT@', '@OUTPUT0@', conf_json]) command: configure_qmake_cmd + ['@INPUT@', '@OUTPUT0@', conf_json])
conf_inc = include_directories('.') conf_inc = include_directories('.')
sp_dir = join_paths(meson.source_root(), 'subprojects') sp_dir = join_paths(meson.source_root(), 'subprojects')
@ -64,7 +71,31 @@ qt5dep = dependency('qt5', modules: qt_modules)
deps = [libr2_dep, qt5dep] deps = [libr2_dep, qt5dep]
if get_option('enable_python') if get_option('enable_python')
deps += [dependency('python3')] py3_dep = dependency('python3')
deps += [py3_dep]
if get_option('enable_python_bindings')
shiboken_dep = dependency('shiboken2', method: 'pkg-config')
pyside_dep = dependency('pyside2', method: 'pkg-config')
pyside_inc_dep = declare_dependency(include_directories: include_directories(join_paths(pyside_dep.get_pkgconfig_variable('includedir'), 'QtCore'),
join_paths(pyside_dep.get_pkgconfig_variable('includedir'), 'QtGui'),
join_paths(pyside_dep.get_pkgconfig_variable('includedir'), 'QtWidgets')))
deps += [shiboken_dep, pyside_dep, pyside_inc_dep]
shiboken_exe = shiboken_dep.get_pkgconfig_variable('generator_location')
qt5core_dep = dependency('Qt5Core', method: 'pkg-config')
bindings_generate_inc = [meson.current_source_dir(),
join_paths(meson.current_source_dir(), 'common'),
join_paths(meson.current_source_dir(), 'widgets'),
join_paths(meson.current_source_dir(), 'plugins'),
join_paths(meson.current_source_dir(), 'subprojects/radare2/libr/include'),
join_paths(meson.current_build_dir(), 'subprojects/radare2'),
qt5core_dep.get_pkgconfig_variable('includedir'),
join_paths(qt5core_dep.get_pkgconfig_variable('includedir'), 'QtCore'),
join_paths(qt5core_dep.get_pkgconfig_variable('includedir'), 'QtGui'),
join_paths(qt5core_dep.get_pkgconfig_variable('includedir'), 'QtWidgets')]
message('bindings_inc: @0@'.format(bindings_generate_inc))
subdir('bindings')
sources += bindings_target
endif
endif endif
moc_files = qt5_mod.preprocess( moc_files = qt5_mod.preprocess(
@ -96,6 +127,6 @@ cutter_exe = executable(
moc_files, moc_files,
gui_app: true, gui_app: true,
sources: sources, sources: sources,
include_directories: [platform_inc, conf_inc], include_directories: [include_directories('common', 'widgets', 'plugins'), platform_inc, conf_inc],
dependencies: deps, dependencies: deps,
) )

View File

@ -1,3 +1,4 @@
option('enable_python', type: 'boolean', value: true) option('enable_python', type: 'boolean', value: true)
option('enable_python_bindings', type: 'boolean', value: true)
option('enable_jupyter', type: 'boolean', value: false) option('enable_jupyter', type: 'boolean', value: false)
option('enable_webengine', type: 'boolean', value: false) option('enable_webengine', type: 'boolean', value: false)