diff --git a/.azure-pipelines/azure-pipelines-win.yml b/.azure-pipelines/azure-pipelines-win.yml old mode 100755 new mode 100644 index c0b4113d..16f3ecd1 --- a/.azure-pipelines/azure-pipelines-win.yml +++ b/.azure-pipelines/azure-pipelines-win.yml @@ -5,7 +5,7 @@ jobs: - job: win pool: - vmImage: windows-2019 + vmImage: windows-2022 strategy: matrix: win_64_numpy1.20python3.8.____73_pypypython_implpypy: @@ -51,7 +51,7 @@ jobs: - script: | call activate base - mamba.exe install "python=3.9" conda-build conda pip boa conda-forge-ci-setup=3 "py-lief<0.12" -c conda-forge --strict-channel-priority --yes + mamba.exe install "python=3.10" conda-build conda pip boa conda-forge-ci-setup=3 -c conda-forge --strict-channel-priority --yes displayName: Install conda-build - script: set PYTHONUNBUFFERED=1 diff --git a/.scripts/build_steps.sh b/.scripts/build_steps.sh index 84431a63..a6b09f6b 100755 --- a/.scripts/build_steps.sh +++ b/.scripts/build_steps.sh @@ -33,9 +33,9 @@ CONDARC mamba install --update-specs --yes --quiet --channel conda-forge \ - conda-build pip boa conda-forge-ci-setup=3 "py-lief<0.12" + conda-build pip boa conda-forge-ci-setup=3 mamba update --update-specs --yes --quiet --channel conda-forge \ - conda-build pip boa conda-forge-ci-setup=3 "py-lief<0.12" + conda-build pip boa conda-forge-ci-setup=3 # set up the condarc setup_conda_rc "${FEEDSTOCK_ROOT}" "${RECIPE_ROOT}" "${CONFIG_FILE}" diff --git a/.scripts/run_osx_build.sh b/.scripts/run_osx_build.sh index b3abaeb5..bb00584b 100755 --- a/.scripts/run_osx_build.sh +++ b/.scripts/run_osx_build.sh @@ -24,9 +24,9 @@ source ${MINIFORGE_HOME}/etc/profile.d/conda.sh conda activate base mamba install --update-specs --quiet --yes --channel conda-forge \ - conda-build pip boa conda-forge-ci-setup=3 "py-lief<0.12" + conda-build pip boa conda-forge-ci-setup=3 mamba update --update-specs --yes --quiet --channel conda-forge \ - conda-build pip boa conda-forge-ci-setup=3 "py-lief<0.12" + conda-build pip boa conda-forge-ci-setup=3 diff --git a/README.md b/README.md index 065edb8e..85b67285 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ -About scipy -=========== +About scipy-feedstock +===================== + +Feedstock license: [BSD-3-Clause](https://github.com/conda-forge/scipy-feedstock/blob/main/LICENSE.txt) Home: http://www.scipy.org/ Package license: BSD-3-Clause -Feedstock license: [BSD-3-Clause](https://github.com/conda-forge/scipy-feedstock/blob/main/LICENSE.txt) - Summary: Scientific Library for Python Development: https://github.com/scipy/scipy diff --git a/recipe/build.sh b/recipe/build.sh index b1da6fa4..030561f9 100644 --- a/recipe/build.sh +++ b/recipe/build.sh @@ -1,9 +1,15 @@ #!/bin/bash +set -ex -set -x +mkdir builddir -# Use the G77 ABI wrapper everywhere so that the underlying blas implementation -# can have a G77 ABI (currently only MKL) -export SCIPY_USE_G77_ABI_WRAPPER=1 +# need to run meson first for cross-compilation case +$PYTHON $(which meson) setup ${MESON_ARGS} \ + -Dblas=blas \ + -Dlapack=lapack \ + -Duse-g77-abi=true \ + builddir || (cat builddir/meson-logs/meson-log.txt && exit 1) -$PYTHON setup.py install --single-version-externally-managed --record=record.txt +# -wnx flags mean: --wheel --no-isolation --skip-dependency-check +$PYTHON -m build -w -n -x -Cbuilddir=builddir +pip install dist/scipy*.whl diff --git a/recipe/meta.yaml b/recipe/meta.yaml index c4f836b9..893f2eab 100644 --- a/recipe/meta.yaml +++ b/recipe/meta.yaml @@ -14,6 +14,11 @@ source: # the submodules (not in tarball due to dear-github/dear-github#214) - url: https://github.com/scipy/scipy/archive/refs/tags/v{{ version }}.tar.gz sha256: 8f08e1742c9b09eb58640fa5a56031d6e1844806899e883fbe7447ca86fe8c55 + patches: + # backport https://github.com/scipy/scipy/pull/18006 + - patches/0001-BLD-use-a-relative-path-to-numpy-pybind11-pythran-in.patch + # backport https://github.com/scipy/scipy/pull/18034 + - patches/0002-BLD-avoid-running-run_command-py3-.-for-better-cross.patch # https://github.com/scipy/scipy/tree/v{{ version }}/scipy/_lib - git_url: https://github.com/scipy/boost-headers-only.git git_rev: 3af99e6d566043072e95bc882d32c9c26f37e0ba @@ -39,7 +44,10 @@ requirements: - cython # [build_platform != target_platform] - numpy # [build_platform != target_platform] - pybind11 # [build_platform != target_platform] - - setuptools <60 # [build_platform != target_platform] + - meson-python # [build_platform != target_platform] + - cmake # [build_platform != target_platform] + - ninja # [build_platform != target_platform] + - pkg-config # [build_platform != target_platform] - {{ compiler('c') }} - {{ compiler('cxx') }} # pythran code needs clang-cl on windows @@ -54,8 +62,12 @@ requirements: - libcblas - liblapack - python - - setuptools <60 + - setuptools <60 # [win] - cython + - meson-python # [unix] + - ninja # [unix] + - pkg-config # [unix] + - python-build # [unix] - pybind11 - pythran - numpy @@ -78,14 +90,26 @@ requirements: {% set tests_to_skip = tests_to_skip + " or (test_optimize and TestBrute and test_workers)" %} # [aarch64 or ppc64le] # tests that run into timeouts (set in scipy test suite) in emulation {% set tests_to_skip = tests_to_skip + " or (test_propack and test_examples)" %} # [aarch64 or ppc64le] +# occasionally runs out of memory on windows + pypy +{% set tests_to_skip = tests_to_skip + " or test_bootstrap_against_" %} # [(python_impl == "pypy") and win] # very slow tests for pypy in emulation -{% set tests_to_skip = tests_to_skip + " or test_triple_integral_improper" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] +{% set tests_to_skip = tests_to_skip + " or test_all_nograd_minimizers or test_basic_fit_mle" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] +{% set tests_to_skip = tests_to_skip + " or test_cdf_against_tables or test_pdf_integration" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] +{% set tests_to_skip = tests_to_skip + " or test_cdist_ and (refcount or calling_convention)" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] {% set tests_to_skip = tests_to_skip + " or test_conditionally_positive_definite" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] -{% set tests_to_skip = tests_to_skip + " or test_cont_basic[500" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] -{% set tests_to_skip = tests_to_skip + " or test_gh12922 or test_modules_importable" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] -{% set tests_to_skip = tests_to_skip + " or test_random_complex_exact" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] +{% set tests_to_skip = tests_to_skip + " or test_cont_basic[500 or test_cython_api[elliprj]" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] +{% set tests_to_skip = tests_to_skip + " or test_filtfilt_gust or test_kappa3_array_gh13582" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] +{% set tests_to_skip = tests_to_skip + " or test_fitstart[genexpon-shapes28] or test_gh12922" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] +{% set tests_to_skip = tests_to_skip + " or test_integration_sparse or test_kdtree_box" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] {% set tests_to_skip = tests_to_skip + " or test_minimize_callback_copies_array[fmin]" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] -{% set tests_to_skip = tests_to_skip + " or TestDifferentialEvolutionSolver" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] +{% set tests_to_skip = tests_to_skip + " or test_mip1 or test_mixed_threads_processes" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] +{% set tests_to_skip = tests_to_skip + " or test_modules_importable or test_neldermead_limit" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] +{% set tests_to_skip = tests_to_skip + " or test_random_exact or test_random_complex_exact" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] +{% set tests_to_skip = tests_to_skip + " or TestDualAnnealing or TestQuad or TestNQuad" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] +{% set tests_to_skip = tests_to_skip + " or TestDifferentialEvolutionSolver or TestTRF" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] +{% set tests_to_skip = tests_to_skip + " or TestMonteCarloHypothesisTest" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] +{% set tests_to_skip = tests_to_skip + " or (TestBessel and test_fs_param)" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] +{% set tests_to_skip = tests_to_skip + " or (TestOrdQZWorkspaceSize and test_decompose)" %} # [(python_impl == "pypy") and (aarch64 or ppc64le)] test: requires: diff --git a/recipe/patches/0001-BLD-use-a-relative-path-to-numpy-pybind11-pythran-in.patch b/recipe/patches/0001-BLD-use-a-relative-path-to-numpy-pybind11-pythran-in.patch new file mode 100644 index 00000000..636e4d23 --- /dev/null +++ b/recipe/patches/0001-BLD-use-a-relative-path-to-numpy-pybind11-pythran-in.patch @@ -0,0 +1,1180 @@ +From 66ccdf8520ec803cfd00371833170008f3b0f666 Mon Sep 17 00:00:00 2001 +From: Ralf Gommers +Date: Sun, 19 Feb 2023 22:13:39 +0000 +Subject: [PATCH 1/2] BLD: use a relative path to numpy/pybind11/pythran + include and lib dirs + +This should make things work with in-tree virtual envs, as well as some +situations with Docker that had issues before. + +The approach to determine absolute/relative paths unfortunately has to +be a bit convoluted, but I believe this should work in all +circumstances. A future improvement is still to make this work: +``` +np_dep = dependency('numpy') +``` +That way it won't be needed to run any Python code for the host +interpreter at build time (this is bad for cross-compiling). + +Closes gh-16312 +--- + scipy/cluster/meson.build | 6 +- + scipy/fft/_pocketfft/meson.build | 3 +- + scipy/fftpack/meson.build | 2 +- + scipy/integrate/meson.build | 11 +--- + scipy/interpolate/meson.build | 16 ++--- + scipy/io/matlab/meson.build | 4 +- + scipy/io/meson.build | 1 - + scipy/linalg/meson.build | 20 +++---- + scipy/meson.build | 58 +++++++++++++++---- + scipy/ndimage/meson.build | 9 +-- + scipy/odr/meson.build | 3 +- + scipy/optimize/_highs/meson.build | 3 +- + scipy/optimize/_lsq/meson.build | 2 +- + scipy/optimize/_trlib/meson.build | 3 +- + scipy/optimize/cython_optimize/meson.build | 2 +- + scipy/optimize/meson.build | 27 ++++----- + scipy/signal/meson.build | 14 ++--- + scipy/sparse/csgraph/meson.build | 2 +- + scipy/sparse/linalg/_dsolve/meson.build | 4 +- + scipy/sparse/linalg/_eigen/arpack/meson.build | 1 - + scipy/sparse/linalg/_isolve/meson.build | 1 - + scipy/sparse/linalg/_propack/meson.build | 1 - + scipy/sparse/meson.build | 2 +- + scipy/sparse/sparsetools/meson.build | 2 +- + scipy/spatial/meson.build | 15 ++--- + scipy/spatial/transform/meson.build | 2 +- + scipy/special/meson.build | 24 ++++---- + scipy/stats/_boost/meson.build | 3 +- + scipy/stats/_levy_stable/meson.build | 2 +- + scipy/stats/_rcont/meson.build | 3 +- + scipy/stats/_unuran/meson.build | 3 +- + scipy/stats/meson.build | 14 ++--- + 32 files changed, 138 insertions(+), 125 deletions(-) + +diff --git a/scipy/cluster/meson.build b/scipy/cluster/meson.build +index a20619264..8ca032a76 100644 +--- a/scipy/cluster/meson.build ++++ b/scipy/cluster/meson.build +@@ -1,7 +1,7 @@ + slib = py3.extension_module('_hierarchy', + linalg_cython_gen.process('_hierarchy.pyx'), + c_args: cython_c_args, +- include_directories: [inc_np], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/cluster' +@@ -10,7 +10,7 @@ slib = py3.extension_module('_hierarchy', + slib = py3.extension_module('_optimal_leaf_ordering', + linalg_cython_gen.process('_optimal_leaf_ordering.pyx'), + c_args: cython_c_args, +- include_directories: [inc_np], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/cluster' +@@ -19,7 +19,7 @@ slib = py3.extension_module('_optimal_leaf_ordering', + slib = py3.extension_module('_vq', + linalg_cython_gen.process('_vq.pyx'), + c_args: cython_c_args, +- include_directories: [inc_np], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/cluster' +diff --git a/scipy/fft/_pocketfft/meson.build b/scipy/fft/_pocketfft/meson.build +index 242c6e5d0..29aeadc06 100644 +--- a/scipy/fft/_pocketfft/meson.build ++++ b/scipy/fft/_pocketfft/meson.build +@@ -27,8 +27,7 @@ endif + py3.extension_module('pypocketfft', + 'pypocketfft.cxx', + cpp_args: pocketfft_threads, +- include_directories: inc_pybind11, +- dependencies: fft_deps, ++ dependencies: [fft_deps, pybind11_dep], + link_args: version_link_args, + install: true, + subdir: 'scipy/fft/_pocketfft', +diff --git a/scipy/fftpack/meson.build b/scipy/fftpack/meson.build +index 94165357f..d190213fa 100644 +--- a/scipy/fftpack/meson.build ++++ b/scipy/fftpack/meson.build +@@ -1,7 +1,7 @@ + py3.extension_module('convolve', + cython_gen.process('convolve.pyx'), + c_args: cython_c_args, +- include_directories: inc_np, ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/fftpack' +diff --git a/scipy/integrate/meson.build b/scipy/integrate/meson.build +index 97c85b99d..c1386b928 100644 +--- a/scipy/integrate/meson.build ++++ b/scipy/integrate/meson.build +@@ -102,10 +102,10 @@ py3.extension_module('_quadpack', + ['__quadpack.h', '_quadpackmodule.c'], + c_args: numpy_nodepr_api, + fortran_args: fortran_ignore_warnings, +- include_directories: [inc_np, '../_lib/src'], ++ include_directories: ['../_lib/src'], + link_with: [quadpack_lib, mach_lib], + link_args: version_link_args, +- dependencies: [lapack], ++ dependencies: [lapack, np_dep], + install: true, + link_language: 'fortran', + subdir: 'scipy/integrate' +@@ -117,8 +117,7 @@ py3.extension_module('_odepack', + fortran_args: fortran_ignore_warnings, + link_with: [lsoda_lib, mach_lib], + link_args: version_link_args, +- dependencies: [lapack], +- include_directories: [inc_np], ++ dependencies: [lapack, np_dep], + install: true, + link_language: 'fortran', + subdir: 'scipy/integrate' +@@ -134,7 +133,6 @@ py3.extension_module('_vode', + vode_module, + link_with: [vode_lib], + c_args: [numpy_nodepr_api, Wno_unused_variable], +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + dependencies: [lapack, fortranobject_dep], + install: true, +@@ -153,7 +151,6 @@ py3.extension_module('_lsoda', + link_with: [lsoda_lib, mach_lib], + c_args: [numpy_nodepr_api, Wno_unused_variable], + dependencies: [lapack, fortranobject_dep], +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + install: true, + link_language: 'fortran', +@@ -171,7 +168,6 @@ py3.extension_module('_dop', + link_with: [dop_lib], + c_args: [numpy_nodepr_api, Wno_unused_variable], + dependencies: [fortranobject_dep], +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + install: true, + link_language: 'fortran', +@@ -196,7 +192,6 @@ py3.extension_module('_test_odeint_banded', + c_args: numpy_nodepr_api, + link_with: [lsoda_lib, mach_lib], + fortran_args: _fflag_Wno_unused_dummy_argument, +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + dependencies: [lapack, fortranobject_dep], + install: true, +diff --git a/scipy/interpolate/meson.build b/scipy/interpolate/meson.build +index 16ab3afe5..1ca52f989 100644 +--- a/scipy/interpolate/meson.build ++++ b/scipy/interpolate/meson.build +@@ -96,7 +96,7 @@ fitpack_lib = static_library('fitpack_lib', + interpnd = py3.extension_module('interpnd', + spt_cython_gen.process('interpnd.pyx'), + c_args: [Wno_discarded_qualifiers, cython_c_args], +- include_directories: [incdir_numpy], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/interpolate' +@@ -105,7 +105,7 @@ interpnd = py3.extension_module('interpnd', + py3.extension_module('_ppoly', + linalg_cython_gen.process('_ppoly.pyx'), + c_args: cython_c_args, +- include_directories: [incdir_numpy], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/interpolate' +@@ -114,8 +114,7 @@ py3.extension_module('_ppoly', + py3.extension_module('_rgi_cython', + linalg_cython_gen.process('_rgi_cython.pyx'), + c_args: cython_c_args, +- include_directories: [incdir_numpy], +- dependencies: [py3_dep], ++ dependencies: np_dep, + install: true, + subdir: 'scipy/interpolate' + ) +@@ -123,7 +122,8 @@ py3.extension_module('_rgi_cython', + _bspl = py3.extension_module('_bspl', + cython_gen.process('_bspl.pyx'), + c_args: cython_c_args, +- include_directories: ['src/', incdir_numpy], ++ include_directories: 'src/', ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/interpolate' +@@ -134,7 +134,8 @@ _fitpack = py3.extension_module('_fitpack', + ['src/_fitpackmodule.c'], + c_args: numpy_nodepr_api, + link_with: [fitpack_lib], +- include_directories: ['src/', incdir_numpy], ++ include_directories: 'src/', ++ dependencies: np_dep, + link_args: version_link_args, + link_language: 'fortran', + install: true, +@@ -151,7 +152,6 @@ dfitpack_module = custom_target('dfitpack_module', + dfitpack = py3.extension_module('dfitpack', + dfitpack_module, + c_args: [numpy_nodepr_api, Wno_unused_variable], +- include_directories: [incdir_numpy, incdir_f2py], + link_args: version_link_args, + dependencies: [lapack, fortranobject_dep], + link_with: [fitpack_lib], +@@ -170,7 +170,7 @@ if use_pythran + _rbfinterp_pythran = py3.extension_module('_rbfinterp_pythran', + _rbfinterp_pythran, + cpp_args: cpp_args_pythran, +- include_directories: [incdir_pythran, incdir_numpy], ++ dependencies: [pythran_dep, np_dep], + link_args: version_link_args, + install: true, + subdir: 'scipy/interpolate' +diff --git a/scipy/io/matlab/meson.build b/scipy/io/matlab/meson.build +index 1fe4d9d07..5eeef4bbb 100644 +--- a/scipy/io/matlab/meson.build ++++ b/scipy/io/matlab/meson.build +@@ -9,7 +9,7 @@ streams = py3.extension_module('_streams', + mio_utils = py3.extension_module('_mio_utils', + cython_gen.process('_mio_utils.pyx'), + c_args: cython_c_args, +- include_directories: [incdir_numpy], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/io/matlab' +@@ -18,7 +18,7 @@ mio_utils = py3.extension_module('_mio_utils', + mio5_utils = py3.extension_module('_mio5_utils', + cython_gen.process('_mio5_utils.pyx'), + c_args: cython_c_args, +- include_directories: [incdir_numpy], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/io/matlab' +diff --git a/scipy/io/meson.build b/scipy/io/meson.build +index 515047d2d..afe8c391d 100644 +--- a/scipy/io/meson.build ++++ b/scipy/io/meson.build +@@ -11,7 +11,6 @@ _test_fortran = py3.extension_module('_test_fortran', + ], + c_args: [numpy_nodepr_api, Wno_unused_variable], + fortran_args: fortran_ignore_warnings, +- include_directories: [incdir_numpy, incdir_f2py], + link_args: version_link_args, + dependencies: [lapack, fortranobject_dep], + install: true, +diff --git a/scipy/linalg/meson.build b/scipy/linalg/meson.build +index ce383e5d5..bf1b74e7f 100644 +--- a/scipy/linalg/meson.build ++++ b/scipy/linalg/meson.build +@@ -53,7 +53,6 @@ fblas_module = custom_target('fblas_module', + py3.extension_module('_fblas', + [fblas_module, g77_abi_wrappers], + c_args: numpy_nodepr_api, +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + dependencies: [blas, lapack, fortranobject_dep], + install: true, +@@ -74,7 +73,6 @@ flapack_module = custom_target('flapack_module', + py3.extension_module('_flapack', + [flapack_module, g77_abi_wrappers], + c_args: [numpy_nodepr_api, Wno_empty_body], +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + dependencies: [lapack, fortranobject_dep], + install: true, +@@ -94,7 +92,6 @@ flinalg_module = custom_target('flinalg_module', + py3.extension_module('_flinalg', + ['src/det.f', 'src/lu.f', flinalg_module], + c_args: numpy_nodepr_api, +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + dependencies: [lapack, fortranobject_dep], + install: true, +@@ -156,7 +153,6 @@ py3.extension_module('_interpolative', + ], + c_args: numpy_nodepr_api, + fortran_args: [fortran_ignore_warnings, _suppress_all_warnings], +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + dependencies: [lapack, fortranobject_dep], + install: true, +@@ -168,7 +164,7 @@ py3.extension_module('_interpolative', + py3.extension_module('_solve_toeplitz', + linalg_init_cython_gen.process('_solve_toeplitz.pyx'), + c_args: cython_c_args, +- include_directories: inc_np, ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/linalg' +@@ -178,7 +174,7 @@ py3.extension_module('_solve_toeplitz', + py3.extension_module('_matfuncs_sqrtm_triu', + linalg_init_cython_gen.process('_matfuncs_sqrtm_triu.pyx'), + c_args: cython_c_args, +- include_directories: inc_np, ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/linalg' +@@ -202,9 +198,8 @@ cython_blas = py3.extension_module('cython_blas', + ], + c_args: cython_c_args, + link_with: fwrappers, +- include_directories: inc_np, + link_args: version_link_args, +- dependencies: [blas, lapack], ++ dependencies: [blas, lapack, np_dep], + install: true, + link_language: 'fortran', + subdir: 'scipy/linalg' +@@ -218,9 +213,8 @@ cython_lapack = py3.extension_module('cython_lapack', + ], + c_args: cython_c_args, + link_with: fwrappers, +- include_directories: inc_np, + link_args: version_link_args, +- dependencies: [blas, lapack], ++ dependencies: [blas, lapack, np_dep], + install: true, + link_language: 'fortran', + subdir: 'scipy/linalg' +@@ -235,7 +229,7 @@ _decomp_update_pyx = custom_target('_decomp_update', + py3.extension_module('_decomp_update', + linalg_cython_gen.process(_decomp_update_pyx), + c_args: cython_c_args, +- include_directories: inc_np, ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/linalg' +@@ -251,7 +245,7 @@ _matfuncs_expm_pyx = custom_target('_matfuncs_expm', + py3.extension_module('_matfuncs_expm', + linalg_cython_gen.process(_matfuncs_expm_pyx), + c_args: cython_c_args, +- include_directories: inc_np, ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/linalg' +@@ -260,7 +254,7 @@ py3.extension_module('_matfuncs_expm', + _cythonized_array_utils = py3.extension_module('_cythonized_array_utils', + linalg_init_utils_cython_gen.process('_cythonized_array_utils.pyx'), + c_args: [cython_c_args, Wno_maybe_uninitialized], +- include_directories: [inc_np], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/linalg' +diff --git a/scipy/meson.build b/scipy/meson.build +index 21ea04d5e..a7a9ba7ae 100644 +--- a/scipy/meson.build ++++ b/scipy/meson.build +@@ -37,50 +37,86 @@ endif + thread_dep = dependency('threads', required: false) + + # NumPy include directory - needed in all submodules ++# The chdir is needed because within numpy there's an `import signal` ++# statement, and we don't want that to pick up scipy's signal module rather ++# than the stdlib module. The try-except is needed because when things are ++# split across drives on Windows, there is no relative path and an exception ++# gets raised. There may be other such cases, so add a catch-all and switch to ++# an absolute path. Relative paths are needed when for example a virtualenv is ++# placed inside the source tree; Meson rejects absolute paths to places inside ++# the source tree. + incdir_numpy = run_command(py3, + [ + '-c', +- 'import os; os.chdir(".."); import numpy; print(numpy.get_include())' ++ '''import os ++os.chdir(os.path.join("..", "tools")) ++import numpy as np ++try: ++ incdir = os.path.relpath(np.get_include()) ++except Exception: ++ incdir = np.get_include() ++print(incdir) ++''' + ], + check: true + ).stdout().strip() +- + inc_np = include_directories(incdir_numpy) ++np_dep = declare_dependency(include_directories: inc_np) + + incdir_f2py = incdir_numpy / '..' / '..' / 'f2py' / 'src' + inc_f2py = include_directories(incdir_f2py) + fortranobject_c = incdir_f2py / 'fortranobject.c' + ++# We do need an absolute path to feed to `cc.find_library` below ++_incdir_numpy_abs = run_command(py3, ++ ['-c', 'import os; os.chdir(".."); import numpy; print(numpy.get_include())'], ++ check: true ++).stdout().strip() ++ + cc = meson.get_compiler('c') +-npymath_path = incdir_numpy / '..' / 'lib' ++npymath_path = _incdir_numpy_abs / '..' / 'lib' ++npyrandom_path = _incdir_numpy_abs / '..' / '..' / 'random' / 'lib' + npymath_lib = cc.find_library('npymath', dirs: npymath_path) +-npyrandom_path = incdir_numpy / '..' / '..' / 'random' / 'lib' +-# Note: `required: false` can be removed once numpy 1.19 is the minimum version +-npyrandom_lib = cc.find_library('npyrandom', dirs: npyrandom_path, required: false) ++npyrandom_lib = cc.find_library('npyrandom', dirs: npyrandom_path) + + # pybind11 include directory - needed in several submodules + incdir_pybind11 = run_command(py3, + [ + '-c', +- 'import pybind11; print(pybind11.get_include())' ++ '''from os.path import relpath ++import pybind11 ++try: ++ incdir = relpath(pybind11.get_include()) ++except Exception: ++ incdir = pybind11.get_include() ++print(incdir) ++''' + ], + check: true + ).stdout().strip() + +-inc_pybind11 = include_directories(incdir_pybind11) ++pybind11_dep = declare_dependency(include_directories: incdir_pybind11) + + # Pythran include directory and build flags + if use_pythran + incdir_pythran = run_command(py3, + [ + '-c', +- 'import os; os.chdir(".."); import pythran; print(os.path.dirname(pythran.__file__));' ++ '''import os ++os.chdir(os.path.join("..", "tools")) ++import pythran ++try: ++ incdir = os.path.relpath(pythran.get_include()) ++except Exception: ++ incdir = pythran.get_include() ++print(incdir) ++''' + ], + check: true + ).stdout().strip() +- inc_pythran = include_directories(incdir_pythran) ++ pythran_dep = declare_dependency(include_directories: incdir_pythran) + else +- inc_pythran = [] ++ pythran_dep = [] + endif + + # Note: warning flags are added to this further down +diff --git a/scipy/ndimage/meson.build b/scipy/ndimage/meson.build +index 69989a06d..4af9fbada 100644 +--- a/scipy/ndimage/meson.build ++++ b/scipy/ndimage/meson.build +@@ -9,7 +9,8 @@ py3.extension_module('_nd_image', + 'src/ni_splines.c', + 'src/ni_support.c' + ], +- include_directories: [incdir_numpy, '../_lib/src'], ++ include_directories: '../_lib/src', ++ dependencies: np_dep, + link_args: version_link_args, + c_args: numpy_nodepr_api, + install: true, +@@ -19,7 +20,7 @@ py3.extension_module('_nd_image', + py3.extension_module('_ni_label', + cython_gen.process('src/_ni_label.pyx'), + c_args: cython_c_args, +- include_directories: incdir_numpy, ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/ndimage' +@@ -27,7 +28,7 @@ py3.extension_module('_ni_label', + + py3.extension_module('_ctest', + 'src/_ctest.c', +- include_directories: incdir_numpy, ++ dependencies: np_dep, + c_args: numpy_nodepr_api, + link_args: version_link_args, + install: true, +@@ -37,7 +38,7 @@ py3.extension_module('_ctest', + py3.extension_module('_cytest', + cython_gen.process('src/_cytest.pyx'), + c_args: cython_c_args, +- include_directories: incdir_numpy, ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/ndimage' +diff --git a/scipy/odr/meson.build b/scipy/odr/meson.build +index 5f1a3e62a..b4232084b 100644 +--- a/scipy/odr/meson.build ++++ b/scipy/odr/meson.build +@@ -11,10 +11,9 @@ odrpack = static_library('odrpack', + py3.extension_module('__odrpack', + '__odrpack.c', + link_with: odrpack, +- include_directories: inc_np, + link_args: version_link_args, + c_args: numpy_nodepr_api, +- dependencies: [blas], ++ dependencies: [blas, np_dep], + install: true, + link_language: 'fortran', + subdir: 'scipy/odr' +diff --git a/scipy/optimize/_highs/meson.build b/scipy/optimize/_highs/meson.build +index 5051a08b9..8d701e5e3 100644 +--- a/scipy/optimize/_highs/meson.build ++++ b/scipy/optimize/_highs/meson.build +@@ -229,7 +229,6 @@ highs_lib = static_library('highs', + _highs_wrapper = py3.extension_module('_highs_wrapper', + cython_gen_cpp.process('cython/src/_highs_wrapper.pyx'), + include_directories: [ +- inc_np, + 'cython/src/', + 'src/', + '../../_lib/highs/src/', +@@ -237,7 +236,7 @@ _highs_wrapper = py3.extension_module('_highs_wrapper', + '../../_lib/highs/src/lp_data/', + '../../_lib/highs/src/util/' + ], +- dependencies: [thread_dep, atomic_dep], ++ dependencies: [np_dep, thread_dep, atomic_dep], + link_args: version_link_args, + link_with: [highs_lib, ipx_lib, basiclu_lib], + cpp_args: [highs_flags, highs_define_macros, cython_c_args], +diff --git a/scipy/optimize/_lsq/meson.build b/scipy/optimize/_lsq/meson.build +index 496a84f03..14b971f1b 100644 +--- a/scipy/optimize/_lsq/meson.build ++++ b/scipy/optimize/_lsq/meson.build +@@ -1,7 +1,7 @@ + _lsq = py3.extension_module('givens_elimination', + linalg_cython_gen.process('givens_elimination.pyx'), + c_args: cython_c_args, +- include_directories: [inc_np], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/optimize/_lsq' +diff --git a/scipy/optimize/_trlib/meson.build b/scipy/optimize/_trlib/meson.build +index 66fa0a392..f91a2bbb3 100644 +--- a/scipy/optimize/_trlib/meson.build ++++ b/scipy/optimize/_trlib/meson.build +@@ -8,12 +8,11 @@ _trlib = py3.extension_module('_trlib', + 'trlib_tri_factor.c' + ], + c_args: cython_c_args, +- dependencies: [lapack], + include_directories: [ +- inc_np, + '../../_lib', + '../../_build_utils/src' + ], ++ dependencies: [lapack, np_dep], + link_args: version_link_args, + install: true, + subdir: 'scipy/optimize/_trlib' +diff --git a/scipy/optimize/cython_optimize/meson.build b/scipy/optimize/cython_optimize/meson.build +index 3604ad1b0..359ea8418 100644 +--- a/scipy/optimize/cython_optimize/meson.build ++++ b/scipy/optimize/cython_optimize/meson.build +@@ -23,7 +23,7 @@ cy_opt_gen = generator(cython, + _zeros = py3.extension_module('_zeros', + cy_opt_gen.process(_zeros_pyx), + c_args: cython_c_args, +- include_directories: inc_np, ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/optimize/cython_optimize' +diff --git a/scipy/optimize/meson.build b/scipy/optimize/meson.build +index 05db6a680..8a517797f 100644 +--- a/scipy/optimize/meson.build ++++ b/scipy/optimize/meson.build +@@ -1,5 +1,3 @@ +-include_dirs = [inc_np, '../_lib/src'] +- + _direct = py3.extension_module('_direct', + ['_direct/direct_wrap.c', + '_direct/direct-internal.h', +@@ -10,7 +8,8 @@ _direct = py3.extension_module('_direct', + '_directmodule.c' + ], + c_args: [numpy_nodepr_api], +- include_directories: include_dirs, ++ include_directories: '../_lib/src', ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/optimize' +@@ -48,7 +47,8 @@ _minpack = py3.extension_module('_minpack', + ['minpack.h', '__minpack.h', '_minpackmodule.c'], + link_with: minpack_lib, + c_args: numpy_nodepr_api, +- include_directories: include_dirs, ++ include_directories: '../_lib/src', ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + link_language: 'fortran', +@@ -66,7 +66,8 @@ py3.extension_module('_lsap', + ['_lsap.c'], + link_with: rectangular_lsap, + c_args: numpy_nodepr_api, +- include_directories: include_dirs, ++ include_directories: '../_lib/src', ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/optimize' +@@ -86,7 +87,7 @@ py3.extension_module('_zeros', + 'zeros.c', + link_with: rootfind_lib, + c_args: numpy_nodepr_api, +- include_directories: inc_np, ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/optimize' +@@ -107,7 +108,6 @@ _lbfgsb = py3.extension_module('_lbfgsb', + ], + c_args: numpy_nodepr_api, + fortran_args: fortran_ignore_warnings, +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + dependencies: [lapack, fortranobject_dep], + install: true, +@@ -120,7 +120,8 @@ moduleTNC = py3.extension_module('_moduleTNC', + cython_gen.process('tnc/_moduleTNC.pyx'), + 'tnc/tnc.c'], + c_args: cython_c_args, +- include_directories: [inc_np, inc_f2py, 'tnc'], ++ include_directories: 'tnc', ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/optimize' +@@ -136,7 +137,6 @@ _cobyla = py3.extension_module('_cobyla', + [cobyla_module, 'cobyla/cobyla2.f', 'cobyla/trstlp.f'], + c_args: [numpy_nodepr_api, Wno_unused_variable], + fortran_args: fortran_ignore_warnings, +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + dependencies: [fortranobject_dep], + install: true, +@@ -154,7 +154,6 @@ minpack2 = py3.extension_module('_minpack2', + [minpack2_module, 'minpack2/dcsrch.f', 'minpack2/dcstep.f'], + c_args: numpy_nodepr_api, + fortran_args: fortran_ignore_warnings, +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + dependencies: [fortranobject_dep], + install: true, +@@ -172,7 +171,6 @@ _slsqp = py3.extension_module('_slsqp', + [slsqp_module, 'slsqp/slsqp_optmz.f'], + c_args: numpy_nodepr_api, + fortran_args: fortran_ignore_warnings, +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + dependencies: [fortranobject_dep], + install: true, +@@ -195,7 +193,6 @@ __nnls = py3.extension_module('__nnls', + ['__nnls/nnls.f', __nnls_module], + c_args: numpy_nodepr_api, + fortran_args: fortran_ignore_warnings, +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + dependencies: [fortranobject_dep], + install: true, +@@ -213,7 +210,7 @@ if use_pythran + _group_columns = py3.extension_module('_group_columns', + [_group_columns_cpp], + cpp_args: cpp_args_pythran, +- include_directories: [incdir_pythran, incdir_numpy], ++ dependencies: [pythran_dep, np_dep], + link_args: version_link_args, + install: true, + subdir: 'scipy/optimize' +@@ -222,7 +219,7 @@ else + _group_columns = py3.extension_module('_group_columns', + cython_gen.process('_group_columns.pyx'), + c_args: cython_c_args, +- include_directories: [inc_np], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/optimize' +@@ -241,7 +238,7 @@ _bglu_dense_c = opt_gen.process('_bglu_dense.pyx') + py3.extension_module('_bglu_dense', + _bglu_dense_c, + c_args: cython_c_args, +- include_directories: [inc_np], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/optimize' +diff --git a/scipy/signal/meson.build b/scipy/signal/meson.build +index 09410080b..64055bd7a 100644 +--- a/scipy/signal/meson.build ++++ b/scipy/signal/meson.build +@@ -20,7 +20,7 @@ sigtools = py3.extension_module('_sigtools', + correlate_nd_c + ], + c_args: numpy_nodepr_api, +- include_directories: [inc_np], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/signal' +@@ -36,7 +36,7 @@ if use_pythran + _max_len_seq_inner = py3.extension_module('_max_len_seq_inner', + [_max_len_seq_inner], + cpp_args: [cpp_args_pythran, _cpp_Wno_unused_local_typedefs], +- include_directories: [incdir_pythran, incdir_numpy], ++ dependencies: [pythran_dep, np_dep], + link_args: version_link_args, + install: true, + subdir: 'scipy/signal' +@@ -51,7 +51,7 @@ if use_pythran + _spectral = py3.extension_module('_spectral', + [_spectral], + cpp_args: cpp_args_pythran, +- include_directories: [incdir_pythran, incdir_numpy], ++ dependencies: [pythran_dep, np_dep], + link_args: version_link_args, + install: true, + subdir: 'scipy/signal' +@@ -60,7 +60,7 @@ else + _max_len_seq_inner = py3.extension_module('_max_len_seq_inner', + [cython_gen.process('_max_len_seq_inner.pyx')], + c_args: cython_c_args, +- include_directories: [inc_np], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/signal' +@@ -69,7 +69,7 @@ else + _spectral = py3.extension_module('_spectral', + [cython_gen.process('_spectral.pyx')], + c_args: cython_c_args, +- include_directories: [inc_np], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/signal' +@@ -86,7 +86,7 @@ foreach pyx_file: pyx_files + py3.extension_module(pyx_file[0], + cython_gen.process(pyx_file[1]), + c_args: cython_c_args, +- include_directories: [inc_np], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/signal' +@@ -102,7 +102,7 @@ bspline_util = custom_target('_bspline_util', + spline = py3.extension_module('_spline', + ['_splinemodule.c', bspline_util], + c_args: numpy_nodepr_api, +- include_directories: [inc_np], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/signal' +diff --git a/scipy/sparse/csgraph/meson.build b/scipy/sparse/csgraph/meson.build +index 9c33787db..4bd1fe36f 100644 +--- a/scipy/sparse/csgraph/meson.build ++++ b/scipy/sparse/csgraph/meson.build +@@ -12,7 +12,7 @@ foreach pyx_file: pyx_files + py3.extension_module(pyx_file[0], + cython_gen.process(pyx_file[1]), + c_args: cython_c_args, +- include_directories: inc_np, ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/sparse/csgraph' +diff --git a/scipy/sparse/linalg/_dsolve/meson.build b/scipy/sparse/linalg/_dsolve/meson.build +index bf16643fe..4277927a5 100644 +--- a/scipy/sparse/linalg/_dsolve/meson.build ++++ b/scipy/sparse/linalg/_dsolve/meson.build +@@ -197,9 +197,9 @@ _superlu = py3.extension_module('_superlu', + ['_superlumodule.c', '_superlu_utils.c', '_superluobject.c'], + c_args: numpy_nodepr_api, + link_with: [superlu_lib], +- include_directories: [incdir_numpy, 'SuperLU/SRC'], ++ include_directories: ['SuperLU/SRC'], + link_args: version_link_args, +- dependencies: [blas, lapack], ++ dependencies: [blas, lapack, np_dep], + install: true, + subdir: 'scipy/sparse/linalg/_dsolve' + ) +diff --git a/scipy/sparse/linalg/_eigen/arpack/meson.build b/scipy/sparse/linalg/_eigen/arpack/meson.build +index bc77d411a..ce8125b46 100644 +--- a/scipy/sparse/linalg/_eigen/arpack/meson.build ++++ b/scipy/sparse/linalg/_eigen/arpack/meson.build +@@ -101,7 +101,6 @@ _arpack = py3.extension_module('_arpack', + [arpack_module, g77_abi_wrappers], + c_args: numpy_nodepr_api, + link_with: [arpack_lib], +- include_directories: [incdir_numpy, incdir_f2py], + link_args: version_link_args, + dependencies: [lapack, fortranobject_dep], + install: true, +diff --git a/scipy/sparse/linalg/_isolve/meson.build b/scipy/sparse/linalg/_isolve/meson.build +index 300920186..70a9220da 100644 +--- a/scipy/sparse/linalg/_isolve/meson.build ++++ b/scipy/sparse/linalg/_isolve/meson.build +@@ -72,7 +72,6 @@ _iterative = py3.extension_module('_iterative', + ], + c_args: numpy_nodepr_api, + fortran_args: fortran_ignore_warnings, +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + dependencies: [lapack, fortranobject_dep], + install: true, +diff --git a/scipy/sparse/linalg/_propack/meson.build b/scipy/sparse/linalg/_propack/meson.build +index 745d010ce..fb8d99c66 100644 +--- a/scipy/sparse/linalg/_propack/meson.build ++++ b/scipy/sparse/linalg/_propack/meson.build +@@ -110,7 +110,6 @@ foreach ele: elements + c_args: ['-U_OPENMP', _cpp_Wno_cpp], + fortran_args: _fflag_Wno_maybe_uninitialized, + dependencies: [lapack, fortranobject_dep], +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + install: true, + link_language: 'fortran', +diff --git a/scipy/sparse/meson.build b/scipy/sparse/meson.build +index 2cae8e4db..507a884c1 100644 +--- a/scipy/sparse/meson.build ++++ b/scipy/sparse/meson.build +@@ -7,7 +7,7 @@ _csparsetools_pyx = custom_target('_csparsetools_pyx', + py3.extension_module('_csparsetools', + cython_gen.process(_csparsetools_pyx), + c_args: cython_c_args, +- include_directories: inc_np, ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/sparse' +diff --git a/scipy/sparse/sparsetools/meson.build b/scipy/sparse/sparsetools/meson.build +index 60e89816d..57b66d55f 100644 +--- a/scipy/sparse/sparsetools/meson.build ++++ b/scipy/sparse/sparsetools/meson.build +@@ -20,7 +20,7 @@ py3.extension_module('_sparsetools', + _sparsetools_headers, + ], + cpp_args: numpy_nodepr_api, +- include_directories: inc_np, ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/sparse' +diff --git a/scipy/spatial/meson.build b/scipy/spatial/meson.build +index 895e506ae..e210ecfed 100644 +--- a/scipy/spatial/meson.build ++++ b/scipy/spatial/meson.build +@@ -35,13 +35,12 @@ qhull = py3.extension_module('_qhull', + 'qhull_misc.h', 'qhull_misc.c'] + qhull_src, + c_args: cython_c_args, + include_directories: [ +- incdir_numpy, + '../_lib', + '../_build_utils/src', + 'qhull_src/src' + ], + link_args: version_link_args, +- dependencies: [lapack], ++ dependencies: [lapack, np_dep], + install: true, + subdir: 'scipy/spatial' + ) +@@ -60,11 +59,11 @@ ckdtree = py3.extension_module('_ckdtree', + ckdtree_src + [cython_gen_cpp.process('_ckdtree.pyx')], + cpp_args: cython_cpp_args, + include_directories: [ +- incdir_numpy, + '../_lib', + '../_build_utils/src', + 'ckdtree/src' + ], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/spatial' +@@ -73,7 +72,8 @@ ckdtree = py3.extension_module('_ckdtree', + _distance_wrap = py3.extension_module('_distance_wrap', + 'src/distance_wrap.c', + c_args: numpy_nodepr_api, +- include_directories: [incdir_numpy, '../_lib'], ++ include_directories: '../_lib', ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/spatial' +@@ -82,7 +82,8 @@ _distance_wrap = py3.extension_module('_distance_wrap', + _distance_pybind = py3.extension_module('_distance_pybind', + ['src/distance_pybind.cpp'], + cpp_args: [numpy_nodepr_api], +- include_directories: [incdir_pybind11, incdir_numpy, 'src/'], ++ include_directories: 'src/', ++ dependencies: [np_dep, pybind11_dep], + link_args: version_link_args, + install: true, + subdir: 'scipy/spatial' +@@ -91,7 +92,7 @@ _distance_pybind = py3.extension_module('_distance_pybind', + _voronoi = py3.extension_module('_voronoi', + [cython_gen.process('_voronoi.pyx')], + c_args: [cython_c_args, Wno_maybe_uninitialized], +- include_directories: [incdir_numpy], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/spatial' +@@ -100,7 +101,7 @@ _voronoi = py3.extension_module('_voronoi', + _hausdorff = py3.extension_module('_hausdorff', + [cython_gen.process('_hausdorff.pyx')], + c_args: cython_c_args, +- include_directories: [incdir_numpy], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/spatial' +diff --git a/scipy/spatial/transform/meson.build b/scipy/spatial/transform/meson.build +index 480a3a537..5ada030d3 100644 +--- a/scipy/spatial/transform/meson.build ++++ b/scipy/spatial/transform/meson.build +@@ -1,7 +1,7 @@ + rotation = py3.extension_module('_rotation', + [cython_gen.process('_rotation.pyx')], + c_args: [cython_c_args, Wno_maybe_uninitialized], +- include_directories: [incdir_numpy], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/spatial/transform' +diff --git a/scipy/special/meson.build b/scipy/special/meson.build +index f92183f50..99be4561e 100644 +--- a/scipy/special/meson.build ++++ b/scipy/special/meson.build +@@ -238,8 +238,8 @@ ufuncs_cxx_sources = [ + cephes_lib = static_library('cephes', + cephes_sources, + c_args: use_math_defines, +- dependencies: py3_dep, +- include_directories: [inc_np, '../_lib', '../_build_utils/src'], ++ include_directories: ['../_lib', '../_build_utils/src'], ++ dependencies: [py3_dep, np_dep], + ) + + amos_lib = static_library('amos', +@@ -275,7 +275,6 @@ specfun_module = custom_target('specfun_module', + py3.extension_module('_specfun', + specfun_module, + c_args: numpy_nodepr_api, +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + dependencies: [fortranobject_dep], + link_with: specfun_lib, +@@ -323,10 +322,11 @@ py3.extension_module('_ufuncs', + uf_cython_gen.process(cython_special[0]), # _ufuncs.pyx + ], + c_args: [cython_c_args, Wno_maybe_uninitialized], +- include_directories: [inc_np, '../_lib', '../_build_utils/src'], ++ include_directories: ['../_lib', '../_build_utils/src'], + dependencies: [ + lapack, + npymath_lib, ++ np_dep, + ], + link_args: version_link_args, + link_with: [ +@@ -363,10 +363,10 @@ py3.extension_module('_ufuncs_cxx', + uf_cython_gen_cpp.process(cython_special[2]), # _ufuncs_cxx.pyx + ], + cpp_args: cython_cpp_args, +- include_directories: [inc_np, '../_lib/boost', '../_lib', ++ include_directories: ['../_lib/boost', '../_lib', + '../_build_utils/src'], + link_args: version_link_args, +- dependencies: [ellint_dep], ++ dependencies: [np_dep, ellint_dep], + install: true, + subdir: 'scipy/special' + ) +@@ -374,9 +374,9 @@ py3.extension_module('_ufuncs_cxx', + py3.extension_module('_ellip_harm_2', + [uf_cython_gen.process('_ellip_harm_2.pyx'), 'sf_error.c'], + c_args: cython_c_args, +- include_directories: [inc_np, '../_lib', '../_build_utils/src'], ++ include_directories: ['../_lib', '../_build_utils/src'], + link_args: version_link_args, +- dependencies: [lapack], ++ dependencies: [lapack, np_dep], + install: true, + subdir: 'scipy/special' + ) +@@ -391,9 +391,9 @@ py3.extension_module('cython_special', + 'sf_error.c' + ], + c_args: [cython_c_args, Wno_maybe_uninitialized], +- include_directories: [inc_np, '../_lib', '../_build_utils/src', 'cephes'], ++ include_directories: ['../_lib', '../_build_utils/src', 'cephes'], + link_args: version_link_args, +- dependencies: [npymath_lib, lapack], ++ dependencies: [np_dep, npymath_lib, lapack], + link_with: [ + amos_lib, + cdflib_lib, +@@ -417,8 +417,8 @@ dd_dep = declare_dependency(sources: ['cephes/dd_real.c']) + + py3.extension_module('_test_internal', + cython_gen.process('_test_internal.pyx'), +- include_directories: [inc_np, 'cephes', '../_lib', '../_build_utils/src'], +- dependencies: [py3_dep, dd_dep], ++ include_directories: ['cephes', '../_lib', '../_build_utils/src'], ++ dependencies: [np_dep, dd_dep], + link_args: version_link_args, + install: true, + subdir: 'scipy/special' +diff --git a/scipy/stats/_boost/meson.build b/scipy/stats/_boost/meson.build +index a0137f996..851bee4d3 100644 +--- a/scipy/stats/_boost/meson.build ++++ b/scipy/stats/_boost/meson.build +@@ -23,7 +23,8 @@ pyx_files = [ + foreach pyx_file: pyx_files + py3.extension_module(pyx_file[0], + pyx_file[1], +- include_directories: [inc_np, 'include', '../../_lib/boost'], ++ include_directories: ['include', '../../_lib/boost'], ++ dependencies: np_dep, + link_args: version_link_args, + cpp_args: [cpp_args, cython_cpp_args], + install: true, +diff --git a/scipy/stats/_levy_stable/meson.build b/scipy/stats/_levy_stable/meson.build +index ed5769a49..9f6acafa0 100644 +--- a/scipy/stats/_levy_stable/meson.build ++++ b/scipy/stats/_levy_stable/meson.build +@@ -11,7 +11,7 @@ _levyst = static_library('_levyst', + levyst = py3.extension_module('levyst', + cython_gen.process('levyst.pyx'), + c_args: numpy_nodepr_api, +- include_directories: [inc_np], ++ dependencies: np_dep, + link_args: version_link_args, + link_with: _levyst, + install: true, +diff --git a/scipy/stats/_rcont/meson.build b/scipy/stats/_rcont/meson.build +index b9bf1a922..0dbdf96ff 100644 +--- a/scipy/stats/_rcont/meson.build ++++ b/scipy/stats/_rcont/meson.build +@@ -9,9 +9,8 @@ rcont = py3.extension_module('rcont', + ['_rcont.c', 'logfactorial.c'], + cython_gen.process('rcont.pyx'), + c_args: numpy_nodepr_api, +- include_directories: [inc_np], ++ dependencies: [np_dep, npyrandom_lib, npymath_lib], + link_args: version_link_args, + install: true, + subdir: 'scipy/stats/_rcont', +- dependencies: [npyrandom_lib, npymath_lib], + ) +diff --git a/scipy/stats/_unuran/meson.build b/scipy/stats/_unuran/meson.build +index 22bbc8cfc..b85deba0c 100644 +--- a/scipy/stats/_unuran/meson.build ++++ b/scipy/stats/_unuran/meson.build +@@ -215,7 +215,8 @@ statlib = py3.extension_module('unuran_wrapper', + unuran_sources + ], + c_args: [unuran_defines, cython_c_args], +- include_directories: [inc_np, unuran_include_dirs], ++ include_directories: [unuran_include_dirs], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/stats/_unuran' +diff --git a/scipy/stats/meson.build b/scipy/stats/meson.build +index 0fca32054..828ccbe5c 100644 +--- a/scipy/stats/meson.build ++++ b/scipy/stats/meson.build +@@ -35,7 +35,6 @@ statlib = py3.extension_module('_statlib', + fortran_args: fortran_ignore_warnings, + link_with: statlib_lib, + dependencies: [fortranobject_dep], +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + install: true, + link_language: 'fortran', +@@ -45,7 +44,7 @@ statlib = py3.extension_module('_statlib', + _stats = py3.extension_module('_stats', + stats_special_cython_gen.process('_stats.pyx'), + c_args: cython_c_args, +- include_directories: [inc_np], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/stats' +@@ -64,7 +63,6 @@ mvn = py3.extension_module('_mvn', + # (see GCC bug 98411: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98411) + fortran_args: [fortran_ignore_warnings, _fflag_Wno_surprising], + dependencies: [fortranobject_dep], +- include_directories: [inc_np, inc_f2py], + link_args: version_link_args, + install: true, + link_language: 'fortran', +@@ -74,7 +72,7 @@ mvn = py3.extension_module('_mvn', + _sobol = py3.extension_module('_sobol', + cython_gen.process('_sobol.pyx'), + c_args: cython_c_args, +- include_directories: [inc_np], ++ dependencies: np_dep, + link_args: version_link_args, + install: true, + subdir: 'scipy/stats' +@@ -89,8 +87,7 @@ py3.install_sources([ + _qmc_cy = py3.extension_module('_qmc_cy', + cython_gen_cpp.process('_qmc_cy.pyx'), + cpp_args: cython_cpp_args, +- dependencies: thread_dep, +- include_directories: [inc_np], ++ dependencies: [np_dep, thread_dep], + link_args: version_link_args, + install: true, + subdir: 'scipy/stats' +@@ -148,10 +145,9 @@ biasedurn = py3.extension_module('_biasedurn', + 'biasedurn/wnchyppr.cpp', + ], + cpp_args: ['-DR_BUILD', cython_cpp_args], +- include_directories: [inc_np], + link_args: version_link_args, + # Note that we're not using npymath directly, it is needed to use npyrandom +- dependencies: [npyrandom_lib, npymath_lib], ++ dependencies: [np_dep, npyrandom_lib, npymath_lib], + install: true, + subdir: 'scipy/stats' + ) +@@ -166,7 +162,7 @@ if use_pythran + _stats_pythran = py3.extension_module('_stats_pythran', + _stats_pythran_cpp, + cpp_args: cpp_args_pythran, +- include_directories: [incdir_pythran, incdir_numpy], ++ dependencies: [pythran_dep, np_dep], + link_args: version_link_args, + install: true, + subdir: 'scipy/stats' +-- +2.38.1.windows.1 + diff --git a/recipe/patches/0002-BLD-avoid-running-run_command-py3-.-for-better-cross.patch b/recipe/patches/0002-BLD-avoid-running-run_command-py3-.-for-better-cross.patch new file mode 100644 index 00000000..3c6a8923 --- /dev/null +++ b/recipe/patches/0002-BLD-avoid-running-run_command-py3-.-for-better-cross.patch @@ -0,0 +1,227 @@ +From 60c26eccbd97de83d0cba143146365527667d0f8 Mon Sep 17 00:00:00 2001 +From: Ralf Gommers +Date: Thu, 23 Feb 2023 14:43:52 +0000 +Subject: [PATCH 2/2] BLD: avoid running `run_command(py3, ...)`, for better + cross-compiling + +Adding the ability to specify the paths to the numpy, pybind11 and +pythran include directories was discussed in gh-14812. Short of +pkg-config files for these packages and/or builtin support for them in +Meson, this is a decent solution. +--- + doc/source/dev/contributor/meson_advanced.rst | 23 ++++++ + meson.build | 12 +-- + meson_options.txt | 4 + + scipy/meson.build | 81 +++++++++++-------- + 4 files changed, 78 insertions(+), 42 deletions(-) + +diff --git a/doc/source/dev/contributor/meson_advanced.rst b/doc/source/dev/contributor/meson_advanced.rst +index 338b43df6..e87bc73e7 100644 +--- a/doc/source/dev/contributor/meson_advanced.rst ++++ b/doc/source/dev/contributor/meson_advanced.rst +@@ -62,6 +62,29 @@ twice, while ``build`` does support that. + -I/path/to/include-dir + + ++Cross compilation ++================= ++ ++Cross compilation is a complex topic, we only add some hopefully helpful hints ++here (for now). Please see ++`Meson's documentation on cross compilation `__ ++for context. ++ ++One common hiccup is that ``numpy``, ``pybind11`` and ``pythran`` require ++running Python code in order to obtain their include directories. This tends to ++not work well, either accidentally picking up the packages from the build ++(native) Python rather than the host (cross) Python or requiring ``crossenv`` ++or QEMU to run the host Python. To avoid this problem, specify the paths to the ++relevant directories in your *cross file*: ++ ++.. code:: ini ++ ++ [properties] ++ numpy-include-dir = /abspath/to/host-pythons/site-packages/numpy/core/include ++ pybind11-include-dir = /abspath/to/host-pythons/site-packages/pybind11/include ++ pythran-include-dir = /abspath/to/host-pythons/site-packages/pythran ++ ++ + Use different build types with Meson + ==================================== + +diff --git a/meson.build b/meson.build +index ad18b245b..34067d2bd 100644 +--- a/meson.build ++++ b/meson.build +@@ -122,17 +122,9 @@ py_mod = import('python') + py3 = py_mod.find_installation(pure: false) + py3_dep = py3.dependency() + +-# For now, keep supporting this environment variable (same as in setup.py) +-# Once setup.py-based builds are gone, we can convert this to a command-line flag, or make Pythran non-optional. +-use_pythran = run_command(py3, +- [ +- '-c', +- 'import os; print(os.environ.get("SCIPY_USE_PYTHRAN", 1))' +- ], +- check: true +-).stdout().strip() == '1' ++use_pythran = get_option('use-pythran') + if use_pythran +- pythran = find_program('pythran') ++ pythran = find_program('pythran', native: true) + endif + + subdir('scipy') +diff --git a/meson_options.txt b/meson_options.txt +index 5935bb850..a44afe562 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -6,3 +6,7 @@ option('use-g77-abi', type: 'boolean', value: 'false', + description: 'If set to true, forces using g77 compatibility wrappers ' + + 'for LAPACK functions. The default is to use gfortran ' + + 'ABI for all LAPACK libraries except MKL.') ++option('use-pythran', type: 'boolean', value: true, ++ description: 'If set to false, disables using Pythran (it falls back ' + ++ 'to either pure Python code or Cython code, depending on ' + ++ 'the implementation).') +diff --git a/scipy/meson.build b/scipy/meson.build +index a7a9ba7ae..32f909e47 100644 +--- a/scipy/meson.build ++++ b/scipy/meson.build +@@ -45,10 +45,19 @@ thread_dep = dependency('threads', required: false) + # an absolute path. Relative paths are needed when for example a virtualenv is + # placed inside the source tree; Meson rejects absolute paths to places inside + # the source tree. +-incdir_numpy = run_command(py3, +- [ +- '-c', +- '''import os ++# For cross-compilation it is often not possible to run the Python interpreter ++# in order to retrieve numpy's include directory. It can be specified in the ++# cross file instead: ++# [properties] ++# numpy-include-dir = /abspath/to/host-pythons/site-packages/numpy/core/include ++# ++# This uses the path as is, and avoids running the interpreter. ++incdir_numpy = meson.get_external_property('numpy-include-dir', 'not-given') ++if incdir_numpy == 'not-given' ++ incdir_numpy = run_command(py3, ++ [ ++ '-c', ++ '''import os + os.chdir(os.path.join("..", "tools")) + import numpy as np + try: +@@ -56,10 +65,19 @@ try: + except Exception: + incdir = np.get_include() + print(incdir) +-''' +- ], +- check: true +-).stdout().strip() ++ ''' ++ ], ++ check: true ++ ).stdout().strip() ++ ++ # We do need an absolute path to feed to `cc.find_library` below ++ _incdir_numpy_abs = run_command(py3, ++ ['-c', 'import os; os.chdir(".."); import numpy; print(numpy.get_include())'], ++ check: true ++ ).stdout().strip() ++else ++ _incdir_numpy_abs = incdir_numpy ++endif + inc_np = include_directories(incdir_numpy) + np_dep = declare_dependency(include_directories: inc_np) + +@@ -67,23 +85,18 @@ incdir_f2py = incdir_numpy / '..' / '..' / 'f2py' / 'src' + inc_f2py = include_directories(incdir_f2py) + fortranobject_c = incdir_f2py / 'fortranobject.c' + +-# We do need an absolute path to feed to `cc.find_library` below +-_incdir_numpy_abs = run_command(py3, +- ['-c', 'import os; os.chdir(".."); import numpy; print(numpy.get_include())'], +- check: true +-).stdout().strip() +- +-cc = meson.get_compiler('c') + npymath_path = _incdir_numpy_abs / '..' / 'lib' + npyrandom_path = _incdir_numpy_abs / '..' / '..' / 'random' / 'lib' + npymath_lib = cc.find_library('npymath', dirs: npymath_path) + npyrandom_lib = cc.find_library('npyrandom', dirs: npyrandom_path) + + # pybind11 include directory - needed in several submodules +-incdir_pybind11 = run_command(py3, +- [ +- '-c', +- '''from os.path import relpath ++incdir_pybind11 = meson.get_external_property('pybind11-include-dir', 'not-given') ++if incdir_pybind11 == 'not-given' ++ incdir_pybind11 = run_command(py3, ++ [ ++ '-c', ++ '''from os.path import relpath + import pybind11 + try: + incdir = relpath(pybind11.get_include()) +@@ -91,18 +104,22 @@ except Exception: + incdir = pybind11.get_include() + print(incdir) + ''' +- ], +- check: true +-).stdout().strip() +- ++ ], ++ check: true ++ ).stdout().strip() ++endif + pybind11_dep = declare_dependency(include_directories: incdir_pybind11) + + # Pythran include directory and build flags + if use_pythran +- incdir_pythran = run_command(py3, +- [ +- '-c', +- '''import os ++ # This external-property may not be needed if we can use the native include ++ # dir, see https://github.com/serge-sans-paille/pythran/issues/1394 ++ incdir_pythran = meson.get_external_property('pythran-include-dir', 'not-given') ++ if incdir_pythran == 'not-given' ++ incdir_pythran = run_command(py3, ++ [ ++ '-c', ++ '''import os + os.chdir(os.path.join("..", "tools")) + import pythran + try: +@@ -111,9 +128,10 @@ except Exception: + incdir = pythran.get_include() + print(incdir) + ''' +- ], +- check: true +- ).stdout().strip() ++ ], ++ check: true ++ ).stdout().strip() ++ endif + pythran_dep = declare_dependency(include_directories: incdir_pythran) + else + pythran_dep = [] +@@ -396,8 +414,7 @@ foreach name, compiler : compilers + endforeach + # Add `pythran` information if present + if use_pythran +- pythran_version_command = run_command('pythran', '-V', check: true) +- conf_data.set('PYTHRAN_VERSION', pythran_version_command.stdout().strip()) ++ conf_data.set('PYTHRAN_VERSION', pythran.version()) + conf_data.set('PYTHRAN_INCDIR', incdir_pythran) + endif + +-- +2.38.1.windows.1 +