Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP on meson port #17

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 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
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
43 changes: 32 additions & 11 deletions .github/workflows/build-wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,42 @@ on:
branches: [ master ]
tags:
- v*
pull_request:
branches: [ master ]

jobs:
build_wheels:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, macos-12, windows-2019]
os: [ubuntu-22.04, macos-13, windows-2019]
fail-fast: false

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

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

- name: Install PCRE2 (Windows only)
if: matrix.os == 'windows-2019'
shell: bash
run: |
pcre2_version=10.42
download_url=https://github.com/PCRE2Project/pcre2/releases/download/pcre2-${pcre2_version}/pcre2-${pcre2_version}.tar.gz
curl -L $download_url -o pcre2.tar.gz
tar xvzf pcre2.tar.gz
cd pcre2-${pcre2_version}
mkdir build
cd build
cmake ..
ninja
ninja install

- name: Build wheels
uses: pypa/cibuildwheel@v2.12.1
env:
Expand All @@ -28,11 +49,11 @@ jobs:
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: "pytest -v {package}/tests"

# # Uncomment to get SSH access for testing
# - name: Setup tmate session
# if: failure()
# uses: mxschmitt/action-tmate@v3
# timeout-minutes: 15
# 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
Expand All @@ -50,10 +71,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
14 changes: 8 additions & 6 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Checkout submodules
run: git submodule update --init --recursive
- name: Set up Python ${{ matrix.python-version }}
Expand Down Expand Up @@ -60,8 +62,8 @@ jobs:
- name: Test with pytest
run: |
USE_FORTRAN=T pytest -v --ignore QUIP
# # Uncomment to get SSH access for testing
# - name: Setup tmate session
# if: failure()
# uses: mxschmitt/action-tmate@v3
# timeout-minutes: 15
# Uncomment to get SSH access for testing
- name: Setup tmate session
if: failure()
uses: mxschmitt/action-tmate@v3
timeout-minutes: 15
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
94 changes: 94 additions & 0 deletions discover_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#
# 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.
"""
git_describe = subprocess.run(
['git', 'describe', '--tags', '--dirty', '--always'],
stdout=subprocess.PIPE)
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:
version = get_version_from_pkg_info()

#
# Print version to screen
#

print(version)
2 changes: 1 addition & 1 deletion libcleri
Submodule libcleri updated 2 files
+4 −1 Release/makefile
+32 −0 meson.build
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
16 changes: 16 additions & 0 deletions libextxyz/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
python3 = find_program('python3')

run_command(
python3,
'..' / 'python' / 'extxyz' / 'extxyz_kv_grammar.py'
)

# Build and install the extension module
module = python.extension_module(
'_extxyz', # Name of the module
['extxyz.c', 'extxyz_kv_grammar.c'],
install: true, # Install it
subdir: 'extxyz',
gnu_symbol_visibility: 'default', # keep symbols public
dependencies: [cleri, pcre2]
)
55 changes: 55 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# https://mesonbuild.com/
project(
'extxyz', # Project name
'c',
version: run_command('python3', 'discover_version.py', check: true).stdout().strip(), # Project version
)

# https://mesonbuild.com/Python-module.html
pymod = import('python')
python = pymod.find_installation('python3',
required: true,
pure: false
)

host_system = host_machine.system()
cc = meson.get_compiler('c')

# adapted from https://gitlab.gnome.org/GNOME/glib/-/blob/cd9a5c173a154e326a3ebaa28cfe41a7444625c5/meson.build#L2020-L2052
pcre2 = dependency('libpcre2-8', version: '>= 10.23', required : false)
if not pcre2.found()
if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl'
# MSVC: Search for the PCRE2 library by the configuration, which corresponds
# to the output of CMake builds of PCRE2. Note that debugoptimized
# is really a Release build with .PDB files.
if vs_crt == 'debug'
pcre2 = cc.find_library('pcre2d-8', required : false)
else
pcre2 = cc.find_library('pcre2-8', required : false)
endif
endif
endif

# Try again with the fallback
if not pcre2.found()
pcre2 = dependency('libpcre2-8', required : true, fallback : ['pcre2', 'libpcre2_8'])
use_pcre2_static_flag = true
elif host_system == 'windows'
pcre2_static = cc.links('''#define PCRE2_STATIC
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
int main() {
void *p = NULL;
pcre2_code_free(p);
return 0;
}''',
dependencies: pcre2,
name : 'Windows system PCRE2 is a static build')
use_pcre2_static_flag = pcre2_static
else
use_pcre2_static_flag = false
endif

subdir('libcleri')
subdir('libextxyz')
subdir('python/extxyz')
33 changes: 30 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
[build-system]
# Minimum requirements for the build system to execute.
requires = ["setuptools", "wheel", "pyleri>=1.3.3"]
build-backend = "setuptools.build_meta"
requires = ["meson>=1.0.0", "meson-python>=0.13.0", "ninja", "pyleri>=1.3.3", "oldest-supported-numpy"]
build-backend = "mesonpy"

[project]
name = "extxyz"
description = "Extended XYZ file format tools"
readme = "README.md"
license = { file = "LICENSE" }
authors = [
{ name = "James Kermode", email = "james.kermode@gmail.com"},
]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Programming Language :: Python"
]
requires-python = ">=3.7.0"
dynamic = [ "version" ]
dependencies = [
"numpy>=1.13.0", 'pyleri>=1.3.3', 'ase>=3.17'
]

[project.optional-dependencies]
test = [
"pytest",

]

[project.urls]
documentation = "http://libatoms.github.io/extxyz/"
repository = "https://github.com/libAtoms/extxyz"
27 changes: 27 additions & 0 deletions python/extxyz/_version.py.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#
# Copyright 2017 Lars Pastewka (U. Freiburg)
#
# matscipy - Materials science with Python at the atomic-scale
# https://github.com/libAtoms/matscipy
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

# This file helps to compute a version number in source trees obtained from
# git-archive tarball (such as those provided by githubs download-from-tag
# feature). Distribution tarballs (built by setup.py sdist) and build
# directories (produced by setup.py build) will contain a much shorter file
# that just contains the computed version number.

__version__ = '@VERSION@'
Loading
Loading