Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
9a79b1a
WIP on meson port
jameskermode Sep 27, 2023
d5e8470
attempt to fix submodule spec
jameskermode Sep 27, 2023
ece0fe4
autogenerate grammar .c and .h files
jameskermode Sep 27, 2023
747a27f
remove defunct setup.py
jameskermode Sep 28, 2023
6f2850b
debug
jameskermode Sep 28, 2023
54cf149
install requires pyleri
jameskermode Sep 28, 2023
6d79bc5
fetch full history so discover_version.py works
jameskermode Sep 28, 2023
fdef071
full fetch for cirrus too
jameskermode Sep 28, 2023
7701082
update libcleri makefile
jameskermode Sep 28, 2023
c542556
Fortran code depends on libcleri
jameskermode Sep 28, 2023
518a40d
fix Fortran build
jameskermode Sep 28, 2023
42a1e49
check wheel building on PRs
jameskermode Sep 28, 2023
f6a963d
Merge branch 'meson' of https://github.com/libAtoms/extxyz into meson
jameskermode Sep 28, 2023
b6ab2b7
try to install PCRE2 on Windows
jameskermode Sep 28, 2023
bfd2f3d
pcre2 attempts on Windows and Ubuntu
jameskermode Sep 28, 2023
d8e3ba5
another attempt at building pcre2 on Windows
jameskermode Sep 28, 2023
250b741
another attempt at building pcre2 on Windows
jameskermode Sep 28, 2023
c126f24
remove build prefix
jameskermode Sep 28, 2023
9fbfe1b
fix check-tag syntax
jameskermode Sep 28, 2023
f3e2363
enable debugging
jameskermode Sep 28, 2023
dcc6264
try to make twice
jameskermode Oct 2, 2023
a63307e
add missing cc definition
jameskermode Oct 2, 2023
7d515e1
try to make twice
jameskermode Oct 2, 2023
1628dbb
try to build libpcre2 with cmake+ninja on windows
jameskermode Oct 2, 2023
d747eb3
try to build libpcre2 with cmake+ninja on windows
jameskermode Oct 2, 2023
2187c5f
Fix Meson build system issues
jameskermode Oct 30, 2025
e8e786c
Fix CI/CD workflows for wheel building
jameskermode Oct 30, 2025
10705b9
Merge branch 'master' into meson
jameskermode Oct 30, 2025
da4ac06
Fix CI workflows: disable tmate, fix Windows build, add PCRE2
jameskermode Oct 30, 2025
1d0a807
Parallelize wheel builds by Python version
jameskermode Oct 30, 2025
3e82a8e
Fix workflow syntax: compute cibuildwheel Python version
jameskermode Oct 30, 2025
bad4666
Fix wheel building: Windows PCRE2 detection and macOS ARM64
jameskermode Oct 31, 2025
9f0f834
Fix all wheel building issues: macOS deployment target, Python 3.8, W…
jameskermode Oct 31, 2025
d29f23d
Fix remaining wheel build issues: macOS 15.0 target, Windows CMake pa…
jameskermode Oct 31, 2025
9ac9093
Windows: Add compiler environment variables for PCRE2 detection
jameskermode Oct 31, 2025
88f7a64
Add x86_64 macOS support and fix Windows MinGW PCRE2 detection
jameskermode Oct 31, 2025
6a37a96
Fix macOS-13 deployment target and add pkg-config for Windows
jameskermode Oct 31, 2025
609c21a
Use vcpkg for Windows PCRE2 and set macOS x86_64 target to 13.0
jameskermode Oct 31, 2025
816b5e1
Windows: Add pkgconfiglite and Meson wrap fallback for PCRE2
jameskermode Oct 31, 2025
79d5bde
Update MESON_BUILD_STATUS.md with Windows fix attempts
jameskermode Oct 31, 2025
83dc67d
Fix Windows builds: Correct CIBW_ENVIRONMENT_WINDOWS format
jameskermode Oct 31, 2025
87cf963
Document root cause of Windows build failures
jameskermode Oct 31, 2025
d2f2b80
Remove MESON_BUILD_STATUS.md and add notes files to .gitignore
jameskermode Oct 31, 2025
3e7a375
Move cibuildwheel config to pyproject.toml
jameskermode Oct 31, 2025
05888c2
Fix Windows PATH issue in cibuildwheel
jameskermode Oct 31, 2025
620f44d
Fix Windows builds: Use cross-platform Python command in Meson
jameskermode Oct 31, 2025
487f0ad
Fix Meson: project() must be first statement, use 'python' command
jameskermode Oct 31, 2025
5dce581
Fix Windows builds: Handle missing git in discover_version.py
jameskermode Oct 31, 2025
72c52cb
Fix Windows version discovery: Add git to PATH and fallback version
jameskermode Oct 31, 2025
d4d89c3
Fix Windows builds: Define vs_crt variable for MSVC PCRE2 detection
jameskermode Oct 31, 2025
edb6d25
Fix Windows builds: Use auto-detection for Python installation
jameskermode Oct 31, 2025
e7f8aaf
Fix macOS runners and Windows architecture mismatch
jameskermode Oct 31, 2025
1d70032
Update macOS x86_64 deployment target to 14.0 for macos-15-intel
jameskermode Oct 31, 2025
aa38518
Update libcleri submodule with Windows/MSVC compatibility fixes
jameskermode Oct 31, 2025
cc45b8b
Update libcleri to upstream/master with Windows MSVC fix
jameskermode Oct 31, 2025
a7d0631
Update for libcleri API changes: remove cleri_children_t
jameskermode Oct 31, 2025
e1a7ab0
Update libcleri: add strncasecmp MSVC compatibility
jameskermode Oct 31, 2025
3943115
Update libcleri: add static library build target
jameskermode Oct 31, 2025
99b063e
Disable import library generation for Windows Python extension
jameskermode Oct 31, 2025
1e07c42
Revert implib parameter - not supported in older Meson
jameskermode Oct 31, 2025
6e9d034
Require Meson >= 1.3.0 and disable Windows import library
jameskermode Oct 31, 2025
792bece
Remove unsupported implib parameter from python.extension_module()
jameskermode Nov 1, 2025
13a3f5e
Fix Windows build by requiring meson-python >= 0.16.0
jameskermode Nov 1, 2025
435cb4e
Force .lib import library generation on Windows with /EXPORT
jameskermode Nov 1, 2025
0806039
Try downgrading to meson-python 0.13.2 to fix Windows .lib issue
jameskermode Nov 1, 2025
688316f
Disable Windows builds and clean up
jameskermode Nov 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ cirrus_wheels_macos_arm64_task:

