Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
1dc34fd
Update cross build installation mechanism
ryanking13 Aug 19, 2024
ee09707
Fix symlink
ryanking13 Aug 19, 2024
c806c05
type
ryanking13 Aug 20, 2024
033e552
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 21, 2024
797e605
Merge remote-tracking branch 'upstream/main' into no-host-site
ryanking13 Sep 24, 2024
c8f4663
cleanup [integration]
ryanking13 Sep 24, 2024
821cef1
Merge branch 'no-host-site' of https://github.com/ryanking13/pyodide-…
ryanking13 Sep 24, 2024
6521bef
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 24, 2024
0ec228c
Merge branch 'main' into no-host-site
ryanking13 Oct 14, 2024
f039816
Add more test
ryanking13 Oct 15, 2024
5b49ad5
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 15, 2024
221f9ea
changelog
ryanking13 Oct 15, 2024
10edfb7
More integration test files [integration]
ryanking13 Oct 15, 2024
a18357d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 15, 2024
611ed7b
exclude patchfile from codespell
ryanking13 Oct 15, 2024
9ec8e60
[integration]
ryanking13 Oct 15, 2024
f962cc4
Remove integration tests from pre-commit check
ryanking13 Oct 15, 2024
54efacc
Fix integration test [integration]
ryanking13 Oct 15, 2024
2f5bc3b
Remove uncessery arg
ryanking13 Oct 16, 2024
0feb9aa
Force install cross-build package even if version mismatches [integra…
ryanking13 Oct 16, 2024
401aa67
Merge main
agriyakhetarpal Jun 6, 2026
f72ca2a
Update SciPy integration test to 1.17.1, drop f2py generators patch
agriyakhetarpal Jun 6, 2026
f98ef43
Rename `openblas` to `libopenblas`
agriyakhetarpal Jun 6, 2026
2c7e98f
Change openblas to libopenblas in recipe file
agriyakhetarpal Jun 6, 2026
aac25bd
Add Boost recipe needed for SciPy
agriyakhetarpal Jun 6, 2026
2e9ed3f
Update OpenBLAS version and patches
agriyakhetarpal Jun 6, 2026
24746e6
Update `_find_executable_and_scripts` as per build 1.5.0
agriyakhetarpal Jun 6, 2026
eedcb31
Better docstring
agriyakhetarpal Jun 6, 2026
491bb9c
Rework `AVOIDED_REQUIREMENTS` bits
agriyakhetarpal Jun 6, 2026
fddf520
Early skip if no unisolated packages
agriyakhetarpal Jun 6, 2026
8c85dcf
Drop tests
agriyakhetarpal Jun 6, 2026
0795637
More changes
agriyakhetarpal Jun 6, 2026
f572a3d
Don't exclude integration tests from linting
agriyakhetarpal Jun 6, 2026
1e37553
Put TODO above function
agriyakhetarpal Jun 6, 2026
679daad
Drop oldest-supported-numpy, it's deprecated now
agriyakhetarpal Jun 6, 2026
f3bdb7d
Drop `integration_tests/` changes, will test separately
agriyakhetarpal Jun 6, 2026
9715cf4
Add f2py example for testing
agriyakhetarpal Jun 6, 2026
aedf9b8
Fix grammar in `get_unisolated_packages` docstring
agriyakhetarpal Jun 6, 2026
14749d1
Fix docstring for `get_unisolated_files`
agriyakhetarpal Jun 6, 2026
daecc1a
Fix param name mismatch (`venv_path`)
agriyakhetarpal Jun 6, 2026
48e674d
Use warning instead of bare print
agriyakhetarpal Jun 6, 2026
1821d6c
Deprecation warning for `skip_install_cross_build_packages`
agriyakhetarpal Jun 6, 2026
5bb795c
Be a bit more defensive about xbuildenv reqs file
agriyakhetarpal Jun 6, 2026
25f0ce4
Add CHANGELOG entries for #21
agriyakhetarpal Jun 6, 2026
4f88027
Fix license compliance for pypa/build
agriyakhetarpal Jun 6, 2026
0bc7d3e
Merge main and resolve conflicts in CHANGELOG
agriyakhetarpal Jun 7, 2026
10275a0
Restore logic to install cross-build packages
agriyakhetarpal Jun 7, 2026
a97c864
Restructure and add lazy tests back
agriyakhetarpal Jun 7, 2026
a0f5420
Discard changes to pyodide_build/xbuildenv.py
agriyakhetarpal Jun 7, 2026
29ef6e8
Add back existence guard in `get_unisolated_packages`
agriyakhetarpal Jun 7, 2026
a95de42
Fix case-sensitivity issue in `_replace_unisolated_packages`
agriyakhetarpal Jun 7, 2026
37bbc6f
Rename `symlink_unisolated_packages` to something better
agriyakhetarpal Jun 7, 2026
c0a3603
Use `shutil.copytree` for cross-build file copying
agriyakhetarpal Jun 7, 2026
afdbe68
Add tests for getting unisolated packages
agriyakhetarpal Jun 7, 2026
9d89aa7
Tests for unisolated package name normalisation
agriyakhetarpal Jun 7, 2026
4fdbf9c
Tests for cross-build file installation
agriyakhetarpal Jun 7, 2026
905925b
Drop unnecessary list conversion
agriyakhetarpal Jun 27, 2026
44e6da0
Invert condition for matched packages
agriyakhetarpal Jun 27, 2026
0772d46
Rename `get_unisolated_files` to `get_cross_build_files_dir`
agriyakhetarpal Jun 27, 2026
981b099
Simplify CHANGELOG entry
agriyakhetarpal Jun 27, 2026
e523091
Simplify tests for cross-build files checking
agriyakhetarpal Jun 27, 2026
a1ea4be
Simplify Fortran package recipe
agriyakhetarpal Jun 27, 2026
a9d4841
Repack dummy xbuildenv without `unisolated.txt`
agriyakhetarpal Jun 27, 2026
a898657
Update test to handle unisolated package version mismatch warning
agriyakhetarpal Jun 27, 2026
53e5f91
Add line in between
agriyakhetarpal Jun 27, 2026
1e82983
Merge branch 'main' into no-host-site
agriyakhetarpal Jun 27, 2026
38edec2
Explicitly reject `oldest-supported-numpy`
agriyakhetarpal Jun 27, 2026
2c05513
Raise `FileNotFoundError` for non-existent xbuildenv requirements file
agriyakhetarpal Jun 27, 2026
8e682f9
Add comment about skipping cross-build file installation
agriyakhetarpal Jun 27, 2026
a8f63ff
Shapely was using oldest-supported-numpy, bump its version
agriyakhetarpal Jun 27, 2026
a5bbea2
Revert "Shapely was using oldest-supported-numpy, bump its version"
agriyakhetarpal Jun 27, 2026
ea0f514
Evaluate PEP 508 markers for build-time reqs
agriyakhetarpal Jun 27, 2026
78cc998
Same bug for removing avoided requirements
agriyakhetarpal Jun 27, 2026
86104b9
Fix order in CHANGELOG + adjust version
agriyakhetarpal Jun 27, 2026
cb3f8a8
Add `numpy.pc` through `PKG_CONFIG_LIBDIR`
agriyakhetarpal Jun 27, 2026
c90969e
Revert oldest-supported-numpy change for now
agriyakhetarpal Jun 30, 2026
304bab0
Add comment about PEP 508 and `evaluate()`
agriyakhetarpal Jun 30, 2026
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
12 changes: 9 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [0.36.0] - 2026/MM/DD

### Fixed

Expand Down Expand Up @@ -50,6 +50,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
setting `UV_BUILD_CONSTRAINT` alongside `PIP_CONSTRAINT` and `PIP_BUILD_CONSTRAINT`.
[#389](https://github.com/pyodide/pyodide-build/pull/389)

### Changed

- Fixed build-time scripts of unisolated packages (like `f2py` and
`numpy-config` from NumPy) not being available on `PATH` during builds.
[#21](https://github.com/pyodide/pyodide-build/pull/21)

## [0.35.1] - 2026/06/13

### Fixed
Expand Down Expand Up @@ -222,12 +228,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Added `pyodide clean recipes`, a CLI command that deletes build files for chosen packages or tags.
[#254](https://github.com/pyodide/pyodide-build/pull/254)
[#254](https://github.com/pyodide/pyodide-build/pull/254)

## [0.30.8] - 2025/10/22

- `pyodide config` now exposes `dist_dir` variable.
[#236](https://github.com/pyodide/pyodide-build/pull/236)
[#236](https://github.com/pyodide/pyodide-build/pull/236)

- The CMake toolchain file for Pyodide now sets `CMAKE_SHARED_LINKER_FLAGS_INIT` and `CMAKE_MODULE_LINKER_FLAGS_INIT` and
unset `CMAKE_SHARED_LINKER_FLAGS` to avoid conflicts with the user's settings.
Expand Down
1 change: 1 addition & 0 deletions integration_tests/recipes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This directory contains a few curated recipes to test the build process of pyodi
- `pydoc_data`: Unvendored cpython module
- `boost-histogram``: Tests scikit-build-core and cmake build system.
- `colorama`: Uses prebuilt wheel as source to check test file unvendoring capabilities.
- `numpy-scripts-example`: Tests that unisolated package scripts (say, `f2py` or `numpy-config` from NumPy as a build dependency) are available on PATH during builds.

### For maintainers

Expand Down
23 changes: 23 additions & 0 deletions integration_tests/recipes/numpy-scripts-example/meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package:
name: numpy-scripts-example
version: 0.1.0
top-level:
- numpy_scripts_example

source:
path: source

requirements:
host:
- numpy
run:
- numpy

about:
home: https://github.com/pyodide/pyodide-build
summary: Minimal integration test that verifies f2py and numpy-config are on PATH during the build
license: MIT

extra:
recipe-maintainers:
- agriyakhetarpal
32 changes: 32 additions & 0 deletions integration_tests/recipes/numpy-scripts-example/source/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
project('numpy-scripts-example', 'c',
version: '0.1.0',
license: 'MIT',
meson_version: '>= 1.3.0',
)

py_mod = import('python')
py3 = py_mod.find_installation()
py3_dep = py3.dependency()

# The only point of this recipe is to verify that NumPy's console scripts
# are discoverable on PATH when it is a build-time dependency.
f2py = find_program('f2py')
numpy_cflags = run_command('numpy-config', '--cflags', check: true).stdout().strip().split()

incdir_numpy = run_command(py3,
['-c', 'import numpy; print(numpy.get_include())'],
check: true,
).stdout().strip()

py3.install_sources(['numpy_scripts_example/__init__.py'],
pure: false,
subdir: 'numpy_scripts_example')

py3.extension_module('_add',
'numpy_scripts_example/_add.c',
include_directories: incdir_numpy,
c_args: numpy_cflags,
dependencies: py3_dep,
install: true,
subdir: 'numpy_scripts_example',
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from ._add import add

__all__ = ["add"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <numpy/arrayobject.h>

static PyObject *
add(PyObject *self, PyObject *args)
{
double a, b;
if (!PyArg_ParseTuple(args, "dd", &a, &b))
return NULL;
return PyFloat_FromDouble(a + b);
}

static PyMethodDef methods[] = {
{"add", add, METH_VARARGS, "Add two floats."},
{NULL, NULL, 0, NULL}
};

static struct PyModuleDef module = {
PyModuleDef_HEAD_INIT, "_add", NULL, -1, methods
};

PyMODINIT_FUNC
PyInit__add(void)
{
import_array();
return PyModule_Create(&module);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[build-system]
build-backend = "mesonpy"
requires = ["meson-python", "numpy"]

[project]
name = "numpy-scripts-example"
version = "0.1.0"
requires-python = ">=3.9"
dependencies = ["numpy"]
72 changes: 62 additions & 10 deletions pyodide_build/build_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ def get_build_environment_vars(pyodide_root: Path) -> dict[str, str]:
"PYODIDE": "1",
# This is the legacy environment variable used for the aforementioned purpose
"PYODIDE_PACKAGE_ABI": "1",
"PYTHONPATH": env["HOSTSITEPACKAGES"],
}
)

Expand Down Expand Up @@ -220,29 +219,82 @@ def get_hostsitepackages() -> str:
return get_build_flag("HOSTSITEPACKAGES")


# TODO: Remove this function (and use remote package index)
# https://github.com/pyodide/pyodide-build/issues/43
@functools.cache
def get_unisolated_packages() -> list[str]:
# TODO: Remove this function (and use remote package index)
# https://github.com/pyodide/pyodide-build/issues/43
def get_unisolated_packages() -> dict[str, str]:
"""
Get a map of unisolated packages.

Unisolated packages are packages that are used during the build process
and have some platform-specific files. When these packages are used
during the build process, their platform-specific files are replaced with
WASM-compatible versions to build the package correctly.

Comment thread
agriyakhetarpal marked this conversation as resolved.
Returns
-------
A dictionary of package names and versions.
"""
PYODIDE_ROOT = get_pyodide_root()

unisolated_file = PYODIDE_ROOT / "unisolated.txt"
if unisolated_file.exists():
# in xbuild env, read from file
unisolated_packages = unisolated_file.read_text().splitlines()
unisolated_packages: dict[str, str] = {}
if in_xbuildenv():
unisolated_packages_file = PYODIDE_ROOT / ".." / "requirements.txt"
Comment thread
ryanking13 marked this conversation as resolved.

if not unisolated_packages_file.exists():
raise FileNotFoundError(
f"Expected {unisolated_packages_file} to exist in the xbuildenv. "
"The xbuildenv archive may be corrupt or from an incompatible version."
)
for line in unisolated_packages_file.read_text().splitlines():
line = line.strip()
# The xbuildenv requirements.txt is machine-generated and always
# uses pinned name==version entries, but we skip blank lines,
# comments, and any non-pinned specs just in case. Shouldn't
# really happen though.
if not line or line.startswith("#") or "==" not in line:
continue
name, version = line.split("==", 1)
unisolated_packages[name] = version
else:
from pyodide_build.recipe.loader import load_all_recipes

unisolated_packages = []
recipe_dir = PYODIDE_ROOT / "packages"
recipes = load_all_recipes(recipe_dir)
for name, config in recipes.items():
if config.build.cross_build_env:
unisolated_packages.append(name)
unisolated_packages[name] = config.package.version

return unisolated_packages


def get_cross_build_files_dir(package_name: str) -> Path:
"""
Get the directory containing an unisolated package's cross-build files
(such as headers, .a libs, .pxd files, and so on).

Parameters
----------
package_name
The name of the package

Returns
-------
The directory containing the package's cross-build files, relative to
which they should be laid out in site-packages. The directory may not
exist if the package has no cross-build files.
"""
PYODIDE_ROOT = get_pyodide_root()

# TODO: unify libdir for in-tree and out-of-tree builds
if in_xbuildenv():
libdir = PYODIDE_ROOT / ".." / "site-packages-extras"
else:
libdir = Path(get_hostsitepackages())

return libdir / package_name


def platform() -> str:
emscripten_version = get_build_flag("PYODIDE_EMSCRIPTEN_VERSION")
version = emscripten_version.replace(".", "_")
Expand Down
Loading
Loading