Skip to content

Commit

Permalink
Allow overriding _f2c_fixes.py from user (#8)
Browse files Browse the repository at this point in the history
While most parts of pyodide-build are decoupled with pyodide/pyodide,
`_f2c_fixes.py` file that is used to build scipy is highly coupled with
the scipy recipe in pyodide/pyodide.

It would be very inefficient if we need to update pyodide-build whenever
we fix scipy (e.g. pyodide/pyodide#4818).
Therefore, this add a private config variable `_f2c_fixes_wrapper`,
which allows users to modify override `_f2c_fixes.py` file without
touching pyodide-build itself.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
ryanking13 and pre-commit-ci[bot] authored Jul 17, 2024
1 parent 833135c commit fac0109
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 6 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

## [0.27.3] - 2024/07/17

- It is now possible to override `_f2c_fixes.py` file, with `_f2c_fixes_wrapper` variable.
[#8](https://github.com/pyodide/pyodide-build/pull/8)

## [0.27.2] - 2024/07/11

## Changed
Expand Down
6 changes: 6 additions & 0 deletions pyodide_build/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ def to_env(self) -> dict[str, str]:
"home": "HOME",
"path": "PATH",
"zip_compression_level": "PYODIDE_ZIP_COMPRESSION_LEVEL",
# maintainer only
"_f2c_fixes_wrapper": "_F2C_FIXES_WRAPPER",
}

BUILD_VAR_TO_KEY = {v: k for k, v in BUILD_KEY_TO_VAR.items()}
Expand All @@ -181,6 +183,8 @@ def to_env(self) -> dict[str, str]:
"ldflags",
"rust_toolchain",
"meson_cross_file",
# maintainer only
"_f2c_fixes_wrapper",
}

# Default configuration values.
Expand All @@ -197,6 +201,8 @@ def to_env(self) -> dict[str, str]:
"rust_toolchain": "nightly-2024-01-29",
# Other configuration
"pyodide_jobs": "1",
# maintainer only
"_f2c_fixes_wrapper": "",
}

# Default configs that are computed from other values (often from Makefile.envs)
Expand Down
16 changes: 13 additions & 3 deletions pyodide_build/pypabuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from build.env import DefaultIsolatedEnv
from packaging.requirements import Requirement

from . import common, pywasmcross
from . import _f2c_fixes, common, pywasmcross
from .build_env import (
get_build_flag,
get_hostsitepackages,
Expand Down Expand Up @@ -214,10 +214,20 @@ def make_command_wrapper_symlinks(symlink_dir: Path) -> dict[str, str]:
The dictionary of compiler environment variables that points to the symlinks.
"""

# For maintainers:
# - you can set "_f2c_fixes_wrapper" variable in pyproject.toml
# in order to change the script to use when cross-compiling
# this is only for maintainers and *should* not be used by others

pywasmcross_exe = symlink_dir / "pywasmcross.py"
shutil.copy2(pywasmcross.__file__, pywasmcross_exe)
pywasmcross_origin = pywasmcross.__file__
shutil.copy2(pywasmcross_origin, pywasmcross_exe)
pywasmcross_exe.chmod(0o755)

f2c_fixes_exe = symlink_dir / "_f2c_fixes.py"
f2c_fixes_origin = get_build_flag("_F2C_FIXES_WRAPPER") or _f2c_fixes.__file__
shutil.copy2(f2c_fixes_origin, f2c_fixes_exe)

env = {}
for symlink in pywasmcross.SYMLINKS:
symlink_path = symlink_dir / symlink
Expand Down Expand Up @@ -266,7 +276,7 @@ def get_build_env(
env.update(make_command_wrapper_symlinks(symlink_dir))

sysconfig_dir = Path(get_build_flag("TARGETINSTALLDIR")) / "sysconfigdata"
args["PYTHONPATH"] = sys.path + [str(sysconfig_dir)]
args["PYTHONPATH"] = sys.path + [str(symlink_dir), str(sysconfig_dir)]
args["orig__name__"] = __name__
args["pythoninclude"] = get_build_flag("PYTHONINCLUDE")
args["PATH"] = env["PATH"]
Expand Down
4 changes: 2 additions & 2 deletions pyodide_build/pywasmcross.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ def handle_command(
"""

if line[0] == "gfortran":
from pyodide_build._f2c_fixes import replay_f2c
from _f2c_fixes import replay_f2c

tmp = replay_f2c(line)
if tmp is None:
Expand All @@ -604,7 +604,7 @@ def handle_command(
new_args = handle_command_generate_args(line, build_args)

if build_args.pkgname == "scipy":
from pyodide_build._f2c_fixes import scipy_fixes
from _f2c_fixes import scipy_fixes

scipy_fixes(new_args)

Expand Down
20 changes: 19 additions & 1 deletion pyodide_build/tests/test_pypabuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,25 @@ def test_make_command_wrapper_symlinks(tmp_path):
assert key in pypabuild.SYMLINK_ENV_VARS.values()


def test_get_build_env(tmp_path):
def test_make_command_wrapper_symlinks_f2c_wrapper(
tmp_path, dummy_xbuildenv, reset_env_vars, reset_cache
):
import os

dummy_f2c_wrapper = tmp_path / "_dummy_f2c_fixes.py"
dummy_f2c_wrapper.write_text("print('Hello, world!')")

os.environ["_F2C_FIXES_WRAPPER"] = str(dummy_f2c_wrapper)

symlink_dir = tmp_path
pypabuild.make_command_wrapper_symlinks(symlink_dir)

wrapper = symlink_dir / "_f2c_fixes.py"
assert wrapper.exists()
assert wrapper.read_text() == dummy_f2c_wrapper.read_text()


def test_get_build_env(tmp_path, dummy_xbuildenv):
build_env_ctx = pypabuild.get_build_env(
env={"PATH": ""},
pkgname="",
Expand Down

0 comments on commit fac0109

Please sign in to comment.