build_script:
- which python
# needed for discover_version.py
- git fetch --all
# needed for submodules
- git submodule update --init
- uname -m
Expand Down
76 changes: 61 additions & 15 deletions .github/workflows/build-wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,86 @@ on:
branches: [ master ]
tags:
- v*
pull_request:
branches: [ master ]

jobs:
build_wheels:
name: Build wheels on ${{ matrix.os }}
name: Build wheels on ${{ matrix.os }} for Python ${{ matrix.python-version }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, macos-12, windows-2019]
os: [ubuntu-22.04, macos-latest, macos-15-intel]
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
exclude:
# macOS ARM64 (macos-latest) doesn't support Python 3.8
- os: macos-latest
python-version: '3.8'
# Windows builds disabled due to meson-python issue with .lib import libraries
# See: https://github.com/libAtoms/extxyz/pull/17
fail-fast: false

steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Checkout submodules
run: git submodule update --init --recursive
run: git submodule update --init --recursive

- name: Set Python version for cibuildwheel
id: set-py-version
shell: bash
run: |
PY_VERSION="${{ matrix.python-version }}"
CIBW_PYTHON="cp${PY_VERSION//.}"
echo "cibw-python=${CIBW_PYTHON}" >> $GITHUB_OUTPUT

- name: Install PCRE2 via vcpkg (Windows only)
if: runner.os == 'Windows'
shell: bash
run: |
# Install pkg-config lite (ensures working pkg-config before Strawberry Perl)
choco install pkgconfiglite -y

# Install PCRE2 using vcpkg
vcpkg install pcre2:x64-windows

# Set up environment for meson/pkg-config
VCPKG_ROOT="C:/vcpkg"
PCRE2_DIR="${VCPKG_ROOT}/installed/x64-windows"

# Add pkgconfiglite to PATH first (before Strawberry Perl)
echo "C:/ProgramData/chocolatey/lib/pkgconfiglite/tools/bin" >> $GITHUB_PATH

