diff --git a/docs/source/user_guide/installation.rst b/docs/source/user_guide/installation.rst
index 3b72bdd0..a7b3081f 100644
--- a/docs/source/user_guide/installation.rst
+++ b/docs/source/user_guide/installation.rst
@@ -15,7 +15,7 @@ To install IMAS-Core via pip for Python users:
Requirements
~~~~~~~~~~~~
-- **Python 3.8+**
+- **Python 3.8+**
- **Linux** (fully supported)
- **macOS and Windows** (experimental - in testing)
@@ -60,9 +60,9 @@ The following dependencies are only required for some of the components:
- **UDA backend**: `UDA `__ libraries
(2.7.5 or newer) [#uda_install]_
-.. [#uda_install] When installing UDA, make sure you have
+.. [#uda_install] When installing UDA, make sure you have
`Cap'n'Proto `__ installed in your system
- and add its support by adding the CMake switch `-DENABLE_CAPNP=ON` when configuring UDA.
+ and add its support by adding the CMake switch `-DENABLE_CAPNP=ON` when configuring UDA.
Standard environments:
@@ -119,10 +119,10 @@ overview of configuration options.
cd IMAS-Core
cmake -B build -D CMAKE_INSTALL_PREFIX=$HOME/install -D OPTION1=VALUE1 -D OPTION2=VALUE2 [...]
-.. note::
+.. note::
CMake will automatically fetch dependencies from required repositories
- for you.
+ for you.
- `data-dictionary (git@github.com:iterorganization/IMAS-Data-Dictionary.git)
`__
@@ -131,7 +131,7 @@ overview of configuration options.
repository or to use a HTTPS URL instead of the default SSH URLs, you can update the
:ref:`configuration options`. For example, add the following options to your
``cmake`` command to download the repositories over HTTPS instead of SSH:
-
+
.. code-block:: text
:caption: Use explicit options to download dependent repositories over HTTPS
@@ -222,7 +222,7 @@ Configuration options
When ``AL_DOWNLOAD_DEPENDENCIES`` is enabled, the following settings can be used to
configure the location and/or version of the dependencies that should be used.
-
+
- ``AL_CORE_GIT_REPOSITORY``,
, ``DD_GIT_REPOSITORY``. Configure the git URLs
where the ``IMAS-Core`` c.q.
@@ -276,7 +276,7 @@ available configuration options, use the command-line tool ``ccmake`` or the gui
Build the IMAS-Core
~~~~~~~~~~~~~~~~~~~
-Use ``cmake`` to build as shown below.
+Use ``cmake`` to build as shown below.
.. code-block:: bash
@@ -359,9 +359,66 @@ can be passed using this method. The option names remain the same, but are prefi
``-C skbuild.cmake.define.``.
+Optional: Build IMAS-Core with Meson
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also build and install IMAS-Core using the Meson build system as an alternative to CMake. This can be useful for users who prefer Meson or want to try a different build workflow.
+
+First, ensure you have Meson and Ninja installed. You can install them with pip:
+
+.. code-block:: bash
+
+ pip install meson ninja
+
+Then, clone the IMAS-Core repository if you haven't already:
+
+.. code-block:: bash
+
+ git clone git@github.com:iterorganization/IMAS-Core.git
+ cd IMAS-Core
+
+Create a build directory and configure the project:
+
+.. code-block:: bash
+
+ meson setup builddir
+
+You can pass Meson options at this step. For example, to enable or disable backends:
+
+.. code-block:: bash
+
+ meson setup builddir -Dal_backend_hdf5=true -Dal_backend_uda=false
+
+To see all available options, run:
+
+.. code-block:: bash
+
+ meson configure builddir
+
+Build the project:
+
+.. code-block:: bash
+
+ meson compile -C builddir
+
+Install IMAS-Core (you may need sudo for system-wide installs):
+
+.. code-block:: bash
+
+ meson install -C builddir
+
+You can also run tests using Meson:
+
+.. code-block:: bash
+
+ meson test -C builddir
+
+For more information on Meson, see the official documentation: https://mesonbuild.com/
+
+
Optional: Test the IMAS-Core
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Following snippet shows how to run the test with pytest. Just ensure that you have
+Following snippet shows how to run the test with pytest. Just ensure that you have
AL_PYTHON_BINDINGS-ON in cmake configuration.
If you set either of the options ``AL_EXAMPLES`` or ``AL_TESTS`` to ``ON``, you can run
the corresponding test programs as follows:
@@ -371,7 +428,7 @@ the corresponding test programs as follows:
python3 -m venv build/pip_install
source build/pip_install/bin/activate
pip install --upgrade pip wheel
- pip install numpy
+ pip install numpy
set -x
pip install --find-links=build/dist imas-core[test,cov]
pytest --junitxml results.xml --cov imas_core --cov-report xml --cov-report html
@@ -393,7 +450,7 @@ Access Layer. To help you with this, a file ``al_env.sh`` is installed. You can
You may want to add this to your ``$HOME/.bashrc`` file to automatically make the IMAS-Core
installation available for you.
-.. note::
+.. note::
To use a ``public`` dataset, you also need to set the ``IMAS_HOME`` environment
variable. For example, on SDCC, this would be ``export IMAS_HOME=/work/imas``.
@@ -406,7 +463,7 @@ You may want to add this to your ``$HOME/.bashrc`` file to automatically make th
Once you have set the required environment variables, you may continue Using the
IMAS-Core.
-If IMAS-Core is built with Python bindings, you can also use the Python bindings with imas-python.
+If IMAS-Core is built with Python bindings, you can also use the Python bindings with imas-python.
`imas_python `_. Just install with `pip install imas-python`
and you can use the Python bindings. more information is here `imas-python `_.
diff --git a/include/meson.build b/include/meson.build
new file mode 100644
index 00000000..83f0132e
--- /dev/null
+++ b/include/meson.build
@@ -0,0 +1,44 @@
+# =============================================================================
+# Configuration Data for al_defs.h
+# =============================================================================
+
+cdata = configuration_data()
+
+# Version information
+cdata.set('PROJECT_VERSION', meson.project_version())
+
+# Generate Config Headers
+al_defs_h = configure_file(
+ input: 'al_defs.h.in',
+ output: 'al_defs.h',
+ configuration: cdata,
+)
+
+install_headers(al_defs_h, subdir: 'al_core')
+
+# =============================================================================
+# Install Public Headers
+# =============================================================================
+
+install_headers(
+ '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',
+ 'fix_include_windows.h',
+ 'provenance_plugin_feature.h',
+ 'readback_plugin_feature.h',
+ 'uri_parser.h',
+ subdir: 'al_core',
+)
+
+# =============================================================================
+# Include Directories
+# =============================================================================
+public_inc = include_directories('.')
\ No newline at end of file
diff --git a/meson.build b/meson.build
new file mode 100644
index 00000000..bf48c1a2
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,119 @@
+project(
+ 'imas-core',
+ 'cpp',
+ license: 'LGPL-3.0-or-later',
+ meson_version: '>=1.1.0',
+ version: run_command(
+ find_program('python3'),
+ '-m', 'setuptools_scm',
+ '--strip-dev',
+ check: true,
+ ).stdout().strip(),
+ default_options: [
+ 'cpp_std=c++17',
+ 'buildtype=debugoptimized',
+ ],
+)
+
+# =============================================================================
+# Compiler and System Setup
+# =============================================================================
+cxx = meson.get_compiler('cpp')
+host_system = host_machine.system()
+host_cpu = host_machine.cpu_family()
+
+# =============================================================================
+# Warning Flags
+# =============================================================================
+warning_flags = []
+if host_system == 'darwin'
+ warning_flags += [
+ '-Wno-deprecated-declarations',
+ '-Wno-inconsistent-missing-override',
+ '-Wno-delete-non-abstract-non-virtual-dtor',
+ '-Wno-unused-but-set-variable',
+ '-Wno-unused-variable',
+ '-Wno-misleading-indentation',
+ '-Wno-reorder-ctor',
+ '-Wno-pessimizing-move',
+ '-Wno-sometimes-uninitialized',
+ ]
+endif
+
+# =============================================================================
+# 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')
+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(
+ {
+ 'Core Arguments': core_args,
+ 'Warning Flags': warning_flags,
+ },
+ 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..90eafad3
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,70 @@
+# =============================================================================
+# 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_mdsplus',
+ type: 'boolean',
+ value: false,
+ description: 'Enable MDSplus backend',
+)
+
+option(
+ 'al_backend_uda',
+ type: 'boolean',
+ value: true,
+ description: 'Enable UDA backend',
+)
+
+option(
+ 'uda_fat',
+ type: 'boolean',
+ value: false,
+ description: 'Use UDA FAT client libraries',
+)
\ 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..0b1a4388
--- /dev/null
+++ b/python/meson.build
@@ -0,0 +1,105 @@
+add_languages('cython', native: false)
+
+# =============================================================================
+# Version File
+# =============================================================================
+# Get version using setuptools-scm
+version = run_command(
+ find_program('python3'),
+ '-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(
+ find_program('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 = py.dependency()
+numpy_dep = dependency('numpy', required: false)
+
+if not numpy_dep.found()
+ # Get numpy include directory and library using Python
+ _incdic_numpy_abs = run_command(
+ py,
+ '-c', 'import numpy; print(numpy.get_include())',
+ check: true,
+ ).stdout().strip()
+
+ # Create numpy dependency using include directory
+ numpy_dep = declare_dependency(
+ include_directories: include_directories(_incdic_numpy_abs),
+ )
+endif
+
+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',
+ override_options: ['cython_language=cpp'],
+ )
+endforeach
+
+# Install pure python files
+py.install_sources(
+ py_files + pxd_files + version_file,
+ subdir: 'imas_core',
+)
diff --git a/src/hdf5/meson.build b/src/hdf5/meson.build
new file mode 100644
index 00000000..4b659401
--- /dev/null
+++ b/src/hdf5/meson.build
@@ -0,0 +1,27 @@
+# HDF5 Backend
+
+# Add sources
+core_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',
+)
+
+# Add include directories
+core_inc += include_directories('.')
+
+# Add dependency
+core_deps += dependency('hdf5', language: 'cpp')
+
+# Add compiler flags
+core_args += '-DHDF5'
+
+if host_system == 'windows'
+ core_args += '-DH5_BUILT_AS_DYNAMIC_LIB'
+endif
\ No newline at end of file
diff --git a/src/mdsplus/meson.build b/src/mdsplus/meson.build
new file mode 100644
index 00000000..3c5a88de
--- /dev/null
+++ b/src/mdsplus/meson.build
@@ -0,0 +1,19 @@
+# MDSplus Backend
+
+# Add sources
+core_sources += files(
+ 'mdsplus_backend.cpp',
+)
+
+# Add include directories
+core_inc += include_directories('.')
+
+# Add dependency
+core_deps += dependency('mdsplus')
+
+# Add compiler flags
+core_args += '-DMDSPLUS'
+
+if host_system == 'windows'
+ core_args += '-DMDSOBJECTSCPPSHRVS_EXPORTS'
+endif
\ No newline at end of file
diff --git a/src/meson.build b/src/meson.build
new file mode 100644
index 00000000..d7a19b44
--- /dev/null
+++ b/src/meson.build
@@ -0,0 +1,92 @@
+# AL-Core Library
+
+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',
+)
+
+# Enable ASCII backend
+core_args = [
+ '-DASCII',
+]
+
+# Include local and public headers
+core_inc = [include_directories('.'), public_inc]
+
+# =============================================================================
+# Dependencies
+# =============================================================================
+boost_dep = dependency(
+ 'boost',
+ modules: ['filesystem'],
+ required: false,
+)
+if not boost_dep.found()
+ boost_dep = cxx.find_library('boost_filesystem')
+endif
+
+core_deps = [
+ boost_dep,
+]
+
+if host_system == 'windows'
+ core_deps += [
+ cxx.find_library('pthreads'),
+ dependency('dlfcn-win32', modules: ['dlfcn-win32::dl'], method: 'cmake'),
+ ]
+endif
+
+# =============================================================================
+# Add Optional Backends
+# =============================================================================
+if get_option('al_backend_hdf5')
+ subdir('hdf5')
+endif
+
+if get_option('al_backend_mdsplus')
+ subdir('mdsplus')
+endif
+
+if get_option('al_backend_uda')
+ subdir('uda')
+endif
+
+# =============================================================================
+# Library
+# =============================================================================
+al_core = library(
+ 'al',
+ core_sources,
+ cpp_args: core_args + warning_flags,
+ include_directories: core_inc,
+ dependencies: core_deps,
+ install: true,
+)
+
+# Declare dependency for other libraries to use
+al_core_dep = declare_dependency(
+ link_with: al_core,
+ include_directories: public_inc,
+)
+
+# =============================================================================
+# 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..dbead0d8
--- /dev/null
+++ b/src/uda/meson.build
@@ -0,0 +1,43 @@
+# UDA Backend
+
+# Add sources
+core_sources += files(
+ 'pugixml.cpp',
+ 'uda_backend.cpp',
+ 'uda_cache.cpp',
+ 'uda_path.cpp',
+ 'uda_xml.cpp',
+)
+
+# Add include directories
+core_inc += include_directories('.')
+
+# Add dependencies
+if get_option('uda_fat')
+ uda_fat_cpp_dep = dependency('uda-fat-cpp')
+ core_deps += [
+ dependency('uda-fat-client'),
+ uda_fat_cpp_dep,
+ ]
+else
+ uda_cpp_dep = dependency('uda-cpp')
+ core_deps += [
+ dependency('uda-client'),
+ uda_cpp_dep,
+ ]
+endif
+
+# Add compiler flags
+if get_option('uda_fat')
+ if uda_fat_cpp_dep.version().version_compare('>=2.7.6')
+ core_args += ['-DUDA', '-DUDA_LEGACY_276', '-DUDA_CLIENT_FLAGS_API']
+ else
+ core_args += ['-DUDA']
+ endif
+else
+ if uda_cpp_dep.version().version_compare('>=2.7.6')
+ core_args += ['-DUDA', '-DUDA_LEGACY_276', '-DUDA_CLIENT_FLAGS_API']
+ else
+ core_args += ['-DUDA']
+ endif
+endif
\ No newline at end of file
diff --git a/tests/meson.build b/tests/meson.build
new file mode 100644
index 00000000..83499a81
--- /dev/null
+++ b/tests/meson.build
@@ -0,0 +1,28 @@
+# 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
+add_languages('c', native: false)
+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