Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
83 changes: 80 additions & 3 deletions recipes/recipes_emscripten/scipy/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ sed -i 's/void BLAS_FUNC/int BLAS_FUNC/g' scipy/special/lapack_defs.h
sed -i 's/extern void/extern int/g' scipy/optimize/__minpack.h
sed -i 's/void/int/g' scipy/linalg/cython_blas_signatures.txt
sed -i 's/void/int/g' scipy/linalg/cython_lapack_signatures.txt
sed -i 's/^void/int/g' scipy/linalg/_common_array_utils.h

sed -i 's/^void/int/g' scipy/interpolate/src/_fitpackmodule.c
sed -i 's/^void/int/g' scipy/interpolate/src/__fitpack.h
sed -i 's/^void/int/g' scipy/interpolate/src/__fitpack.cc
sed -i 's/void BLAS_FUNC/int BLAS_FUNC/g' scipy/interpolate/src/__fitpack.h

sed -i 's/double z_abs(/double my_z_abs(/g' scipy/sparse/linalg/_dsolve/SuperLU/SRC/dcomplex.c

Expand All @@ -45,13 +50,32 @@ sed -i 's/^void/int/g' scipy/sparse/linalg/_dsolve/*.{c,h}
sed -i 's/void \(.\)print/int \1/g' scipy/sparse/linalg/_dsolve/SuperLU/SRC/*.{c,h}
sed -i 's/TYPE_GENERIC_FUNC(\(.*\), void)/TYPE_GENERIC_FUNC(\1, int)/g' scipy/sparse/linalg/_dsolve/_superluobject.h

sed -i 's/^void/int/g' scipy/optimize/__nnls.h
sed -i 's/^void/int/g' scipy/optimize/__nnls.c
sed -i 's/^void/int/g' scipy/optimize/__slsqp.h
sed -i 's/^void/int/g' scipy/optimize/__slsqp.c
sed -i 's/^static void/static int/g' scipy/optimize/__slsqp.c

sed -i 's/^void/int/g' scipy/optimize/_trlib/trlib_private.h
sed -i 's/^void/int/g' scipy/optimize/_trlib/trlib/trlib_private.h
sed -i 's/^void/int/g' scipy/_build_utils/src/wrap_dummy_g77_abi.c
sed -i 's/, int)/)/g' scipy/optimize/_trlib/trlib_private.h
sed -i 's/, 1)/)/g' scipy/optimize/_trlib/trlib_private.h

sed -i 's/^void/int/g' scipy/linalg/_matfuncs_expm.h
sed -i 's/^void/int/g' scipy/linalg/_matfuncs_expm.c
sed -i 's/^void/int/g' scipy/linalg/_matfuncs_sqrtm.h
sed -i 's/^void/int/g' scipy/linalg/_matfuncs_sqrtm.c

sed -i 's/^void/int/g' scipy/sparse/linalg/_eigen/arpack/ARPACK/_arpack_n_double_complex.h
sed -i 's/^void/int/g' scipy/sparse/linalg/_eigen/arpack/ARPACK/_arpack_n_double.h
sed -i 's/^void/int/g' scipy/sparse/linalg/_eigen/arpack/ARPACK/_arpack_n_single_complex.h
sed -i 's/^void/int/g' scipy/sparse/linalg/_eigen/arpack/ARPACK/_arpack_n_single.h
sed -i 's/^void/int/g' scipy/sparse/linalg/_eigen/arpack/ARPACK/_arpack_s_double.h
sed -i 's/^void/int/g' scipy/sparse/linalg/_eigen/arpack/ARPACK/_arpack_s_single.h

sed -i 's/^void/int/g' scipy/spatial/qhull_misc.h
sed -i 's/^void/int/g' scipy/optimize/__lbfgsb.h
sed -i 's/, size_t)/)/g' scipy/spatial/qhull_misc.h
sed -i 's/,1)/)/g' scipy/spatial/qhull_misc.h

Expand All @@ -74,16 +98,44 @@ export EMBIN=$CONDA_EMSDK_DIR/upstream/emscripten
python $RECIPE_DIR/inject_compiler_wrapper.py $EMBIN/emcc.py

# add BUILD_PREFIX/include for f2c.h file
export CFLAGS="$CFLAGS -I$BUILD_PREFIX/include -Wno-return-type -DUNDERSCORE_G77 -s WASM_BIGINT"
export LDFLAGS="$LDFLAGS -s WASM_BIGINT"
# Fix LONG_BIT issue: Python's pyport.h checks LONG_BIT and errors if it doesn't match expectations
# We need to patch pyport.h to undefine LONG_BIT before the check (same as Python recipe patch 0005)
if [ -f "$BUILD_PREFIX/include/python${PY_VER}/pyport.h" ]; then
# Apply the same fix as Python recipe patch 0005: add #undef LONG_BIT before the check
if ! grep -q "^#undef LONG_BIT" "$BUILD_PREFIX/include/python${PY_VER}/pyport.h"; then
# Find the line with "#ifndef LONG_BIT" and add "#undef LONG_BIT" before it
sed -i '/^#ifndef LONG_BIT/i#undef LONG_BIT' "$BUILD_PREFIX/include/python${PY_VER}/pyport.h"
fi
fi
# Note: -s WASM_BIGINT is a linker flag, not a compiler flag
# Suppress incompatible function pointer type errors (due to void->int function changes)
# Set visibility=default for C++ symbols to fix "bad export type" errors (e.g., _ZTIPFvbE)
# NumPy 2.1+ disabled visibility for symbols outside of extension modules by default,
# so we need to explicitly set visibility=default for SciPy modules that rely on NumPy symbols
# Use single quotes around the entire macro definition to preserve the inner double quotes
# The quotes in NPY_API_SYMBOL_ATTRIBUTE will cause a syntax error in the generated __config__.py
# We'll fix this in the post-install step below
export CFLAGS="$CFLAGS -I$BUILD_PREFIX/include -Wno-return-type -DUNDERSCORE_G77 -Wno-incompatible-function-pointer-types -DNPY_API_SYMBOL_ATTRIBUTE='__attribute__((visibility(\"default\")))' -fvisibility=default"
export CXXFLAGS="$CXXFLAGS -Wno-incompatible-function-pointer-types -fvisibility=default"
# Add numpy library paths to LDFLAGS for linking
# Get numpy installation path using Python
NUMPY_LIB=$(python -c "import numpy; import os; print(os.path.dirname(numpy.__file__))")
# Build Python extension modules as side modules to ensure PyInit functions are exported
# SIDE_MODULE=1 is required for Python extension modules in Emscripten
# EXPORT_ALL=1 is required to export all symbols from the extension module (e.g. HiGHS)
export LDFLAGS="$LDFLAGS -s WASM_BIGINT -s EXPORT_ALL=1 -s SIDE_MODULE=1 -L${NUMPY_LIB}/_core/lib -L${NUMPY_LIB}/random/lib"




#############################################################
# write out the cross file
#############################################################
export NUMPY_INCLUDE_DIR="$BUILD_PREFIX/lib/python${PY_VER}/site-packages/numpy/_core/include"
# Get numpy include directory using Python - resolve to actual filesystem path
NUMPY_INCLUDE_DIR=$(python -c "import numpy; import os; numpy_dir = os.path.dirname(numpy.__file__); include_dir = os.path.join(numpy_dir, '_core', 'include'); print(os.path.abspath(os.path.realpath(include_dir)))")
export NUMPY_INCLUDE_DIR
echo "NUMPY_INCLUDE_DIR=${NUMPY_INCLUDE_DIR}"
# Use | as delimiter for sed
sed "s|@(NUMPY_INCLUDE_DIR)|${NUMPY_INCLUDE_DIR}|g" $RECIPE_DIR/emscripten.meson.cross > $SRC_DIR/emscripten.meson.cross.temp
sed "s|@(PYTHON)|${PYTHON}|g" $SRC_DIR/emscripten.meson.cross.temp > $SRC_DIR/emscripten.meson.cross
rm $SRC_DIR/emscripten.meson.cross.temp
Expand All @@ -99,3 +151,28 @@ export PKG_CONFIG_PATH=$SRC_DIR=openblas.pc
MESON_ARGS="-Dfortran_std=none" ${PYTHON} -m pip install . -vvv --no-deps --no-build-isolation \
-Csetup-args="--cross-file=$SRC_DIR/emscripten.meson.cross"\
-Csetup-args="-Dfortran_std=none"

# Fix syntax error in generated __config__.py: escape quotes in NPY_API_SYMBOL_ATTRIBUTE
# Meson writes the CFLAGS to the config file, and the double quotes break Python syntax
# The config file is generated during build, so we need to find and fix it after pip install
# Look for __config__.py in the site-packages directory
if [ -d "$SP_DIR/scipy" ]; then
SCIPY_CONFIG="$SP_DIR/scipy/__config__.py"
elif [ -n "$PREFIX" ] && [ -d "$PREFIX/lib/python${PY_VER}/site-packages/scipy" ] && [ -f "$PREFIX/lib/python${PY_VER}/site-packages/scipy/__config__.py" ]; then
SCIPY_CONFIG="$PREFIX/lib/python${PY_VER}/site-packages/scipy/__config__.py"
else
# Try to find it using Python
SCIPY_CONFIG=$(python -c "import scipy; import os; print(os.path.join(os.path.dirname(scipy.__file__), '__config__.py'))" 2>/dev/null || echo "")
fi

if [ -n "$SCIPY_CONFIG" ] && [ -f "$SCIPY_CONFIG" ]; then
echo "Fixing syntax error in $SCIPY_CONFIG"
# Replace unescaped double quotes in the visibility("default") part with escaped quotes
# This fixes: visibility("default") -> visibility(\"default\")
# Need to escape both the quotes and the backslashes for sed
sed -i 's/visibility("default")/visibility(\\"default\\")/g' "$SCIPY_CONFIG"
echo "Fixed config file syntax"
else
echo "Warning: Could not find scipy/__config__.py to fix syntax error"
echo "Searched in: $SP_DIR/scipy, $PREFIX/lib/python${PY_VER}/site-packages/scipy, $SRC_DIR/scipy"
fi
7 changes: 6 additions & 1 deletion recipes/recipes_emscripten/scipy/emscripten.meson.cross
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
needs_exe_wrapper = true
skip_sanity_check = true
longdouble_format = 'IEEE_QUAD_LE' # for numpy
#numpy-include-dir = '@(NUMPY_INCLUDE_DIR)'
numpy-include-dir = '@(NUMPY_INCLUDE_DIR)'

[built-in options]
# Set visibility=default for C++ symbols to fix "bad export type" errors
# This applies to all subprojects including HiGHS, which needs its C++ symbols exported
cpp_args = ['-fvisibility=default']


[host_machine]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
From 45a31145679c83f2719b6420f234d484b9459697 Mon Sep 17 00:00:00 2001
From: Hood Chatham <[email protected]>
Date: Fri, 18 Mar 2022 16:25:39 -0700
Subject: [PATCH 1/18] Fix dstevr in special/lapack_defs.h
Subject: [PATCH 1/14] Fix dstevr in special/lapack_defs.h

---
scipy/special/lapack_defs.h | 5 ++---
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
From d53ade3f03ba3557fd50fb38990d605f4ae7f8f1 Mon Sep 17 00:00:00 2001
From: Hood Chatham <[email protected]>
Date: Sat, 25 Dec 2021 18:04:18 -0800
Subject: [PATCH 2/18] int to string
Subject: [PATCH 2/14] int to string

f2c does not handle implicit casts of function arguments correctly. The msg
argument of `xerrwv` is defined to be an `int *`, and then implicitly cast
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
From e528227dd37c8b0512381992c222789a114e3169 Mon Sep 17 00:00:00 2001
From: Hood Chatham <[email protected]>
Date: Sat, 18 Dec 2021 11:41:15 -0800
Subject: [PATCH 3/18] gemm_ no const
Subject: [PATCH 3/14] gemm_ no const

cgemm, dgemm, sgemm, and zgemm are declared with `const` in slu_cdefs.h, but
other places don't have the cosnt causing compile errors.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
From a86a2304fd925f815bbb0e0753e46a7b863e2de2 Mon Sep 17 00:00:00 2001
From: Joe Marshall <[email protected]>
Date: Wed, 6 Apr 2022 21:25:13 -0700
Subject: [PATCH 4/18] make int return values
Subject: [PATCH 4/14] make int return values

The return values of f2c functions are insignificant in most cases, so often it
is treated as returning void, when it really should return int (values are
Expand Down Expand Up @@ -240,21 +240,20 @@ index 67e83bcc77..e5757d5c4d 100644

/* Macro definitions */
diff --git a/scipy/sparse/linalg/_dsolve/SuperLU/SRC/slu_scomplex.h b/scipy/sparse/linalg/_dsolve/SuperLU/SRC/slu_scomplex.h
index 83be8c971f..047a07ce9c 100644
index 1e53fbca5..b35313ccb 100644
--- a/scipy/sparse/linalg/_dsolve/SuperLU/SRC/slu_scomplex.h
+++ b/scipy/sparse/linalg/_dsolve/SuperLU/SRC/slu_scomplex.h
@@ -27,8 +27,9 @@ at the top-level directory.

