Skip to content

Commit 6c73391

Browse files
committed
Binary wheels on pip, build with github actions; v1.5.5
1 parent 5c3bdd7 commit 6c73391

File tree

12 files changed

+206
-33
lines changed

12 files changed

+206
-33
lines changed

.github/workflows/build_wheels.yml

+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
name: Wheels
2+
3+
on: [ push, pull_request ]
4+
5+
jobs:
6+
build_wheels:
7+
name: Build wheels on ${{ matrix.os }}
8+
if: ${{ startsWith(github.ref, 'refs/tags/') || contains(github.event.head_commit.message, '[pypi]') }}
9+
runs-on: ${{ matrix.os }}
10+
strategy:
11+
matrix:
12+
os: [ macos-11, macos-12, macos-13, flyci-macos-large-latest-m2, macos-14, ubuntu-latest, windows-latest ]
13+
14+
steps:
15+
- uses: awvwgk/setup-fortran@main
16+
if: matrix.os == 'windows-latest'
17+
id: setup-fortran
18+
with:
19+
compiler: gcc
20+
version: 11
21+
22+
- run: ln -s $(which gfortran-11) /usr/local/bin/gfortran
23+
if: matrix.os != 'windows-latest'
24+
25+
- run: gfortran --version
26+
27+
- uses: actions/checkout@v4
28+
with:
29+
submodules: recursive
30+
31+
- uses: actions/setup-python@v5
32+
33+
- name: Install cibuildwheel
34+
run: python -m pip install cibuildwheel==2.18.1
35+
36+
- name: Build macos-13 wheels
37+
if: matrix.os == 'macos-13' || matrix.os == 'macos-13-xlarge' || matrix.os == 'flyci-macos-large-latest-m2'
38+
env:
39+
MACOSX_DEPLOYMENT_TARGET: 13
40+
CIBW_BUILD: cp311-*
41+
CIBW_SKIP: pp*
42+
CIBW_BUILD_VERBOSITY: 1
43+
run: python -m cibuildwheel --output-dir wheelhouse
44+
45+
- name: Build macos-12 wheels
46+
if: matrix.os == 'macos-12'
47+
env:
48+
MACOSX_DEPLOYMENT_TARGET: 12
49+
CIBW_BUILD: cp311-*
50+
CIBW_SKIP: pp*
51+
CIBW_BUILD_VERBOSITY: 1
52+
run: python -m cibuildwheel --output-dir wheelhouse
53+
54+
- name: Build macos-11 wheels
55+
if: matrix.os == 'macos-11'
56+
env:
57+
# all cp3xx, since old macs seem to only use osx 11+ builds if this is set not "none"
58+
# see consistency with get_tag() in setup.py
59+
MACOSX_DEPLOYMENT_TARGET: 11
60+
CIBW_SKIP: pp*
61+
CIBW_BUILD_VERBOSITY: 1
62+
run: python -m cibuildwheel --output-dir wheelhouse
63+
64+
- name: Build wheels
65+
if: matrix.os == 'macos-14' || matrix.os == 'ubuntu-latest' || matrix.os == 'windows-latest'
66+
env:
67+
MACOSX_DEPLOYMENT_TARGET: 14
68+
CIBW_BUILD: cp311-*
69+
CIBW_SKIP: pp* *-win32 *-manylinux_i686 *musllinux*
70+
CIBW_BUILD_VERBOSITY: 1
71+
run: python -m cibuildwheel --output-dir wheelhouse
72+
73+
- uses: actions/upload-artifact@v4
74+
with:
75+
name: wheels-${{ matrix.os }}
76+
path: |
77+
wheelhouse/*.whl
78+
79+
build-sdist-and-upload:
80+
runs-on: ubuntu-latest
81+
needs: [ 'build_wheels' ]
82+
environment: wheels
83+
if: github.repository_owner == 'cmbant'
84+
permissions:
85+
id-token: write
86+
87+
steps:
88+
- uses: actions/checkout@v4
89+
with:
90+
submodules: recursive
91+
92+
- name: Set up Python
93+
uses: actions/setup-python@v5
94+
with:
95+
python-version: "3.10"
96+
cache: pip
97+
cache-dependency-path: "setup.py"
98+
99+
- name: Install dependencies
100+
run: |
101+
python -m pip install -U pip
102+
python -m pip install -U build twine
103+
104+
- name: Download wheels from build artifacts
105+
uses: actions/download-artifact@v4
106+
with:
107+
pattern: wheels-*
108+
merge-multiple: true
109+
path: dist-wheels/
110+
111+
- name: Build package
112+
run: |
113+
python -m build --sdist
114+
twine check --strict dist/*
115+
twine check --strict dist-wheels/*
116+
117+
- name: Publish wheels to PyPI Test
118+
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
119+
uses: pypa/gh-action-pypi-publish@release/v1
120+
with:
121+
repository-url: https://test.pypi.org/legacy/
122+
packages-dir: dist-wheels/
123+
124+
- name: Publish sdist to PyPI Test
125+
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
126+
uses: pypa/gh-action-pypi-publish@release/v1
127+
with:
128+
repository-url: https://test.pypi.org/legacy/
129+
130+
- name: Publish wheels to PyPI
131+
if: ${{ startsWith(github.ref, 'refs/tags/') }}
132+
uses: pypa/gh-action-pypi-publish@release/v1
133+
with:
134+
packages-dir: dist-wheels/
135+
136+
- name: Publish sdist to PyPI
137+
if: ${{ startsWith(github.ref, 'refs/tags/') }}
138+
uses: pypa/gh-action-pypi-publish@release/v1
139+
140+
test_wheels:
141+
name: Test wheels on ${{ matrix.os }}
142+
if: contains(github.event.head_commit.message, '[testpypi]')
143+
runs-on: ${{ matrix.os }}
144+
strategy:
145+
matrix:
146+
os: [ macos-11, macos-12, macos-13, flyci-macos-large-latest-m2, macos-14, ubuntu-latest, windows-latest ]
147+
148+
steps:
149+
- uses: actions/setup-python@v5
150+
151+
- name: install
152+
run: python -m pip install -i https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ camb
153+
154+
- name: test
155+
run: python -m unittest camb.tests.camb_test

.travis.yml

-13
Original file line numberDiff line numberDiff line change
@@ -88,16 +88,3 @@ script:
8888
after_failure:
8989
- test $TRAVIS_PULL_REQUEST == "false" && test $PYPI_DIST == "true" && test $TRAVIS_REPO_SLUG == "cmbant/CAMB" && [ -d fortran/testfiles ] && bash fortran/tests/upload_tests.sh
9090

91-
before_deploy:
92-
- pushd fortran; make clean delete; popd
93-
94-
deploy:
95-
- provider: pypi
96-
distributions: sdist
97-
username: "__token__"
98-
password: $PYPI_PASSWORD
99-
on:
100-
branch: master
101-
repo: cmbant/CAMB
102-
tags: true
103-
condition: $PYPI_DIST = true

README.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ Then install using::
3939

4040
pip install -e ./CAMB [--user]
4141

42-
You will need gfortran 6 or higher installed to compile. Binary files for Windows are also provided, so these are used instead if no
43-
gfortran installation is found on Windows machines. If you have gfortran installed, "python setup.py make"
44-
(and other standard setup commands) will build the Fortran library on all systems (including Windows without directly using a Makefile).
42+
You will need gfortran 6 or higher installed to compile (usually included with gcc by default).
43+
If you have gfortran installed, "python setup.py make" (and other standard setup commands) will build the Fortran
44+
library on all systems (including Windows without directly using a Makefile).
4545

4646
The python wrapper provides a module called "camb" documented in the Python `CAMB documentation <https://camb.readthedocs.io/en/latest/>`_.
4747

camb/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
__author__ = "Antony Lewis"
88
__contact__ = "antony at cosmologist dot info"
99
__url__ = "https://camb.readthedocs.io"
10-
__version__ = "1.5.4"
10+
__version__ = "1.5.5"
1111

1212
from . import baseconfig
1313

camb/cambdll.dll

-2.77 MB
Binary file not shown.

camb/sources.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def set_table(self, z, W, bias_z=None, k_bias=None, bias_kz=None):
5757
:param z: array of redshift values (monotonically increasing)
5858
:param W: array of window function values. It must be well enough sampled to smoothly cubic-spline interpolate
5959
:param bias_z: optional array of bias values at each z for scale-independent bias
60-
:param k_bias: optional array of k values for bias
60+
:param k_bias: optional array of k values for bias (Mpc^-1)
6161
:param bias_kz: optional 2D contiguous array for space-dependent bias(k, z).
6262
Must ensure range of k is large enough to cover required values.
6363

camb/tests/camb_test.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from camb import model, correlations, bbn, dark_energy, initialpower
1414
from camb.baseconfig import CAMBParamRangeError, CAMBValueError
1515

16-
fast = 'ci fast' in os.getenv("TRAVIS_COMMIT_MESSAGE", "")
16+
fast = 'ci fast' in os.getenv("TRAVIS_COMMIT_MESSAGE", "") or os.getenv("GITHUB_ACTIONS")
1717

1818

1919
class CambTest(unittest.TestCase):

docs/source/fortran_compilers.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ This includes in Jupyter notebooks; just re-start the kernel or use::
4545
import IPython
4646
IPython.Application.instance().kernel.do_shutdown(True)
4747

48-
If you want to automamatically rebuild the library from Jupyter you can do something like this::
48+
If you want to automatically rebuild the library from Jupyter you can do something like this::
4949

5050
import subprocess
5151
import sys

docs/source/index.rst

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@ If you want to work on the code from `GitHub <https://github.com/cmbant/camb>`_,
2121
pip install -e ./CAMB [--user]
2222

2323
You will need ifort or gfortran 6 or higher installed (and on your path) to compile; see :ref:`fortran-compilers` for
24-
compiler installation details if needed. A compiled library for Windows is also provided, and is used if no
25-
gfortran installation is found on Windows machines. If you have gfortran installed, "python setup.py make" will build
24+
compiler installation details if needed. If you have gfortran installed, "python setup.py make" will build
2625
the Fortran library on all systems (including Windows without directly using a Makefile), and can be used to update
2726
a source installation after changes or pulling an updated version.
2827

28+
The standard pip installation includes binary pre-compiled code, so no need for a Fortran compiler
29+
(unless you want to use custom sources/symbolic compilation features).
2930
Anaconda users can also install from conda-forge, best making a new clean environment using::
3031

31-
conda create -n camb -c conda-forge python=3.9 camb
32+
conda create -n camb -c conda-forge python=3.11 camb
3233
activate camb
3334

34-
with no need for a Fortran compiler (unless you want to use custom sources/symbolic compilation features).
3535
Check that conda installs the latest version, if not try installing
3636
in a new clean conda environment as above.
3737

fortran/config.f90

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module config
33
use constants, only: const_twopi
44
implicit none
55

6-
character(LEN=*), parameter :: version = '1.5.4'
6+
character(LEN=*), parameter :: version = '1.5.5'
77

88
integer :: FeedbackLevel = 0 !if >0 print out useful information about the model
99

pyproject.toml

+3-4
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,18 @@ authors = [
88
{ name = "Antony Lewis" },
99
]
1010
description = "Code for Anisotropies in the Microwave Background"
11-
keywords= ['cosmology', 'CAMB', 'CMB']
11+
keywords = ['cosmology', 'CAMB', 'CMB']
1212
readme = "docs/README_pypi.rst"
1313
license = { file = "LICENCE.txt" }
1414
dynamic = ["version"]
15-
requires-python = ">=3.6.0"
15+
requires-python = ">=3.7.0"
1616
classifiers = [
1717
"Development Status :: 5 - Production/Stable",
1818
"Operating System :: OS Independent",
1919
"Environment :: Console",
2020
"Intended Audience :: Science/Research",
2121
"Topic :: Scientific/Engineering :: Astronomy",
2222
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
23-
"Programming Language :: Python :: 3.6",
2423
"Programming Language :: Python :: 3.7",
2524
"Programming Language :: Python :: 3.8",
2625
"Programming Language :: Python :: 3.9",
@@ -46,4 +45,4 @@ Tracker = "https://github.com/cmbant/camb/issues"
4645
Licensing = "https://github.com/cmbant/camb/blob/master/LICENCE.txt"
4746

4847
[tool.setuptools.dynamic]
49-
version = {attr = "camb.__version__"}
48+
version = { attr = "camb.__version__" }

setup.py

+36-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
import os
44
import shutil
55
from typing import Any
6-
from setuptools import setup
6+
from setuptools import setup, Command, Extension
7+
from setuptools.command.build_ext import build_ext
78
from setuptools.command.build_py import build_py
89
from setuptools.command.develop import develop
9-
from setuptools import Command
10+
from setuptools.command.install import install
11+
from wheel.bdist_wheel import bdist_wheel as _bdist_wheel
1012

1113
file_dir = os.path.abspath(os.path.dirname(__file__))
1214
os.chdir(file_dir)
@@ -19,6 +21,7 @@
1921
else:
2022
DLLNAME = 'camblib.so'
2123

24+
2225
def get_forutils():
2326
fpath = os.getenv('FORUTILSPATH')
2427

@@ -177,7 +180,7 @@ def make_library(cluster=False):
177180
get_forutils()
178181
print("Compiling source...")
179182
subprocess.call("make python PYCAMB_OUTPUT_DIR=%s/camb/ CLUSTER_SAFE=%d" %
180-
(pycamb_path, int(cluster)), shell=True)
183+
(pycamb_path, int(cluster if not os.getenv("GITHUB_ACTIONS") else 1)), shell=True)
181184
subprocess.call("chmod 755 %s" % lib_file, shell=True)
182185

183186
if not os.path.isfile(os.path.join(pycamb_path, 'camb', DLLNAME)):
@@ -246,12 +249,41 @@ def run(self):
246249
subprocess.call("make clean", shell=True, cwd=os.path.join(file_dir, 'fortran'))
247250

248251

252+
class BDistWheelNonPure(_bdist_wheel):
253+
def finalize_options(self):
254+
super().finalize_options()
255+
self.root_is_pure = False
256+
257+
def get_tag(self):
258+
_, _, plat = super().get_tag()
259+
if "osx_11" in plat:
260+
return _, _, plat
261+
return "py3", "none", plat
262+
263+
264+
class InstallPlatlib(install):
265+
def finalize_options(self):
266+
super().finalize_options()
267+
if self.distribution.has_ext_modules():
268+
self.install_lib = self.install_platlib
269+
270+
271+
class BuildExtCommand(build_ext):
272+
"""Ensure built extensions are added to the correct path in the wheel."""
273+
274+
def run(self):
275+
pass
276+
277+
249278
if __name__ == "__main__":
250279
setup(name=os.getenv('CAMB_PACKAGE_NAME', 'camb'),
251280
zip_safe=False,
252281
cmdclass={'build_py': SharedLibrary, 'build_cluster': SharedLibraryCluster,
253282
'make': MakeLibrary, 'make_cluster': MakeLibraryCluster, 'clean': CleanLibrary,
254-
'develop': DevelopLibrary, 'develop_cluster': DevelopLibraryCluster},
283+
'develop': DevelopLibrary, 'develop_cluster': DevelopLibraryCluster,
284+
'bdist_wheel': BDistWheelNonPure, 'install': InstallPlatlib,
285+
"build_ext": BuildExtCommand},
286+
ext_modules=[Extension("camb.camblib", [])],
255287
packages=['camb', 'camb.tests'],
256288
platforms="any",
257289
package_data={'camb': [DLLNAME, 'HighLExtrapTemplate_lenspotentialCls.dat',

0 commit comments

Comments
 (0)