Add support for backend flags to buildpkg (#2690)

And use it to disable numpy optimization by passing the `--disable-optimization` 
flag instead of patching numpy.
This commit is contained in:
Hood Chatham 2022-06-13 16:40:48 -07:00 committed by GitHub
parent 07322414e8
commit 2d056ed253
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 39 additions and 35 deletions

View File

@ -103,6 +103,10 @@ Extra arguments to pass to the linker when building for WebAssembly.
(This key is not in the Conda spec).
### `build/backend-flags`
Extra flags to pass to the build backend (e.g., `setuptools`, `flit`, etc).
### `build/library`
Should be set to true for library packages. Library packages are packages that are needed for other packages but are not Python packages themselves. For library packages, the script specified in the `build/script` section is run to compile the library. See the [zlib meta.yaml](https://github.com/pyodide/pyodide/blob/main/packages/zlib/meta.yaml) for an example of a library package specification.

View File

@ -10,12 +10,12 @@ source:
- patches/0001-make-int-return-values.patch
- patches/0002-MAINT-BLD-Fix-math-feature-detection-for-wasm.patch
- patches/0003-BUG-Fix-the-return-type-of-random_float_fill.patch
- patches/0004-disable-optimization.patch
- patches/0005-Fix-ieee754.patch
- patches/0006-not-build-lapack-lite-as-64-bit.patch
- patches/0001-ENH-cross-compilation-use-sysconfig-to-determine-if-.patch
build:
backend-flags: --disable-optimization
cflags: |
-Wno-return-type
cross-build-env: true

View File

@ -1,26 +0,0 @@
From 97b588ab3e321cc0fe6b226f6b2eb3c5ae05bc09 Mon Sep 17 00:00:00 2001
From: Hood Chatham <roberthoodchatham@gmail.com>
Date: Thu, 31 Mar 2022 17:17:30 -0700
Subject: [PATCH 4/7] disable optimization
This is to disable SIMD optimization until SAFARI has good support for it.
---
numpy/distutils/command/build.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/numpy/distutils/command/build.py b/numpy/distutils/command/build.py
index a4fda537d..11fffe282 100644
--- a/numpy/distutils/command/build.py
+++ b/numpy/distutils/command/build.py
@@ -37,7 +37,7 @@ def initialize_options(self):
self.warn_error = False
self.cpu_baseline = "min"
self.cpu_dispatch = "max -xop -fma4" # drop AMD legacy features by default
- self.disable_optimization = False
+ self.disable_optimization = True
"""
the '_simd' module is a very large. Adding more dispatched features
will increase binary size and compile time. By default we minimize
--
2.25.1

View File

@ -444,6 +444,7 @@ def compile(
pywasmcross.compile(
env=bash_runner.env,
pkgname=name,
backend_flags=build_metadata["backend-flags"],
cflags=build_metadata["cflags"],
cxxflags=build_metadata["cxxflags"],
ldflags=build_metadata["ldflags"],
@ -878,6 +879,7 @@ def main(args):
pkg["source"] = pkg.get("source", {})
pkg["build"] = pkg.get("build", {})
build_metadata = pkg["build"]
build_metadata["backend-flags"] = build_metadata.get("backend-flags", "")
build_metadata["cflags"] = build_metadata.get("cflags", "")
build_metadata["cxxflags"] = build_metadata.get("cxxflags", "")
build_metadata["ldflags"] = build_metadata.get("ldflags", "")

View File

@ -19,6 +19,7 @@ PACKAGE_CONFIG_SPEC: dict[str, dict[str, Any]] = {
"extras": list, # List[Tuple[str, str]],
},
"build": {
"backend-flags": str,
"cflags": str,
"cxxflags": str,
"ldflags": str,

View File

@ -7,7 +7,7 @@ from itertools import chain
from pathlib import Path
from typing import Generator, Mapping
from build import BuildBackendException, ProjectBuilder
from build import BuildBackendException, ConfigSettingsType, ProjectBuilder
from build.__main__ import (
_STYLES,
_error,
@ -74,6 +74,7 @@ def _build_in_isolated_env(
builder: ProjectBuilder,
outdir: str,
distribution: str,
config_settings: ConfigSettingsType,
) -> str:
# For debugging: The following line disables removal of the isolated venv.
# It will be left in the /tmp folder and can be inspected or entered as
@ -87,7 +88,7 @@ def _build_in_isolated_env(
install_reqs(env, builder.build_system_requires)
installed_requires_for_build = False
try:
build_reqs = builder.get_requires_for_build(distribution)
build_reqs = builder.get_requires_for_build(distribution, config_settings)
except BuildBackendException:
pass
else:
@ -96,19 +97,38 @@ def _build_in_isolated_env(
with replace_env(build_env):
if not installed_requires_for_build:
install_reqs(env, builder.get_requires_for_build(distribution))
return builder.build(distribution, outdir, {})
install_reqs(
env, builder.get_requires_for_build(distribution, config_settings)
)
return builder.build(distribution, outdir, config_settings)
def build(build_env: Mapping[str, str]) -> None:
def parse_backend_flags(backend_flags: str) -> ConfigSettingsType:
config_settings: dict[str, str | list[str]] = {}
for arg in backend_flags.split():
setting, _, value = arg.partition("=")
if setting not in config_settings:
config_settings[setting] = value
continue
cur_value = config_settings[setting]
if isinstance(cur_value, str):
config_settings[setting] = [cur_value, value]
else:
cur_value.append(value)
return config_settings
def build(build_env: Mapping[str, str], backend_flags: str) -> None:
srcdir = Path.cwd()
outdir = srcdir / "dist"
builder = _ProjectBuilder(str(srcdir))
distribution = "wheel"
config_settings = parse_backend_flags(backend_flags)
try:
with _handle_build_error():
built = _build_in_isolated_env(
build_env, builder, str(outdir), distribution
build_env, builder, str(outdir), distribution, config_settings
)
print("{bold}{green}Successfully built {}{reset}".format(built, **_STYLES))
except Exception as e: # pragma: no cover

View File

@ -80,6 +80,7 @@ def compile(
env: dict[str, str],
*,
pkgname: str,
backend_flags: str,
cflags: str,
cxxflags: str,
ldflags: str,
@ -88,6 +89,7 @@ def compile(
) -> None:
kwargs = dict(
pkgname=pkgname,
backend_flags=backend_flags,
cflags=cflags,
cxxflags=cxxflags,
ldflags=ldflags,
@ -96,6 +98,7 @@ def compile(
)
args = environment_substitute_args(kwargs, env)
backend_flags = args.pop("backend_flags")
args["builddir"] = str(Path(".").absolute())
env = dict(env)
@ -109,10 +112,10 @@ def compile(
env["_PYTHON_HOST_PLATFORM"] = common.platform()
env["_PYTHON_SYSCONFIGDATA_NAME"] = os.environ["SYSCONFIG_NAME"]
from pyodide_build.pypabuild import build
from .pypabuild import build
try:
build(env)
build(env, backend_flags)
except BaseException:
build_log_path = Path("build.log")
if build_log_path.exists():