echo "CMAKE_PREFIX_PATH=${PCRE2_DIR}" >> $GITHUB_ENV
echo "PKG_CONFIG_PATH=${PCRE2_DIR}/lib/pkgconfig" >> $GITHUB_ENV
echo "PCRE2_ROOT=${PCRE2_DIR}" >> $GITHUB_ENV
echo "LIB=${PCRE2_DIR}/lib;$LIB" >> $GITHUB_ENV
echo "INCLUDE=${PCRE2_DIR}/include;$INCLUDE" >> $GITHUB_ENV
echo "PATH=${PCRE2_DIR}/bin;$PATH" >> $GITHUB_ENV

- name: Build wheels
uses: pypa/cibuildwheel@v2.12.1
uses: pypa/cibuildwheel@v2.22.0
env:
CIBW_SKIP: cp27-* cp35-* pp* *musl* "*-macosx_arm64"
CIBW_BUILD: ${{ steps.set-py-version.outputs.cibw-python }}-*
CIBW_SKIP: pp* *musl*
CIBW_ARCHS_LINUX: "auto64"
CIBW_ARCHS_MACOS: "x86_64"
CIBW_BEFORE_ALL_LINUX: "which yum && yum install -y pcre2-devel zlib-devel"
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: "pytest -v {package}/tests"
CIBW_ARCHS_MACOS: ${{ matrix.os == 'macos-latest' && 'arm64' || 'x86_64' }}
CIBW_ENVIRONMENT_MACOS: "MACOSX_DEPLOYMENT_TARGET=${{ matrix.os == 'macos-latest' && '15.0' || '14.0' }}"
CIBW_ARCHS_WINDOWS: "AMD64"

# # Uncomment to get SSH access for testing
# Uncomment to get SSH access for testing
# - name: Setup tmate session
# if: failure()
# uses: mxschmitt/action-tmate@v3
# timeout-minutes: 15