@@ -28,7 +28,9 @@ at the top-level directory.
#ifndef SCOMPLEX_INCLUDE
#define SCOMPLEX_INCLUDE
-
-typedef struct { float r, i; } singlecomplex;
+#include"scipy_slu_config.h"
+#include "scipy_slu_config.h"
+// defined in CLAPACK
+//typedef struct { float r, i; } singlecomplex;


/* Macro definitions */
#if defined(SUPERLU_TYPEDEF_COMPLEX) || DOXYGEN
//! \brief backward compatibility with older versions of SuperLU
diff --git a/scipy/sparse/linalg/_dsolve/_superlu_utils.c b/scipy/sparse/linalg/_dsolve/_superlu_utils.c
index 49b928a431..0822687719 100644
--- a/scipy/sparse/linalg/_dsolve/_superlu_utils.c
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
From c784d3a1ee38da88943364de4ea847a3b9cd155f Mon Sep 17 00:00:00 2001
From: Hood Chatham <[email protected]>
Date: Tue, 30 Aug 2022 11:51:53 -0700
Subject: [PATCH 5/18] Fix fitpack
Subject: [PATCH 5/14] Fix fitpack

---
scipy/interpolate/fitpack/dblint.f | 9 ++++-----
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
From 8addc1da35bc63df651946ef14c723797a431e0c Mon Sep 17 00:00:00 2001
From: Hood Chatham <[email protected]>
Date: Mon, 26 Jun 2023 20:12:25 -0700
Subject: [PATCH 6/18] Fix gees calls
Subject: [PATCH 6/14] Fix gees calls

---
scipy/linalg/flapack_gen.pyf.src | 8 ++++----
Expand Down
Loading
Loading