diff --git a/include/meson.build b/include/meson.build new file mode 100644 index 00000000..e97c447a --- /dev/null +++ b/include/meson.build @@ -0,0 +1,23 @@ +conf_data = configuration_data() +conf_data.set('PROJECT_VERSION', meson.project_version()) +al_defs_h = configure_file(input: 'al_defs.h.in', output: 'al_defs.h', configuration: conf_data) + +public_headers = files( + 'access_layer_base_plugin.h', + 'access_layer_plugin.h', + 'access_layer_plugin_manager.h', + 'al_backend.h', + 'al_const.h', + 'al_context.h', + 'al_exception.h', + 'al_lowlevel.h', + 'data_interpolation.h', + 'extended_access_layer_plugin.h', + 'provenance_plugin_feature.h', + 'readback_plugin_feature.h', + 'uri_parser.h', +) + al_defs_h + +# Include both source include directory and build include directory +public_includes = include_directories('.') +install_headers(public_headers, subdir: 'al_core') \ No newline at end of file diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..7b8f343a --- /dev/null +++ b/meson.build @@ -0,0 +1,100 @@ +project( + 'imas-core', + ['c', 'cpp'], + license: 'LGPL-3.0-or-later', + meson_version: '>=1.1.0', + version: run_command( + 'python', '-m', 'setuptools_scm', '--strip-dev', + check: true + ).stdout().strip(), + default_options: [ + 'c_std=c17', + 'cpp_std=c++17', + 'buildtype=debugoptimized', + ], +) + +# ============================================================================= +# Compiler and System Setup +# ============================================================================= +cc = meson.get_compiler('c') +cxx = meson.get_compiler('cpp') +host_system = host_machine.system() +host_cpu = host_machine.cpu_family() + +# ============================================================================= +# Access Layer core (al-core) Library +# ============================================================================= +if get_option('al_core') + subdir('include') + subdir('src') +else + # Use external al-core installation + al_core_dep = dependency('al-core', required: true) +endif + +# ============================================================================= +# Dummy Executable for version printing +# ============================================================================= +if get_option('al_dummy_exe') + imas_print_version = executable( + 'imas_print_version', + 'tests/imas_print_version.cpp', + dependencies: [al_core_dep], + install: true, + ) + test('imas_print_version_test', imas_print_version) +endif + +# ============================================================================= +# Test Low-level C API (al-core) +# ============================================================================= +if get_option('al_test') + # subdir('tests') # TODO: fix test sources +endif + +# ============================================================================= +# Python Bindings (imas-core) +# ============================================================================= +if get_option('python_bindings') + subdir('python') +endif + +# ============================================================================= +# MDSplus Models +# ============================================================================= +if get_option('mdsplus_models') + warning('MDSplus models are not yet supported in Meson build system.') + # subdir('models/mdsplus') +endif + +# ============================================================================= +# Summary +# ============================================================================= +if get_option('al_core') + summary( + { + 'HDF5': get_option('al_backend_hdf5'), + 'UDA': get_option('al_backend_uda'), + 'MDSplus': get_option('al_backend_mdsplus'), + }, + section: 'Backends', + ) + summary( + { + 'C++ Arguments': al_core_cpp_args, + }, + section: 'Compiler Arguments', + ) +endif + +if get_option('python_bindings') + summary( + { + 'Python Version': py.language_version(), + 'Buildtime Python Path': py.full_path(), + 'Cython Arguments': cython_args, + }, + section: 'Python Bindings', + ) +endif \ No newline at end of file diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 00000000..121be22d --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,63 @@ +# ============================================================================= +# Libraries to build +# ============================================================================= + +option( + 'al_core', + type: 'boolean', + value: true, + description: 'Build internal core library, or use external installation', +) + +option( + 'al_dummy_exe', + type: 'boolean', + value: false, + description: 'Build dummy executable that prints version information.', +) + +option( + 'al_test', + type: 'boolean', + value: false, + description: 'Build tests for al-core library', +) + +option( + 'python_bindings', + type: 'boolean', + value: true, + description: 'Build Python wrapper', +) + +option( + 'mdsplus_models', + type: 'boolean', + value: false, + description: 'Build MDSplus models (requires MDSplus installation)', +) + +# ============================================================================= +# Backends Options +# ============================================================================= + +option( + 'al_backend_hdf5', + type: 'boolean', + value: true, + description: 'Enable HDF5 backend', +) + +option( + 'al_backend_uda', + type: 'boolean', + value: true, + description: 'Enable UDA backend', +) + +option( + 'al_backend_mdsplus', + type: 'boolean', + value: false, + description: 'Enable MDSplus backend', +) \ No newline at end of file diff --git a/python/_version.py.in b/python/_version.py.in new file mode 100644 index 00000000..de6f4d49 --- /dev/null +++ b/python/_version.py.in @@ -0,0 +1,31 @@ +__all__ = [ + "__version__", + "__version_tuple__", + "version", + "version_tuple", + "__commit_id__", + "commit_id", +] + +TYPE_CHECKING = False +if TYPE_CHECKING: + from typing import Tuple + from typing import Union + + VERSION_TUPLE = Tuple[Union[int, str], ...] + COMMIT_ID = Union[str, None] +else: + VERSION_TUPLE = object + COMMIT_ID = object + +version: str +__version__: str +__version_tuple__: VERSION_TUPLE +version_tuple: VERSION_TUPLE +commit_id: COMMIT_ID +__commit_id__: COMMIT_ID + +__version__ = version = "@VERSION@" +__version_tuple__ = version_tuple = @VERSION_TUPLE@ + +__commit_id__ = commit_id = "@COMMIT_ID@" diff --git a/python/meson.build b/python/meson.build new file mode 100644 index 00000000..cf40858f --- /dev/null +++ b/python/meson.build @@ -0,0 +1,78 @@ +add_languages('cython', native: false) + +# ============================================================================= +# Version File +# ============================================================================= +# Get version using setuptools-scm +version = run_command('python', '-m', 'setuptools_scm', check: true).stdout().strip() + +# Create tuple: split version like "5.5.2", ignoring dirty suffix etc. +split_ver = version.split('.') +ver_tuple = '(@0@, @1@, @2@)'.format( + split_ver[0], + split_ver[1], + split_ver[2], +) + +# Get commit id +git_commit = run_command('git', 'rev-parse', '--short', 'HEAD', check: false).stdout().strip() + +if git_commit == '' + git_commit = 'None' +endif + +# Generate _version.py +version_file = configure_file( + input: '_version.py.in', + output: '_version.py', + configuration: { + 'VERSION': version, + 'VERSION_TUPLE': ver_tuple, + 'COMMIT_ID': git_commit, + }, +) + +# ============================================================================= +# Modules and Dependencies +# ============================================================================= +fs = import('fs') +py = import('python').find_installation(pure: false) +py_dep = dependency('python3', native: false) +numpy_dep = dependency('numpy') + +cython_args = ['--annotate'] + +# ============================================================================= +# Source files +# ============================================================================= +py_files = files( + 'imas_core/__init__.py', + 'imas_core/exception.py', + 'imas_core/imasdef.py', +) +pyx_files = files( + 'imas_core/_al_lowlevel.pyx', + 'imas_core/al_defs.pyx', +) +pxd_files = files( + 'imas_core/al_defs.pxd', + 'imas_core/al_lowlevel_interface.pxd', +) + +# ============================================================================= +# Build Python Extension Module +# ============================================================================= +# compile cython +foreach pyx_file : pyx_files + py.extension_module( + fs.stem(pyx_file), + pyx_file, + cython_args: cython_args, + dependencies: [al_core_dep, py_dep, numpy_dep], + install: true, + subdir: 'imas_core', + ) +endforeach + +# Install pure python files +py.install_sources(py_files + pxd_files + version_file, subdir: 'imas_core') \ No newline at end of file diff --git a/src/hdf5/meson.build b/src/hdf5/meson.build new file mode 100644 index 00000000..7bd9d167 --- /dev/null +++ b/src/hdf5/meson.build @@ -0,0 +1,20 @@ +hdf5_backend_sources = files( + 'hdf5_backend.cpp', + 'hdf5_backend_factory.cpp', + 'hdf5_dataset_handler.cpp', + 'hdf5_events_handler.cpp', + 'hdf5_hs_selection_reader.cpp', + 'hdf5_hs_selection_writer.cpp', + 'hdf5_reader.cpp', + 'hdf5_utils.cpp', + 'hdf5_writer.cpp', +) + +private_includes += [include_directories('.')] + +core_deps += dependency('hdf5', language: 'c', required: true) + +al_core_cpp_args += '-DHDF5' + +# Add HDF5 backend sources +al_core_sources += hdf5_backend_sources \ No newline at end of file diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 00000000..0b74ea9b --- /dev/null +++ b/src/meson.build @@ -0,0 +1,89 @@ +# AL-Core Library + +al_core_sources = files( + 'access_layer_plugin_manager.cpp', + 'al_backend.cpp', + 'al_const.cpp', + 'al_context.cpp', + 'al_exception.cpp', + 'al_lowlevel.cpp', + 'ascii_backend.cpp', + 'data_interpolation.cpp', + 'flexbuffers_backend.cpp', + 'memory_backend.cpp', + 'no_backend.cpp', +) + +private_includes = [include_directories('.')] + +# Enable ASCII backend +al_core_cpp_args = [ + '-DASCII', +] + +# ============================================================================= +# Dependencies +# ============================================================================= +boost_dep = dependency('boost', modules: ['filesystem'], required: false) +if not boost_dep.found() + boost_dep = cxx.find_library('boost_filesystem', required: true) +endif + +core_deps = [ + boost_dep, +] + +if host_system == 'windows' + core_deps += [ + cxx.find_library('pthreads', required: true), + dependency('dlfcn-win32', modules: ['dlfcn-win32::dl'], method: 'cmake', required: true), + ] +endif + +# ============================================================================= +# Add Optional Backends +# ============================================================================= +if get_option('al_backend_mdsplus') + warning('MDSplus backend is not yet supported in Meson build system.') + # subdir('mdsplus') +endif + +if get_option('al_backend_hdf5') + subdir('hdf5') +endif + +if get_option('al_backend_uda') + subdir('uda') +endif + +# ============================================================================= +# Library +# ============================================================================= +al_core = library( + 'al', + al_core_sources, + cpp_args: al_core_cpp_args, + include_directories: private_includes + public_includes, + dependencies: core_deps, + version: meson.project_version(), + install: true, +) + +# Declare dependency for other libraries to use +al_core_dep = declare_dependency( + link_with: al_core, + include_directories: public_includes, +) + +# ============================================================================= +# Package Configuration +# ============================================================================= +pkg = import('pkgconfig') +pkg.generate( + libraries: al_core, + subdirs: ['al_core'], + name: 'al-core', + description: 'IMAS Access Layer core libraries for C', + url: 'https://github.com/iterorganization/IMAS-Core', + version: meson.project_version(), +) \ No newline at end of file diff --git a/src/uda/meson.build b/src/uda/meson.build new file mode 100644 index 00000000..b830c626 --- /dev/null +++ b/src/uda/meson.build @@ -0,0 +1,42 @@ +uda_backend_sources = files( + 'pugixml.cpp', + 'uda_backend.cpp', + 'uda_cache.cpp', + 'uda_path.cpp', + 'uda_xml.cpp', +) + +private_includes += [include_directories('.')] + +uda_client_dep = dependency('uda-client', required: false) +uda_cpp_dep = dependency('uda-cpp', required: false) + +uda_fat_client_dep = dependency('uda-fat-client', required: false) +uda_fat_cpp_dep = dependency('uda-fat-cpp', required: false) + +if not uda_cpp_dep.found() and not uda_fat_cpp_dep.found() + error('UDA backend requested but UDA dependency not found.') +endif + +if uda_cpp_dep.found() + core_deps += [uda_cpp_dep, uda_client_dep] + if uda_cpp_dep.version().version_compare('>=2.7.6') + al_core_cpp_args += ['-DUDA', '-DUDA_LEGACY_276', '-DUDA_CLIENT_FLAGS_API'] + else + al_core_cpp_args += ['-DUDA'] + endif +endif + +if uda_fat_cpp_dep.found() + core_deps += [uda_fat_cpp_dep, uda_fat_client_dep] + if uda_fat_cpp_dep.version().version_compare('>=2.7.6') + al_core_cpp_args += ['-DUDA', '-DUDA_LEGACY_276', '-DUDA_CLIENT_FLAGS_API'] + else + al_core_cpp_args += ['-DUDA'] + endif +endif + +# Add UDA backend sources if UDA dependency is found +if uda_cpp_dep.found() or uda_fat_cpp_dep.found() + al_core_sources += uda_backend_sources +endif \ No newline at end of file diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 00000000..5a15e68d --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,27 @@ +# Test executables for AL-Core + +# ============================================================================= +# Test executables +# ============================================================================= + +# C++ test executable +testlowlevel = executable( + 'testlowlevel', + 'testlowlevel.cpp', + dependencies: [al_core_dep], + cpp_args: ['-DNOIMPLIB'], + install: true, +) + +# C test executable +testlowlevel_c = executable( + 'testlowlevel_c', + 'testlowlevel_c.c', + dependencies: [al_core_dep], + c_args: ['-DNOIMPLIB'], + install: true, +) + +# Test cases +test('Test lowlevel C++', testlowlevel) +test('Test lowlevel C', testlowlevel_c) \ No newline at end of file