Skip to content

Commit 400bcb8

Browse files
add wheels/publish action, create lightweight wheels per platform, instead of fat ones
1 parent d1bbfb5 commit 400bcb8

3 files changed

Lines changed: 230 additions & 24 deletions

File tree

.github/workflows/wheels.yml

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
name: Build wheels
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
branches: ["master", "emscripten"]
7+
tags: ["v*"]
8+
9+
jobs:
10+
native-wheels:
11+
name: Native wheels (${{ matrix.os }})
12+
runs-on: ${{ matrix.os }}
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
os: [ubuntu-latest, windows-latest, macos-14]
17+
18+
steps:
19+
- uses: actions/checkout@v4
20+
21+
- uses: actions/setup-python@v5
22+
with:
23+
python-version: "3.12"
24+
25+
- name: Install build tooling
26+
run: python -m pip install --upgrade pip cibuildwheel
27+
28+
- name: Build wheels
29+
run: python -m cibuildwheel --output-dir dist
30+
env:
31+
CIBW_BUILD: cp312-*
32+
CIBW_SKIP: pp* *-musllinux_*
33+
CIBW_ARCHS_MACOS: arm64
34+
35+
- name: Upload native wheel artifacts
36+
uses: actions/upload-artifact@v4
37+
with:
38+
name: wheels-${{ matrix.os }}
39+
path: dist/*.whl
40+
41+
wasm-wheel:
42+
name: WASM wheel (Pyodide)
43+
runs-on: ubuntu-latest
44+
env:
45+
PYODIDE_EMSCRIPTEN_TAG: emscripten_3_1_58_wasm32
46+
47+
steps:
48+
- uses: actions/checkout@v4
49+
50+
- uses: actions/setup-python@v5
51+
with:
52+
python-version: "3.12"
53+
54+
- name: Install build tooling
55+
run: python -m pip install --upgrade pip build wheel
56+
57+
- name: Build wasm wheel
58+
run: python -m build --wheel
59+
env:
60+
PHREEQPYTHON_TARGET: wasm
61+
62+
- name: Retag wheel for Pyodide
63+
shell: bash
64+
run: |
65+
set -euo pipefail
66+
WHEEL_PATH=$(ls dist/*.whl)
67+
python -m wheel tags \
68+
--python-tag cp312 \
69+
--abi-tag cp312 \
70+
--platform-tag "${PYODIDE_EMSCRIPTEN_TAG}" \
71+
"${WHEEL_PATH}"
72+
rm -f "${WHEEL_PATH}"
73+
74+
- name: Upload wasm wheel artifact
75+
uses: actions/upload-artifact@v4
76+
with:
77+
name: wheels-wasm
78+
path: dist/*.whl
79+
80+
sdist:
81+
name: Source distribution
82+
runs-on: ubuntu-latest
83+
steps:
84+
- uses: actions/checkout@v4
85+
86+
- uses: actions/setup-python@v5
87+
with:
88+
python-version: "3.12"
89+
90+
- name: Install build tooling
91+
run: python -m pip install --upgrade pip build
92+
93+
- name: Build sdist
94+
run: python -m build --sdist
95+
96+
- name: Upload sdist artifact
97+
uses: actions/upload-artifact@v4
98+
with:
99+
name: sdist
100+
path: dist/*.tar.gz
101+
102+
pypi-publish:
103+
name: Publish to PyPI
104+
needs: [native-wheels, wasm-wheel, sdist]
105+
runs-on: ubuntu-latest
106+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
107+
permissions:
108+
id-token: write
109+
steps:
110+
- name: Download wheel artifacts
111+
uses: actions/download-artifact@v4
112+
with:
113+
pattern: wheels-*
114+
path: dist
115+
merge-multiple: true
116+
117+
- name: Download sdist artifact
118+
uses: actions/download-artifact@v4
119+
with:
120+
name: sdist
121+
path: dist
122+
123+
- name: Show artifacts
124+
shell: bash
125+
run: ls -la dist
126+
127+
- name: Publish package distributions to PyPI
128+
uses: pypa/gh-action-pypi-publish@release/v1
129+
with:
130+
packages-dir: dist

phreeqpython/viphreeqc.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,27 @@ def __init__(self, dll_path=None):
3939
"""
4040
if not dll_path:
4141
if sys.platform == 'win32':
42-
dll_name = './lib/VIPhreeqc.dll'
42+
dll_names = ['./lib/viphreeqc.dll', './lib/VIPhreeqc.dll']
4343
elif 'linux' in sys.platform:
44-
dll_name = './lib/viphreeqc.so'
44+
dll_names = ['./lib/viphreeqc.so']
4545
elif sys.platform == 'darwin':
46-
dll_name = './lib/viphreeqc.dylib'
46+
dll_names = ['./lib/viphreeqc.dylib']
4747
elif 'emscripten' in sys.platform:
48-
dll_name = './lib/viphreeqcwasm.so'
48+
dll_names = ['./.libs/viphreeqc.so', './lib/viphreeqcwasm.so']
4949
else:
5050
msg = 'Platform %s is not supported.' % sys.platform
5151
raise NotImplementedError(msg)
52-
dll_path = os.path.join(os.path.dirname(__file__), dll_name)
52+
53+
module_dir = os.path.dirname(__file__)
54+
dll_path = None
55+
for dll_name in dll_names:
56+
candidate = os.path.join(module_dir, dll_name)
57+
if os.path.exists(candidate):
58+
dll_path = candidate
59+
break
60+
61+
if dll_path is None:
62+
dll_path = os.path.join(module_dir, dll_names[0])
5363
phreeqc = ctypes.cdll.LoadLibrary(dll_path)
5464
self.debug = False
5565
self.dll = phreeqc

setup.py

Lines changed: 85 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,87 @@
1-
from setuptools import setup, find_packages
21
import os
32
import sys
4-
import zipfile
5-
import urllib
6-
7-
setup(name='phreeqpython',
8-
version='1.6.1',
9-
description='Vitens viphreeqc wrapper and utilities',
10-
url='https://github.com/Vitens/phreeqpython',
11-
author='Abel Heinsbroek',
12-
author_email='abel.heinsbroek@vitens.nl',
13-
license='Apache Licence 2.0',
14-
packages=['phreeqpython', 'phreeqpython.lib', 'phreeqpython.database'],
15-
include_package_data=True,
16-
zip_safe=False,
17-
install_requires=['periodictable','numpy'],
18-
extras_require={
19-
'kinetics': ['scipy'],
20-
}
21-
)
3+
from pathlib import Path
4+
5+
from setuptools import find_packages, setup
6+
7+
cmdclass = {}
8+
try:
9+
from wheel.bdist_wheel import bdist_wheel as _base_bdist_wheel
10+
11+
class bdist_wheel(_base_bdist_wheel):
12+
"""Always build platform wheels (never py3-none-any)."""
13+
14+
def finalize_options(self):
15+
super().finalize_options()
16+
self.root_is_pure = False
17+
18+
cmdclass = {"bdist_wheel": bdist_wheel}
19+
except ImportError: # pragma: no cover
20+
pass
21+
22+
23+
PACKAGE_DIR = Path(__file__).parent / "phreeqpython"
24+
25+
26+
def _candidate_libraries_for_target(target):
27+
if target == "windows":
28+
return ["lib/viphreeqc.dll", "lib/VIPhreeqc.dll"]
29+
if target == "linux":
30+
return ["lib/viphreeqc.so"]
31+
if target == "macos":
32+
return ["lib/viphreeqc.dylib"]
33+
if target == "wasm":
34+
return [".libs/viphreeqc.so", "lib/viphreeqcwasm.so"]
35+
raise ValueError("Unsupported PHREEQPYTHON_TARGET: %s" % target)
36+
37+
38+
def _resolve_target():
39+
explicit_target = os.environ.get("PHREEQPYTHON_TARGET", "").strip().lower()
40+
if explicit_target:
41+
return explicit_target
42+
43+
if sys.platform == "win32":
44+
return "windows"
45+
if "linux" in sys.platform:
46+
return "linux"
47+
if sys.platform == "darwin":
48+
return "macos"
49+
if "emscripten" in sys.platform:
50+
return "wasm"
51+
raise RuntimeError("Unsupported platform for wheel build: %s" % sys.platform)
52+
53+
54+
def _select_native_library(target):
55+
candidates = _candidate_libraries_for_target(target)
56+
for relative_path in candidates:
57+
if (PACKAGE_DIR / relative_path).exists():
58+
return relative_path
59+
raise FileNotFoundError(
60+
"No native library found for target '%s'. Expected one of: %s"
61+
% (target, ", ".join(candidates))
62+
)
63+
64+
65+
TARGET = _resolve_target()
66+
NATIVE_LIBRARY = _select_native_library(TARGET)
67+
PACKAGE_DATA = ["database/*.dat", NATIVE_LIBRARY]
68+
69+
70+
setup(
71+
name="phreeqpython",
72+
version="1.6.1",
73+
description="Vitens viphreeqc wrapper and utilities",
74+
url="https://github.com/Vitens/phreeqpython",
75+
author="Abel Heinsbroek",
76+
author_email="abel.heinsbroek@vitens.nl",
77+
license="Apache Licence 2.0",
78+
packages=find_packages(),
79+
package_data={"phreeqpython": PACKAGE_DATA},
80+
include_package_data=False,
81+
zip_safe=False,
82+
install_requires=["periodictable", "numpy"],
83+
extras_require={
84+
"kinetics": ["scipy"],
85+
},
86+
cmdclass=cmdclass,
87+
)

0 commit comments

Comments
 (0)