- name: Upload artifacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}-py${{ matrix.python-version }}
path: ./wheelhouse/*.whl

- name: Release wheels
Expand All @@ -50,10 +96,10 @@ jobs:
- name: Check tag
id: check-tag
run: |
if [[ ${{ github.event.ref }} =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo ::set-output name=match::true
if [[ ${{ github.ref }} =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+ ]]; then
echo "match=true" >> $GITHUB_OUTPUT
fi

- name: Deploy to PyPI
if: steps.check-tag.outputs.match == 'true'
run: |
Expand Down
16 changes: 11 additions & 5 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,28 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.7, 3.8, 3.9, "3.10", "3.11", "3.12"]
python-version: [3.8, 3.9, "3.10", "3.11", "3.12"]

steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Checkout submodules
run: git submodule update --init --recursive
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install system dependencies
run: |
sudo apt-get update -y
sudo apt-get install -y libpcre2-dev
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
python -m pip install flake8 pytest
python -m pip install -e . --verbose
python -m pip install . --verbose
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
Expand Down Expand Up @@ -63,7 +69,7 @@ jobs:
- name: Test with pytest
run: |
USE_FORTRAN=T pytest -v --ignore QUIP
# # Uncomment to get SSH access for testing
# Uncomment to get SSH access for testing
# - name: Setup tmate session
# if: failure()
# uses: mxschmitt/action-tmate@v3
Expand Down
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ extxyz.egg-info/
.DS_Store
*.o
pcre2-10.37/
venv/
venv/

# Claude notes (don't commit)
MESON_BUILD_STATUS.md
CLAUDE.md
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "extxyz/libcleri"]
path = libcleri
url = https://github.com/transceptor-technology/libcleri
url = https://github.com/libAtoms/libcleri
105 changes: 105 additions & 0 deletions discover_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#
# Copyright 2022 Lars Pastewka
#
# ### MIT license
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#

#
# This is the most minimal-idiotic way of discovering the version that I
# could come up with. It deals with the following issues:
# * If we are installed, we can get the version from package metadata,
# either via importlib.metadata or from pkg_resources. This also holds for
# wheels that contain the metadata. We are good! Yay!
# * If we are not installed, there are two options:
# - We are working within the source git repository. Then
# git describe --tags --always
# yields a reasonable version descriptor, but that is unfortunately not
# PEP 440 compliant (see https://peps.python.org/pep-0440/). We need to
# mangle the version string to yield something compatible.
# - If we install from a source tarball, we need to parse PKG-INFO manually.
#

import re
import subprocess

class CannotDiscoverVersion(Exception):
pass


def get_version_from_pkg_info():
"""
Discover version from PKG-INFO file.
"""
f = open('PKG-INFO', 'r')
l = f.readline()
while l:
if l.startswith('Version:'):
return l[8:].strip()
l = f.readline()
raise CannotDiscoverVersion("No line starting with 'Version:' in 'PKG-INFO'.")


def get_version_from_git():
"""
Discover version from git repository.
"""
try:
git_describe = subprocess.run(
['git', 'describe', '--tags', '--dirty', '--always'],
stdout=subprocess.PIPE)
except (FileNotFoundError, OSError) as e:
# git command not found in PATH (common in isolated build environments like Windows cibuildwheel)
raise CannotDiscoverVersion(f'git command not found: {e}')

if git_describe.returncode != 0:
raise CannotDiscoverVersion('git execution failed.')
version = git_describe.stdout.decode('latin-1').strip()

dirty = version.endswith('-dirty')

# Make version PEP 440 compliant
if dirty:
version = version.replace('-dirty', '')
version = version.strip('v') # Remove leading 'v' if it exists
version = version.replace('-', '.dev', 1)
version = version.replace('-', '+', 1)
if dirty:
version += '.dirty'

return version


try:
version = get_version_from_git()
except CannotDiscoverVersion:
try:
version = get_version_from_pkg_info()
except (CannotDiscoverVersion, FileNotFoundError):
# Fallback for isolated build environments (e.g., Windows cibuildwheel)
# where neither git nor PKG-INFO is available
# Use a development version that will be replaced by the build system
version = '0.0.0+unknown'

#
# Print version to screen
#

print(version)
2 changes: 1 addition & 1 deletion libcleri
Submodule libcleri updated 67 files
+25 −0 .github/workflows/ci.yml
+0 −14 .travis.yml
+1 −1 CONTRIBUTING.md
+1 −1 LICENSE.md
+26 −30 README.md
+11 −3 Release/makefile
+2 −5 Release/src/subdir.mk
+37 −0 debian/changelog
+1 −1 debian/control
+1 −1 debian/copyright
+2 −2 debian/libcleri0.symbols
+1 −1 debian/rules
+1 −1 debian/watch
+0 −76 examples/tree_and_expect/buffer.c
+0 −23 examples/tree_and_expect/buffer.h
+0 −150 examples/tree_and_expect/expect/expect.c
+0 −23 examples/tree_and_expect/expect/expect.h
+0 −122 examples/tree_and_expect/expect/main.c
+0 −69 examples/tree_and_expect/tree/main.c
+0 −158 examples/tree_and_expect/tree/tree.c
+0 −18 examples/tree_and_expect/tree/tree.h
+0 −24 inc/cleri/children.h
+2 −0 inc/cleri/cleri.h
+1 −3 inc/cleri/kwcache.h
+16 −11 inc/cleri/node.h
+0 −21 inc/cleri/node.inline.h
+2 −2 inc/cleri/rule.h
+3 −3 inc/cleri/version.h
+13 −0 inc/cleri/wincompat.h
+4 −4 makefile.init
+31 −0 meson.build
+0 −62 src/children.c
+2 −17 src/choice.c
+7 −0 src/expecting.c
+11 −17 src/keyword.c
+14 −33 src/kwcache.c
+2 −10 src/list.c
+54 −1 src/node.c
+1 −9 src/optional.c
+2 −3 src/parse.c
+5 −10 src/prio.c
+6 −11 src/regex.c
+1 −9 src/repeat.c
+28 −52 src/rule.c
+1 −9 src/sequence.c
+22 −13 src/this.c
+1 −9 src/token.c
+1 −9 src/tokens.c
+8 −0 test/helpers.h
+0 −1 test/test_choice/sources
+0 −1 test/test_dup/sources
+0 −1 test/test_json_lang/sources
+0 −1 test/test_keyword/sources
+0 −1 test/test_list/sources
+2 −2 test/test_list/test_list.c
+0 −1 test/test_optional/sources
+0 −1 test/test_prio/sources
+42 −2 test/test_prio/test_prio.c
+0 −1 test/test_ref/sources
+0 −1 test/test_regex/sources
+0 −1 test/test_repeat/sources
+0 −1 test/test_sequence/sources
+0 −1 test/test_thingsdb_lang/sources
+178 −63 test/test_thingsdb_lang/test_thingsdb_lang.c
+0 −1 test/test_token/sources
+0 −1 test/test_tokens/sources
+1 −1 test/test_version/test_version.c
32 changes: 32 additions & 0 deletions libcleri_meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
inc_dir = include_directories('inc')

libcleri = static_library('cleri',
'src/children.c',
'src/choice.c',
'src/dup.c',
'src/expecting.c',
'src/grammar.c',
'src/keyword.c',
'src/kwcache.c',
'src/list.c',
'src/node.c',
'src/cleri.c',
'src/olist.c',
'src/optional.c',
'src/parse.c',
'src/prio.c',
'src/ref.c',
'src/regex.c',
'src/repeat.c',
'src/rule.c',
'src/sequence.c',
'src/this.c',
'src/token.c',
'src/tokens.c',
'src/version.c',
dependencies: pcre2,
include_directories: inc_dir)

cleri = declare_dependency(
link_with: libcleri,
include_directories: inc_dir)
16 changes: 10 additions & 6 deletions libextxyz/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ else
dlext ?= so
endif

.PHONY: default all libcleri install_libcleri install clean

default: libextxyz.${dlext}

all: libcleri extxyz_kv_grammar.c extxyz_kv_grammar.h libextxyz.${dlext}

libcleri:
if [ -z ${LIBCLERI_PATH} ]; then echo "LIBCLERI_PATH must be defined" 1>&2; exit 1; fi
${MAKE} -C ${LIBCLERI_PATH} -f makefile
${MAKE} -C ${LIBCLERI_PATH} -f makefile libcleri.a

install_libcleri: libcleri
${MAKE} -C ${LIBCLERI_PATH} -f makefile install INSTALL_PATH=${prefix}
Expand All @@ -53,11 +55,13 @@ install: libextxyz.${dlext}

test_fortran_main.o: fextxyz.o extxyz.o extxyz_kv_grammar.o

fextxyz: test_fortran_main.o fextxyz.o extxyz.o extxyz_kv_grammar.o
${F90} -g $^ -o $@ ${LIBCLERI_PATH}/libcleri.a ${LDFLAGS} ${QUIP_LDFLAGS}
FOBJS = test_fortran_main.o fextxyz.o extxyz.o extxyz_kv_grammar.o
fextxyz: libcleri ${FOBJS}
${F90} -g ${FOBJS} -o $@ ${LIBCLERI_PATH}/libcleri.a ${LDFLAGS} ${QUIP_LDFLAGS}

cextxyz: test_C_main.o extxyz.o extxyz_kv_grammar.o
${F90} -g $^ -o $@ ${LIBCLERI_PATH}/libcleri.a ${LDFLAGS}
COBJS = test_C_main.o extxyz.o extxyz_kv_grammar.o
cextxyz: libcleri ${COBJS}
${F90} -g ${COBJS} -o $@ ${LIBCLERI_PATH}/libcleri.a ${LDFLAGS}

clean:
rm -rf libextxyz.${dlext} *.o
rm -rf libextxyz.${dlext} *.o
8 changes: 4 additions & 4 deletions libextxyz/extxyz.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,9 @@ int parse_tree(cleri_node_t *node, DictEntry **cur_entry, int *in_seq, int *in_k
}

//DEBUG printf("looping over children\n"); //DEBUG
for (cleri_children_t *child = node->children; child; child = child->next) {
for (cleri_node_t *child = node->children; child; child = child->next) {
//DEBUG printf("child\n"); //DEBUG
int err = parse_tree(child->node, cur_entry, in_seq, in_kv_pair, in_old_one_d, error_message);
int err = parse_tree(child, cur_entry, in_seq, in_kv_pair, in_old_one_d, error_message);
if (err) {
return err;
}
Expand Down Expand Up @@ -319,8 +319,8 @@ void dump_tree(cleri_node_t *node, char *prefix) {
printf("%snode NULL\n", prefix);
}

for (cleri_children_t *child = node->children; child; child = child->next) {
dump_tree(child->node, new_prefix);
for (cleri_node_t *child = node->children; child; child = child->next) {
dump_tree(child, new_prefix);
}

free(new_prefix);
Expand Down
Loading
Loading