Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3f8d0ef

Browse files
committedMar 27, 2025
scipy: update to v1.15.2
1 parent fbd5255 commit 3f8d0ef

File tree

9 files changed

+498
-1209
lines changed

9 files changed

+498
-1209
lines changed
 

‎pythonforandroid/recipe.py

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class Recipe(metaclass=RecipeMeta):
7676

7777
_version = None
7878
'''A string giving the version of the software the recipe describes,
79-
e.g. ``2.0.3`` or ``master``.'''
79+
e.g. ``2.0.3``. In case of git repository version is branch or a tagged release e.g. ``v12.3`` or ``develop``.'''
8080

8181
md5sum = None
8282
'''The md5sum of the source from the :attr:`url`. Non-essential, but
@@ -109,7 +109,7 @@ class Recipe(metaclass=RecipeMeta):
109109
recipe if they are built at all, but whose presence is not essential.'''
110110

111111
patches = []
112-
'''A list of patches to apply to the source. Values can be either a string
112+
'''Alist of patches to apply to the source. Values can be either a string
113113
referring to the patch file relative to the recipe dir, or a tuple of the
114114
string patch file and a callable, which will receive the kwargs `arch` and
115115
`recipe`, which should return True if the patch should be applied.'''
@@ -155,6 +155,11 @@ class Recipe(metaclass=RecipeMeta):
155155
starting from NDK r18 the `gnustl_shared` lib has been deprecated.
156156
'''
157157

158+
min_ndk_api_support = 20
159+
'''
160+
Minimum ndk api your recipe will support
161+
'''
162+
158163
def get_stl_library(self, arch):
159164
return join(
160165
arch.ndk_lib_dir,
@@ -252,23 +257,20 @@ def report_hook(index, blksize, size):
252257
if not isdir(target):
253258
if url.startswith('git+'):
254259
url = url[4:]
255-
# if 'version' is specified, do a shallow clone
256-
if self.version:
257-
ensure_dir(target)
258-
with current_directory(target):
259-
shprint(sh.git, 'init')
260-
shprint(sh.git, 'remote', 'add', 'origin', url)
261-
else:
262-
shprint(sh.git, 'clone', '--recursive', url, target)
263-
with current_directory(target):
264-
if self.version:
265-
shprint(sh.git, 'fetch', '--tags', '--depth', '1')
266-
shprint(sh.git, 'checkout', self.version)
267-
branch = sh.git('branch', '--show-current')
268-
if branch:
269-
shprint(sh.git, 'pull')
270-
shprint(sh.git, 'pull', '--recurse-submodules')
271-
shprint(sh.git, 'submodule', 'update', '--recursive', '--init', '--depth', '1')
260+
261+
shprint(
262+
sh.git,
263+
'clone',
264+
'--branch',
265+
self.version,
266+
'--depth',
267+
'1',
268+
'--recurse-submodules',
269+
'--shallow-submodules',
270+
url,
271+
target,
272+
)
273+
272274
return target
273275

274276
def apply_patch(self, filename, arch, build_dir=None):
@@ -375,7 +377,12 @@ def get_recipe_dir(self):
375377
# Public Recipe API to be subclassed if needed
376378

377379
def download_if_necessary(self):
380+
if self.ctx.ndk_api < self.min_ndk_api_support:
381+
error(f"In order to build '{self.name}', you must set minimum ndk api (minapi) to `{self.min_ndk_api_support}`.\n")
382+
exit(1)
383+
378384
info_main('Downloading {}'.format(self.name))
385+
379386
user_dir = environ.get('P4A_{}_DIR'.format(self.name.lower()))
380387
if user_dir is not None:
381388
info('P4A_{}_DIR is set, skipping download for {}'.format(
@@ -919,6 +926,32 @@ def folder_name(self):
919926
name = self.name
920927
return name
921928

929+
def patch_shebang(self, _file, original_bin):
930+
_file_des = open(_file, "r")
931+
932+
try:
933+
data = _file_des.readlines()
934+
except UnicodeDecodeError:
935+
return
936+
937+
if "#!" in (line := data[0]):
938+
if line.split("#!")[-1].strip() == original_bin:
939+
return
940+
941+
info(f"Fixing sheband for '{_file}'")
942+
data.pop(0)
943+
data.insert(0, "#!" + original_bin + "\n")
944+
_file_des.close()
945+
_file_des = open(_file, "w")
946+
_file_des.write("".join(data))
947+
_file_des.close()
948+
949+
def patch_shebangs(self, path, original_bin):
950+
# set correct shebang
951+
for file in listdir(path):
952+
_file = join(path, file)
953+
self.patch_shebang(_file, original_bin)
954+
922955
def get_recipe_env(self, arch=None, with_flags_in_cc=True):
923956
env = super().get_recipe_env(arch, with_flags_in_cc)
924957
env['PYTHONNOUSERSITE'] = '1'
@@ -1260,6 +1293,9 @@ def build_arch(self, arch):
12601293
self.install_hostpython_prerequisites(
12611294
packages=["build[virtualenv]", "pip"] + self.hostpython_prerequisites
12621295
)
1296+
python_bin_dir = join(self.hostpython_site_dir, "bin")
1297+
self.patch_shebangs(python_bin_dir, self.real_hostpython_location)
1298+
12631299
build_dir = self.get_build_dir(arch.arch)
12641300
env = self.get_recipe_env(arch, with_flags_in_cc=True)
12651301
# make build dir separately
@@ -1308,6 +1344,7 @@ def get_recipe_meson_options(self, arch):
13081344
"cpp_args": self.sanitize_flags(env["CXXFLAGS"], env["CPPFLAGS"]),
13091345
"c_link_args": self.sanitize_flags(env["LDFLAGS"]),
13101346
"cpp_link_args": self.sanitize_flags(env["LDFLAGS"]),
1347+
"fortran_link_args": self.sanitize_flags(env["LDFLAGS"]),
13111348
},
13121349
"properties": {
13131350
"needs_exe_wrapper": True,
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
import os
2+
import subprocess
3+
import shutil
4+
import sh
5+
from pathlib import Path
6+
from os.path import join
7+
from pythonforandroid.recipe import Recipe
8+
from pythonforandroid.recommendations import read_ndk_version
9+
from pythonforandroid.logger import info, shprint, info_main
10+
import hashlib
11+
12+
FLANG_FILES = {
13+
"package-flang-aarch64.tar.bz2": "775f362c758abe8d3173edc7be9ced3730ff14c64d44743017c3af7ceb0a6610",
14+
"package-flang-host.tar.bz2": "04fe24d67ee7eb5a4223299c610013585e75c56467e4b185ed929a3d17e3d077",
15+
"package-flang-x86_64.tar.bz2": "2061a0e3179f4afa55516ce3858582d25ea7b108ff762d9fb4ec8a03b49b36d2",
16+
"package-install.tar.bz2": "d37dc6a58b495807f015c7fec08a57ff95d52ad0d0553cbf573b0215d8a1707c",
17+
}
18+
19+
20+
class GFortranRecipe(Recipe):
21+
# flang support in NDK by @licy183 (on github)
22+
name = "fortran"
23+
toolchain_ver = 0
24+
url = "https://github.com/licy183/ndk-toolchain-clang-with-flang/releases/download/"
25+
26+
def match_sha256(self, file_path, expected_hash):
27+
sha256 = hashlib.sha256()
28+
with open(file_path, "rb") as f:
29+
for chunk in iter(lambda: f.read(8192), b""):
30+
sha256.update(chunk)
31+
file_hash = sha256.hexdigest()
32+
return file_hash == expected_hash
33+
34+
@property
35+
def ndk_version(self):
36+
ndk_version = read_ndk_version(self.ctx.ndk_dir)
37+
minor_to_letter = {0: ""}
38+
minor_to_letter.update(
39+
{n + 1: chr(i) for n, i in enumerate(range(ord("b"), ord("b") + 25))}
40+
)
41+
return f"{ndk_version.major}{minor_to_letter[ndk_version.minor]}"
42+
43+
def get_cache_dir(self):
44+
dir_name = self.get_dir_name()
45+
return join(self.ctx.build_dir, "other_builds", dir_name)
46+
47+
def get_fortran_dir(self):
48+
toolchain_name = f"android-r{self.ndk_version}-api-{self.ctx.ndk_api}"
49+
return join(
50+
self.get_cache_dir(), f"{toolchain_name}-flang-v{self.toolchain_ver}"
51+
)
52+
53+
def get_incomplete_files(self):
54+
incomplete_files = []
55+
cache_dir = self.get_cache_dir()
56+
for file, sha256sum in FLANG_FILES.items():
57+
_file = join(cache_dir, file)
58+
if not (os.path.exists(_file) and self.match_sha256(_file, sha256sum)):
59+
incomplete_files.append(file)
60+
return incomplete_files
61+
62+
def download_if_necessary(self):
63+
assert self.ndk_version == "27c"
64+
if len(self.get_incomplete_files()) == 0:
65+
return
66+
self.download()
67+
68+
def download(self):
69+
cache_dir = self.get_cache_dir()
70+
for file in self.get_incomplete_files():
71+
_file = join(cache_dir, file)
72+
if os.path.exists(_file):
73+
os.remove(_file)
74+
self.download_file(f"{self.url}r{join(self.ndk_version, file)}", _file)
75+
76+
def extract_tar(self, file_path: Path, dest: Path, strip=1):
77+
shprint(
78+
sh.tar,
79+
"xf",
80+
str(file_path),
81+
"--strip-components",
82+
str(strip),
83+
"-C",
84+
str(dest) if dest else ".",
85+
)
86+
87+
def create_flang_wrapper(self, path: Path, target: str):
88+
script = f"""#!/usr/bin/env bash
89+
if [ "$1" != "-cpp" ] && [ "$1" != "-fc1" ]; then
90+
`dirname $0`/flang-new --target={target}{self.ctx.ndk_api} -D__ANDROID_API__={self.ctx.ndk_api} "$@"
91+
else
92+
`dirname $0`/flang-new "$@"
93+
fi
94+
"""
95+
path.write_text(script)
96+
path.chmod(0o755)
97+
98+
def unpack(self, arch):
99+
info_main("Unpacking fortran")
100+
101+
flang_folder = self.get_fortran_dir()
102+
if os.path.exists(flang_folder):
103+
info("{} is already unpacked, skipping".format(self.name))
104+
return
105+
106+
toolchain_path = Path(
107+
join(self.ctx.ndk_dir, "toolchains/llvm/prebuilt/linux-x86_64")
108+
)
109+
cache_dir = Path(os.path.abspath(self.get_cache_dir()))
110+
111+
# clean tmp folder
112+
tmp_folder = Path(os.path.abspath(f"{flang_folder}-tmp"))
113+
shutil.rmtree(tmp_folder, ignore_errors=True)
114+
tmp_folder.mkdir(parents=True)
115+
os.chdir(tmp_folder)
116+
117+
self.extract_tar(cache_dir / "package-install.tar.bz2", None, strip=4)
118+
self.extract_tar(cache_dir / "package-flang-host.tar.bz2", None)
119+
120+
sysroot_path = tmp_folder / "sysroot"
121+
shutil.copytree(toolchain_path / "sysroot", sysroot_path)
122+
123+
self.extract_tar(
124+
cache_dir / "package-flang-aarch64.tar.bz2",
125+
sysroot_path / "usr/lib/aarch64-linux-android",
126+
)
127+
self.extract_tar(
128+
cache_dir / "package-flang-x86_64.tar.bz2",
129+
sysroot_path / "usr/lib/x86_64-linux-android",
130+
)
131+
132+
# Fix lib/clang paths
133+
version_output = subprocess.check_output(
134+
[str(tmp_folder / "bin/clang"), "--version"], text=True
135+
)
136+
clang_version = next(
137+
(line for line in version_output.splitlines() if "clang version" in line),
138+
"",
139+
)
140+
major_ver = clang_version.split("clang version ")[-1].split(".")[0]
141+
142+
lib_path = tmp_folder / f"lib/clang/{major_ver}/lib"
143+
src_lib_path = toolchain_path / f"lib/clang/{major_ver}/lib"
144+
shutil.rmtree(lib_path, ignore_errors=True)
145+
lib_path.mkdir(parents=True)
146+
147+
for item in src_lib_path.iterdir():
148+
shprint(sh.cp, "-r", str(item), str(lib_path))
149+
150+
# Create flang wrappers
151+
targets = [
152+
"aarch64-linux-android",
153+
"armv7a-linux-androideabi",
154+
"i686-linux-android",
155+
"x86_64-linux-android",
156+
]
157+
158+
for target in targets:
159+
wrapper_path = tmp_folder / f"bin/{target}-flang"
160+
self.create_flang_wrapper(wrapper_path, target)
161+
shutil.copy(
162+
wrapper_path, tmp_folder / f"bin/{target}{self.ctx.ndk_api}-flang"
163+
)
164+
165+
tmp_folder.rename(flang_folder)
166+
167+
@property
168+
def bin_path(self):
169+
return f"{self.get_fortran_dir()}/bin"
170+
171+
def get_host_platform(self, arch):
172+
return {
173+
"arm64-v8a": "aarch64-linux-android",
174+
"armeabi-v7a": "armv7a-linux-androideabi",
175+
"x86_64": "x86_64-linux-android",
176+
"x86": "i686-linux-android",
177+
}[arch]
178+
179+
def get_fortran_bin(self, arch):
180+
return join(self.bin_path, f"{self.get_host_platform(arch)}-flang")
181+
182+
def get_fortran_flags(self, arch):
183+
return f"--target={self.get_host_platform(arch)}{self.ctx.ndk_api} -D__ANDROID_API__={self.ctx.ndk_api}"
184+
185+
186+
recipe = GFortranRecipe()
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from pythonforandroid.recipe import Recipe
2+
from pythonforandroid.logger import shprint
3+
from pythonforandroid.util import current_directory, ensure_dir
4+
from multiprocessing import cpu_count
5+
from os.path import join
6+
import sh
7+
from pythonforandroid.util import rmdir
8+
9+
10+
class LibOpenBlasRecipe(Recipe):
11+
12+
version = "0.3.29"
13+
url = "https://github.com/OpenMathLib/OpenBLAS/archive/refs/tags/v{version}.tar.gz"
14+
built_libraries = {"libopenblas.so": "build/lib"}
15+
min_ndk_api_support = 24 # complex math functions support
16+
17+
def build_arch(self, arch):
18+
source_dir = self.get_build_dir(arch.arch)
19+
build_target = join(source_dir, "build")
20+
21+
ensure_dir(build_target)
22+
with current_directory(build_target):
23+
env = self.get_recipe_env(arch)
24+
rmdir("CMakeFiles")
25+
shprint(sh.rm, "-f", "CMakeCache.txt", _env=env)
26+
27+
opts = [
28+
# default cmake options
29+
"-DCMAKE_SYSTEM_NAME=Android",
30+
"-DCMAKE_ANDROID_ARCH_ABI={arch}".format(arch=arch.arch),
31+
"-DCMAKE_ANDROID_NDK=" + self.ctx.ndk_dir,
32+
"-DCMAKE_ANDROID_API={api}".format(api=self.ctx.ndk_api),
33+
"-DCMAKE_BUILD_TYPE=Release",
34+
"-DBUILD_SHARED_LIBS=ON",
35+
"-DC_LAPACK=ON",
36+
"-DTARGET={target}".format(
37+
target={
38+
"arm64-v8a": "ARMV8",
39+
"armeabi-v7a": "ARMV7",
40+
"x86_64": "CORE2",
41+
"x86": "CORE2",
42+
}[arch.arch]
43+
),
44+
]
45+
46+
shprint(sh.cmake, source_dir, *opts, _env=env)
47+
shprint(sh.make, "-j" + str(cpu_count()), _env=env)
48+
49+
50+
recipe = LibOpenBlasRecipe()

‎pythonforandroid/recipes/numpy/__init__.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
from pythonforandroid.recipe import Recipe, MesonRecipe
2-
from pythonforandroid.logger import error
32
from os.path import join
43
import shutil
54

6-
NUMPY_NDK_MESSAGE = "In order to build numpy, you must set minimum ndk api (minapi) to `24`.\n"
7-
85

96
class NumpyRecipe(MesonRecipe):
10-
version = 'v1.26.5'
7+
version = 'v2.2.4'
118
url = 'git+https://github.com/numpy/numpy'
129
hostpython_prerequisites = ["Cython>=3.0.6"] # meson does not detects venv's cython
1310
extra_build_args = ['-Csetup-args=-Dblas=none', '-Csetup-args=-Dlapack=none']
1411
need_stl_shared = True
12+
min_ndk_api_support = 24 # NumPy requires complex math functions which were added in api 24
1513

1614
def get_recipe_meson_options(self, arch):
1715
options = super().get_recipe_meson_options(arch)
@@ -36,13 +34,6 @@ def get_recipe_env(self, arch, **kwargs):
3634
"python3", self.ctx).get_build_dir(arch.arch), "android-build", "python")
3735
return env
3836

39-
def download_if_necessary(self):
40-
# NumPy requires complex math functions which were added in api 24
41-
if self.ctx.ndk_api < 24:
42-
error(NUMPY_NDK_MESSAGE)
43-
exit(1)
44-
super().download_if_necessary()
45-
4637
def build_arch(self, arch):
4738
super().build_arch(arch)
4839
self.restore_hostpython_prerequisites(["cython"])

‎pythonforandroid/recipes/python3/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ class Python3Recipe(TargetPythonRecipe):
141141

142142
site_packages_dir_blacklist = {
143143
'__pycache__',
144-
'tests'
144+
# 'tests'
145145
}
146146
'''The directories from site packages dir that we don't want to be included
147147
in our python bundle.'''

‎pythonforandroid/recipes/scipy/__init__.py

Lines changed: 47 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,58 @@
1-
from multiprocessing import cpu_count
2-
from os.path import join
3-
from os import environ
4-
import sh
5-
from pythonforandroid.logger import shprint
6-
from pythonforandroid.recipe import CompiledComponentsPythonRecipe, Recipe
7-
from pythonforandroid.util import build_platform, current_directory
1+
from os.path import join, dirname, basename
2+
from pythonforandroid.recipe import MesonRecipe, Recipe
3+
from pathlib import Path
84

95

10-
def arch_to_toolchain(arch):
11-
if 'arm' in arch.arch:
12-
return arch.command_prefix
13-
return arch.arch
6+
class ScipyRecipe(MesonRecipe):
147

15-
16-
class ScipyRecipe(CompiledComponentsPythonRecipe):
17-
18-
version = 'maintenance/1.11.x'
19-
url = 'git+https://github.com/scipy/scipy.git'
20-
git_commit = 'b430bf54b5064465983813e2cfef3fcb86c3df07' # version 1.11.3
21-
site_packages_name = 'scipy'
22-
hostpython_prerequisites = ['numpy']
23-
depends = ['setuptools', 'cython', 'numpy', 'lapack', 'pybind11']
24-
call_hostpython_via_targetpython = False
8+
version = "v1.15.2"
9+
url = "git+https://github.com/scipy/scipy.git"
10+
hostpython_prerequisites = ["Cython>=3.0.6"]
11+
depends = ["numpy", "libopenblas"]
2512
need_stl_shared = True
26-
patches = ["setup.py.patch"]
27-
28-
def build_compiled_components(self, arch):
29-
self.setup_extra_args = ['-j', str(cpu_count())]
30-
super().build_compiled_components(arch)
31-
self.setup_extra_args = []
32-
33-
def rebuild_compiled_components(self, arch, env):
34-
self.setup_extra_args = ['-j', str(cpu_count())]
35-
super().rebuild_compiled_components(arch, env)
36-
self.setup_extra_args = []
37-
38-
def download_file(self, url, target, cwd=None):
39-
super().download_file(url, target, cwd=cwd)
40-
with current_directory(target):
41-
shprint(sh.git, 'fetch', '--unshallow')
42-
shprint(sh.git, 'checkout', self.git_commit)
43-
44-
def get_recipe_env(self, arch):
45-
env = super().get_recipe_env(arch)
13+
meson_version = "1.5.0"
14+
hostpython_prerequisites = ["numpy"]
15+
patches = ["meson.patch"]
16+
17+
def get_recipe_meson_options(self, arch):
18+
options = super().get_recipe_meson_options(arch)
19+
options["binaries"]["python"] = self.ctx.python_recipe.python_exe
20+
options["binaries"]["fortran"] = self.place_wrapper(arch)
21+
options["properties"]["numpy-include-dir"] = join(
22+
self.ctx.get_python_install_dir(arch.arch), "numpy/_core/include"
23+
)
24+
self.ensure_args(
25+
"-Csetup-args=-Dblas=openblas",
26+
"-Csetup-args=-Dlapack=openblas",
27+
f"-Csetup-args=-Dopenblas_libdir={self.ctx.get_libs_dir(arch.arch)}",
28+
f'-Csetup-args=-Dopenblas_incldir={join(Recipe.get_recipe("libopenblas", self.ctx).get_build_dir(arch.arch), "build")}',
29+
"-Csetup-args=-Duse-pythran=false",
30+
)
31+
return options
32+
33+
def place_wrapper(self, arch):
34+
compiler = Recipe.get_recipe("fortran", self.ctx).get_fortran_bin(arch.arch)
35+
file = join(self.get_recipe_dir(), "wrapper.py")
36+
with open(file, "r") as _file:
37+
data = _file.read()
38+
_file.close()
39+
data = data.replace("@COMPILER@", compiler)
40+
# custom compiler
41+
# taken from: https://github.com/termux/termux-packages/blob/master/packages/python-scipy/
42+
m_compiler = Path(join(dirname(compiler), basename(compiler) + "-scipy"))
43+
m_compiler.write_text(data)
44+
m_compiler.chmod(0o755)
45+
self.patch_shebang(str(m_compiler), self.real_hostpython_location)
46+
return str(m_compiler)
47+
48+
def get_recipe_env(self, arch, **kwargs):
49+
env = super().get_recipe_env(arch, **kwargs)
4650
arch_env = arch.get_env()
47-
48-
env['LDFLAGS'] = arch_env['LDFLAGS']
49-
env['LDFLAGS'] += ' -L{} -lpython{}'.format(
51+
env["LDFLAGS"] = arch_env["LDFLAGS"]
52+
env["LDFLAGS"] += " -L{} -lpython{}".format(
5053
self.ctx.python_recipe.link_root(arch.arch),
5154
self.ctx.python_recipe.link_version,
5255
)
53-
54-
ndk_dir = environ["LEGACY_NDK"]
55-
GCC_VER = '4.9'
56-
HOST = build_platform
57-
suffix = '64' if '64' in arch.arch else ''
58-
59-
prefix = arch.command_prefix
60-
CLANG_BIN = f'{ndk_dir}/toolchains/llvm/prebuilt/{HOST}/bin/'
61-
GCC = f'{ndk_dir}/toolchains/{arch_to_toolchain(arch)}-{GCC_VER}/prebuilt/{HOST}'
62-
libgfortran = f'{GCC}/{prefix}/lib{suffix}'
63-
numpylib = self.ctx.get_python_install_dir(arch.arch) + '/numpy'
64-
arch_cflags = ' '.join(arch.arch_cflags)
65-
LDSHARED_opts = f'-target {arch.target} {arch_cflags} ' + ' '.join(arch.common_ldshared)
66-
67-
# TODO: add pythran support
68-
env['SCIPY_USE_PYTHRAN'] = '0'
69-
70-
lapack_dir = join(Recipe.get_recipe('lapack', self.ctx).get_build_dir(arch.arch), 'build', 'install')
71-
env['LAPACK'] = f'{lapack_dir}/lib'
72-
env['BLAS'] = env['LAPACK']
73-
74-
# compilers
75-
env['F77'] = f'{GCC}/bin/{prefix}-gfortran'
76-
env['F90'] = f'{GCC}/bin/{prefix}-gfortran'
77-
env['CC'] = f'{CLANG_BIN}clang -target {arch.target} {arch_cflags}'
78-
env['CXX'] = f'{CLANG_BIN}clang++ -target {arch.target} {arch_cflags}'
79-
80-
# scipy expects ldshared to be a single executable without options
81-
env['LDSHARED'] = f'{CLANG_BIN}/clang'
82-
83-
# erase the default NDK C++ include options
84-
env['CPPFLAGS'] = '-DANDROID'
85-
86-
# configure linker
87-
env['LDFLAGS'] += f' {LDSHARED_opts} -L{libgfortran} -L{numpylib}/core/lib -L{numpylib}/random/lib'
88-
env['LDFLAGS'] += f' -l{self.stl_lib_name}'
8956
return env
9057

9158

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
Binary files scipy.git/.git/index and scipy.git.patch/.git/index differ
2+
diff '--color=auto' -uNr scipy.git/.git/logs/refs/remotes/origin/main scipy.git.patch/.git/logs/refs/remotes/origin/main
3+
--- scipy.git/.git/logs/refs/remotes/origin/main 2025-03-27 02:55:14.521123150 +0530
4+
+++ scipy.git.patch/.git/logs/refs/remotes/origin/main 2025-03-27 11:24:34.225186085 +0530
5+
@@ -1,2 +1,2 @@
6+
0000000000000000000000000000000000000000 48729662732146f4b9191c51622077505c1d50c4 Ansh Dadwal <anshdadwal298@gmail.com> 1742991556 +0530 fetch --tags --depth 1: storing head
7+
-48729662732146f4b9191c51622077505c1d50c4 25c83634c99c78f7aeef0e38fd5060cb810e2218 Ansh Dadwal <anshdadwal298@gmail.com> 1743024293 +0530 fetch --all --no-write-fetch-head: fast-forward
8+
+48729662732146f4b9191c51622077505c1d50c4 2a330d119f4adcf40bbed677e2c659c556c4b10c Ansh Dadwal <anshdadwal298@gmail.com> 1743054874 +0530 fetch --all --no-write-fetch-head: fast-forward
9+
Binary files scipy.git/.git/objects/0d/02ec1f1f196b92ae7272138c486cf848183114 and scipy.git.patch/.git/objects/0d/02ec1f1f196b92ae7272138c486cf848183114 differ
10+
Binary files scipy.git/.git/objects/18/0f09926772f607e076ebb1508239607ce2ab22 and scipy.git.patch/.git/objects/18/0f09926772f607e076ebb1508239607ce2ab22 differ
11+
Binary files scipy.git/.git/objects/28/a68ee737b8578d402e93066be0ba960e7f0f03 and scipy.git.patch/.git/objects/28/a68ee737b8578d402e93066be0ba960e7f0f03 differ
12+
Binary files scipy.git/.git/objects/2a/330d119f4adcf40bbed677e2c659c556c4b10c and scipy.git.patch/.git/objects/2a/330d119f4adcf40bbed677e2c659c556c4b10c differ
13+
Binary files scipy.git/.git/objects/2d/8e8e18e18d0db6428f72699ec0cc266eb9be12 and scipy.git.patch/.git/objects/2d/8e8e18e18d0db6428f72699ec0cc266eb9be12 differ
14+
Binary files scipy.git/.git/objects/3b/2ef179b2b52d890292bc5b5be159aca554b0e8 and scipy.git.patch/.git/objects/3b/2ef179b2b52d890292bc5b5be159aca554b0e8 differ
15+
Binary files scipy.git/.git/objects/41/d31bf24ece424a2a855cfb4033d5b188d94fb6 and scipy.git.patch/.git/objects/41/d31bf24ece424a2a855cfb4033d5b188d94fb6 differ
16+
Binary files scipy.git/.git/objects/42/8fa48420c07c28b0ba56a180fe36dde47c2e76 and scipy.git.patch/.git/objects/42/8fa48420c07c28b0ba56a180fe36dde47c2e76 differ
17+
Binary files scipy.git/.git/objects/43/d378890bc0107353635039aff4fc291b54ab2d and scipy.git.patch/.git/objects/43/d378890bc0107353635039aff4fc291b54ab2d differ
18+
Binary files scipy.git/.git/objects/47/3ede8b6a4fc326b3ab783173a21b6e2c266f80 and scipy.git.patch/.git/objects/47/3ede8b6a4fc326b3ab783173a21b6e2c266f80 differ
19+
Binary files scipy.git/.git/objects/4b/0751abec308d9b44e66e53910fb57a6bc06ea0 and scipy.git.patch/.git/objects/4b/0751abec308d9b44e66e53910fb57a6bc06ea0 differ
20+
Binary files scipy.git/.git/objects/57/2a08b57457d934b1b0b0a854b325564b5a97f9 and scipy.git.patch/.git/objects/57/2a08b57457d934b1b0b0a854b325564b5a97f9 differ
21+
Binary files scipy.git/.git/objects/5b/e56185477360da3460bcb014bdf4ad489a2fa0 and scipy.git.patch/.git/objects/5b/e56185477360da3460bcb014bdf4ad489a2fa0 differ
22+
Binary files scipy.git/.git/objects/63/951b7f33f1a36efdd146ba9eac72dd7a0eff21 and scipy.git.patch/.git/objects/63/951b7f33f1a36efdd146ba9eac72dd7a0eff21 differ
23+
Binary files scipy.git/.git/objects/6c/1fdf7ce31d93f6792d3a0ab20ac8ebc491634a and scipy.git.patch/.git/objects/6c/1fdf7ce31d93f6792d3a0ab20ac8ebc491634a differ
24+
Binary files scipy.git/.git/objects/79/985f4843e2594097a1f642b439e1cdd4e95b67 and scipy.git.patch/.git/objects/79/985f4843e2594097a1f642b439e1cdd4e95b67 differ
25+
Binary files scipy.git/.git/objects/85/d98090063ebe22ee1b0fae064872e6dcf8cf3e and scipy.git.patch/.git/objects/85/d98090063ebe22ee1b0fae064872e6dcf8cf3e differ
26+
Binary files scipy.git/.git/objects/99/be9d37640e84a558303f4186b497b0b68b4cb8 and scipy.git.patch/.git/objects/99/be9d37640e84a558303f4186b497b0b68b4cb8 differ
27+
Binary files scipy.git/.git/objects/9c/7b6bdf4c4cfee1321630a790de96f79d68cc34 and scipy.git.patch/.git/objects/9c/7b6bdf4c4cfee1321630a790de96f79d68cc34 differ
28+
Binary files scipy.git/.git/objects/a1/48b22d0a8a9d7b84f493eac71ca2923dc90b13 and scipy.git.patch/.git/objects/a1/48b22d0a8a9d7b84f493eac71ca2923dc90b13 differ
29+
Binary files scipy.git/.git/objects/a2/8cf022e4d93f9295fafadc34eeac3b5feb9865 and scipy.git.patch/.git/objects/a2/8cf022e4d93f9295fafadc34eeac3b5feb9865 differ
30+
Binary files scipy.git/.git/objects/a2/e0f0f294e82b4f1d8f22a95997d350dc8e99ac and scipy.git.patch/.git/objects/a2/e0f0f294e82b4f1d8f22a95997d350dc8e99ac differ
31+
Binary files scipy.git/.git/objects/a8/a7e3a074af75d757f1b07e501982c0c69407f9 and scipy.git.patch/.git/objects/a8/a7e3a074af75d757f1b07e501982c0c69407f9 differ
32+
Binary files scipy.git/.git/objects/b5/2de999adafb86bc6eeb8cc4a305f807961fb5b and scipy.git.patch/.git/objects/b5/2de999adafb86bc6eeb8cc4a305f807961fb5b differ
33+
Binary files scipy.git/.git/objects/ba/ccd8bf8b7cf9bfc9419c0b89e9002e2643cb3f and scipy.git.patch/.git/objects/ba/ccd8bf8b7cf9bfc9419c0b89e9002e2643cb3f differ
34+
Binary files scipy.git/.git/objects/c3/4e2f9bdbf408c8c58de1ba443976b6d43644c5 and scipy.git.patch/.git/objects/c3/4e2f9bdbf408c8c58de1ba443976b6d43644c5 differ
35+
Binary files scipy.git/.git/objects/c3/b0c331b41fcf32c4fb2094161e2c0cbaa3018d and scipy.git.patch/.git/objects/c3/b0c331b41fcf32c4fb2094161e2c0cbaa3018d differ
36+
Binary files scipy.git/.git/objects/d4/fa8791ac576224f76d12fb5c70d92a349bc048 and scipy.git.patch/.git/objects/d4/fa8791ac576224f76d12fb5c70d92a349bc048 differ
37+
Binary files scipy.git/.git/objects/d6/2bbef60cbf7d132f18edd9de507e293ac6a714 and scipy.git.patch/.git/objects/d6/2bbef60cbf7d132f18edd9de507e293ac6a714 differ
38+
Binary files scipy.git/.git/objects/d8/6830415fbcd94805f3e4f5f4d500af07bc24fa and scipy.git.patch/.git/objects/d8/6830415fbcd94805f3e4f5f4d500af07bc24fa differ
39+
Binary files scipy.git/.git/objects/d8/b32d2bf04fb1c84cb222c8fb9659e081a4cca6 and scipy.git.patch/.git/objects/d8/b32d2bf04fb1c84cb222c8fb9659e081a4cca6 differ
40+
Binary files scipy.git/.git/objects/e1/8876588aa60e9276f2e9f033639486d784c1bb and scipy.git.patch/.git/objects/e1/8876588aa60e9276f2e9f033639486d784c1bb differ
41+
Binary files scipy.git/.git/objects/ef/2dfb84924876e9ad942f107735034e55a1f96e and scipy.git.patch/.git/objects/ef/2dfb84924876e9ad942f107735034e55a1f96e differ
42+
Binary files scipy.git/.git/objects/f7/fa114cd42e062893a58dd8ab862994de26fd2d and scipy.git.patch/.git/objects/f7/fa114cd42e062893a58dd8ab862994de26fd2d differ
43+
Binary files scipy.git/.git/objects/fa/cd8015cbaf54c110eeeac21e62fcd9ba62740d and scipy.git.patch/.git/objects/fa/cd8015cbaf54c110eeeac21e62fcd9ba62740d differ
44+
Binary files scipy.git/.git/objects/ff/5a231c656bd9ffe9c014c998f421a41bbc9b5c and scipy.git.patch/.git/objects/ff/5a231c656bd9ffe9c014c998f421a41bbc9b5c differ
45+
diff '--color=auto' -uNr scipy.git/.git/refs/remotes/origin/main scipy.git.patch/.git/refs/remotes/origin/main
46+
--- scipy.git/.git/refs/remotes/origin/main 2025-03-27 02:55:14.462475393 +0530
47+
+++ scipy.git.patch/.git/refs/remotes/origin/main 2025-03-27 11:24:34.225186085 +0530
48+
@@ -1 +1 @@
49+
-25c83634c99c78f7aeef0e38fd5060cb810e2218
50+
+2a330d119f4adcf40bbed677e2c659c556c4b10c
51+
diff '--color=auto' -uNr scipy.git/meson.options scipy.git.patch/meson.options
52+
--- scipy.git/meson.options 2025-03-27 02:55:14.586853766 +0530
53+
+++ scipy.git.patch/meson.options 2025-03-27 02:07:29.736674085 +0530
54+
@@ -2,6 +2,8 @@
55+
description: 'option for BLAS library switching')
56+
option('lapack', type: 'string', value: 'openblas',
57+
description: 'option for LAPACK library switching')
58+
+option('openblas_incldir', type: 'string', value: '', description: 'OpenBLAS include directory')
59+
+option('openblas_libdir', type: 'string', value: '', description: 'OpenBLAS library directory')
60+
option('use-g77-abi', type: 'boolean', value: false,
61+
description: 'If set to true, forces using g77 compatibility wrappers ' +
62+
'for LAPACK functions. The default is to use gfortran ' +
63+
diff '--color=auto' -uNr scipy.git/scipy/meson.build scipy.git.patch/scipy/meson.build
64+
--- scipy.git/scipy/meson.build 2025-03-27 02:55:14.632428649 +0530
65+
+++ scipy.git.patch/scipy/meson.build 2025-03-27 11:25:33.756445056 +0530
66+
@@ -268,10 +268,18 @@
67+
endif
68+
endif
69+
70+
+openblas_inc = get_option('openblas_incldir')
71+
+openblas_lib = get_option('openblas_libdir')
72+
+
73+
+openblas_dep = declare_dependency(
74+
+ include_directories: include_directories(openblas_inc),
75+
+ link_args: ['-L' + openblas_lib, '-lopenblas']
76+
+)
77+
+
78+
# pkg-config uses a lower-case name while CMake uses a capitalized name, so try
79+
# that too to make the fallback detection with CMake work
80+
if blas_name == 'openblas'
81+
- blas = dependency(['openblas', 'OpenBLAS'])
82+
+ blas = openblas_dep
83+
elif blas_name != 'scipy-openblas' # if so, we found it already
84+
blas = dependency(blas_name)
85+
endif
86+
@@ -295,7 +303,7 @@
87+
# use that - no need to run the full detection twice.
88+
lapack = blas
89+
elif lapack_name == 'openblas'
90+
- lapack = dependency(['openblas', 'OpenBLAS'])
91+
+ lapack = openblas_dep
92+
else
93+
lapack = dependency(lapack_name)
94+
endif

‎pythonforandroid/recipes/scipy/setup.py.patch

Lines changed: 0 additions & 1098 deletions
This file was deleted.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/usr/bin/python3
2+
3+
# Taken from https://github.com/termux/termux-packages/blob/master/packages/python-scipy/wrapper.py.in
4+
5+
import os
6+
import subprocess
7+
import sys
8+
import typing
9+
10+
"""
11+
This wrapper is used to ignore or replace some unsupported flags for flang-new.
12+
13+
It will operate as follows:
14+
15+
1. Ignore `-Minform=inform` and `-fdiagnostics-color`.
16+
They are added by meson automatically, but are not supported by flang-new yet.
17+
2. Remove `-lflang` and `-lpgmath`.
18+
It exists in classic-flang but doesn't exist in flang-new.
19+
3. Replace `-Oz` to `-O2`.
20+
`-Oz` is not supported by flang-new.
21+
4. Replace `-module` to `-J`.
22+
See https://github.com/llvm/llvm-project/issues/66969
23+
5. Ignore `-MD`, `-MQ file` and `-MF file`.
24+
They generates files used by GNU make but we're using ninja.
25+
6. Ignore `-fvisibility=hidden`.
26+
It is not supported by flang-new, and ignoring it will not break the functionality,
27+
as scipy also uses version script for shared libraries.
28+
"""
29+
30+
COMPLIER_PATH = "@COMPILER@"
31+
32+
33+
def main(argv: typing.List[str]):
34+
cwd = os.getcwd()
35+
argv_new = []
36+
i = 0
37+
while i < len(argv):
38+
arg = argv[i]
39+
if arg in [
40+
"-Minform=inform",
41+
"-lflang",
42+
"-lpgmath",
43+
"-MD",
44+
"-fvisibility=hidden",
45+
] or arg.startswith("-fdiagnostics-color"):
46+
pass
47+
elif arg == "-Oz":
48+
argv_new.append("-O2")
49+
elif arg == "-module":
50+
argv_new.append("-J")
51+
elif arg in ["-MQ", "-MF"]:
52+
i += 1
53+
else:
54+
argv_new.append(arg)
55+
i += 1
56+
57+
args = [COMPLIER_PATH] + argv_new
58+
subprocess.check_call(args, env=os.environ, cwd=cwd, text=True)
59+
60+
61+
if __name__ == "__main__":
62+
main(sys.argv[1:])

0 commit comments

Comments
 (0)
Please sign in to comment.