Repository: python-control/Slycot (language: python)

Issue:
Conda MacOS CI failures
I don't understand the MacOS failures.

From one of the the failing runs, there's something that looks weird, though it may be unrelated: https://github.com/python-control/Slycot/runs/6246110913?check_suite_focus=true#step:4:1970

```
Processing dependencies for slycot==0.4.0
Searching for slycot==0.4.0
Reading https://pypi.org/simple/slycot/
Downloading https://files.pythonhosted.org/packages/85/21/4e7110462f3529b2fbcff8a519b61bf64e0604b8fcbe9a07649c9bed9d7a/slycot-0.4.0.0.tar.gz#sha256=1d9921e9b04a5b9892870fd3481f7b08e6fa083a1a3848ad262819de19eb5e02
```

I assume this is a mistake -- we don't want to download slycot 0.4.0 from PyPI for testing, do we?

I don't follow the final error message; I guess it failed, but why?

```
Running slycot-0.4.0.0/setup.py -q bdist_egg --dist-dir /tmp/easy_install-w0mc9zxi/slycot-0.4.0.0/egg-dist-tmp-qcfmz0w8
    sys.exit(main())
  File "/usr/local/miniconda/envs/build-env/lib/python3.9/site-packages/conda_build/cli/main_build.py", line 488, in main
    execute(sys.argv[1:])
  File "/usr/local/miniconda/envs/build-env/lib/python3.9/site-packages/conda_build/cli/main_build.py", line 477, in execute
    outputs = api.build(args.recipe, post=args.post, test_run_post=args.test_run_post,
  File "/usr/local/miniconda/envs/build-env/lib/python3.9/site-packages/conda_build/api.py", line 186, in build
    return build_tree(
  File "/usr/local/miniconda/envs/build-env/lib/python3.9/site-packages/conda_build/build.py", line 3088, in build_tree
    packages_from_this = build(metadata, stats,
  File "/usr/local/miniconda/envs/build-env/lib/python3.9/site-packages/conda_build/build.py", line 2211, in build
    utils.check_call_env(cmd, env=env, rewrite_stdout_env=rewrite_env,
  File "/usr/local/miniconda/envs/build-env/lib/python3.9/site-packages/conda_build/utils.py", line 410, in check_call_env
    return _func_defaulting_env_to_os_environ('call', *popenargs, **kwargs)
  File "/usr/local/miniconda/envs/build-env/lib/python3.9/site-packages/conda_build/utils.py", line 390, in _func_defaulting_env_to_os_environ
    raise subprocess.CalledProcessError(proc.returncode, _args)
subprocess.CalledProcessError: Command '['/bin/bash', '-o', 'errexit', '/usr/local/miniconda/envs/build-env/conda-bld/slycot_1651398745184/work/conda_build.sh']' returned non-zero exit status 1.
Error: Process completed with exit code 1.
```

_Originally posted by @roryyorke in https://github.com/python-control/Slycot/issues/171#issuecomment-1114193395_
Update conda testing in CI
Our CI spends a lot of time resolving all the requirements for the build environement. The conda-forge feedstock switched to the mamba resolver, which in theory is faster. We should try to do the same.


Discussion / hints:
Could be that the current resolver is confused by the `0.4.0` vs `0.4.0.0`.

Should try to fix this with  #163 and probably #164
~~I tried to migrate to mamba and boa, but the windows env setup by the setup-miniconda github action failed. Deferring further.~~

Fix patch:
diff --git a/.github/conda-env/build-env.yml b/.github/conda-env/build-env.yml
new file mode 100644
index 00000000..f747a77e
--- /dev/null
+++ b/.github/conda-env/build-env.yml
@@ -0,0 +1,4 @@
+name: build-env
+dependencies:
+  - boa
+  - numpy
diff --git a/README.rst b/README.rst
index 6003eaed..1dcde8bc 100644
--- a/README.rst
+++ b/README.rst
@@ -32,7 +32,7 @@ following dependencies:
 
 - 3.6+
 - NumPy
-- scikit-build >= 0.10.0
+- scikit-build
 - CMake
 - C compiler (e.g. gcc, MS Visual C++, clang)
 - FORTRAN compiler (e.g. gfortran, ifort, flang)
@@ -70,11 +70,27 @@ The hardest part about installing from source is getting a working
 version of FORTRAN and LAPACK (provided by OpenBLAS, MKL, etc.)
 installed on your system. Depending on where you get your NumPy and SciPy
 from, you will need to use a compatible LAPACK implementation. Make sure that
-the correct header files are installed, and specify the environment variable
-`BLA_VENDOR`_, if necessary.
+the correct header files are installed, and specify the CMake variable
+`BLA_VENDOR`_, if necessary. We recommend to use `BLA_VENDOR=Generic` in order
+to produce a Slycot module, which is binary compatible with all implementations.
 
 .. _BLA_VENDOR: https://cmake.org/cmake/help/latest/module/FindBLAS.html#input-variables
 
+Compiling the PyPI source with pip
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We publish Slycot to the Python package index, but only as a source
+package, so to install using pip you'll first need to install the
+build prerequisites (compilers, libraries, etc.)
+
+If you have these build prerequisites, the command::
+
+    pip install slycot
+
+will download the latest release of the source code from `PyPI`_, compile, and
+install Slycot into the currently configured location (virtual environment or
+user site-packages).
+
 Getting the full source code
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -120,8 +136,8 @@ If you already have a local checkout, but still need to init the submodule::
     git submodule init
     git submodule update
 
-Compiling with setuptools (Linux, macOS, Windows)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Compiling the source (Linux, macOS, Windows)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 If you need to specify a specific compiler, set the environment variable FC
 before running the install::
@@ -135,7 +151,7 @@ before running the install::
 To build and install, execute::
 
     cd /path/to/slycot_src/
-    python setup.py install
+    pip install -v .
 
 Using the conda recipe
 ~~~~~~~~~~~~~~~~~~~~~~
@@ -166,8 +182,8 @@ To build and install::
     conda build -c conda-forge conda-recipe
     conda install -c conda-forge --use-local slycot
 
-With setuptools in a conda environment (Windows)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Building from source manually in a conda environment (Windows)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 A similar method can be used for Linux and macOS, but is detailed here
 for Windows.  This method uses conda and conda-forge to get most build
@@ -186,22 +202,7 @@ This procedure has been tested on Python 3.7 and 3.8.
         conda create --channel conda-forge --name build-slycot python=3.8 numpy scipy libblas=*=*netlib liblapack=*=*netlib scikit-build flang pytest
         conda activate build-slycot
 
-        python setup.py install
-
-Using pip
-~~~~~~~~~
-
-We publish Slycot to the Python package index, but only as a source
-package, so to install using pip you'll first need to install the
-build prerequisites (compilers, libraries, etc.)
-
-If you have these build prerequisites, the command::
-
-    pip install slycot
-
-will download the latest release of the source code from `PyPI`_, compile, and
-install Slycot into the currently configured location (virtual environment or
-user site-packages).
+        pip install -v .
 
 Additional hints
 ~~~~~~~~~~~~~~~~
diff --git a/conda-recipe/bld.bat b/conda-recipe/bld.bat
index 6f2397c6..4b2811d0 100644
--- a/conda-recipe/bld.bat
+++ b/conda-recipe/bld.bat
@@ -1,6 +1,8 @@
 set BLAS_ROOT=%PREFIX%
 set LAPACK_ROOT=%PREFIX%
 
-"%PYTHON%" setup.py install -G "NMake Makefiles" -DBLA_VENDOR=Generic
+set "SKBUILD_CONFIGURE_OPTIONS=-DBLA_VENDOR=Generic"
+set "CMAKE_GENERATOR=NMake Makefiles"
+"%PYTHON%" -m pip install -v .
 
 if errorlevel 1 exit 1
diff --git a/conda-recipe/build.sh b/conda-recipe/build.sh
index 1e72fa01..fbc8a26e 100644
--- a/conda-recipe/build.sh
+++ b/conda-recipe/build.sh
@@ -2,13 +2,5 @@
 rm -rf _skbuild
 rm -rf _cmake_test_compile
 
-export LDFLAGS="$LDFLAGS -v"
-if [[ "$target_platform" == osx-64 ]]; then
-  export LDFLAGS="${LDFLAGS} -isysroot ${CONDA_BUILD_SYSROOT}"
-  export CFLAGS="${CFLAGS} -isysroot ${CONDA_BUILD_SYSROOT}"
-  export CMAKE_OSX_SYSROOT=${CONDA_BUILD_SYSROOT}
-fi
-
-# Always build against netlib implementation
-# https://conda-forge.org/docs/maintainer/knowledge_base.html#blas
-$PYTHON setup.py build_ext install -DBLA_VENDOR=Generic
+export SKBUILD_CONFIGURE_OPTIONS="-DBLA_VENDOR=Generic"
+$PYTHON -m pip install -v .
diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml
index ada3382d..55314c06 100644
--- a/conda-recipe/meta.yaml
+++ b/conda-recipe/meta.yaml
@@ -28,7 +28,8 @@ requirements:
     - liblapack * *netlib
     - python
     - numpy
-    - scikit-build >=0.10.0
+    - pip
+    - scikit-build >=0.14.1
 
   run:
     - python {{ PY_VER }}
diff --git a/pyproject.toml b/pyproject.toml
index 3df57213..206a1e60 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,2 +1,8 @@
 [build-system]
-requires = ["setuptools", "wheel", "scikit-build", "cmake", "numpy"]
+requires = [
+    "setuptools",
+    "wheel",
+    "scikit-build>=0.14.1",
+    "cmake",
+    "numpy"]
+build-backend = "setuptools.build_meta"


Test patch:
diff --git a/.github/workflows/slycot-build-and-test.yml b/.github/workflows/slycot-build-and-test.yml
index ef92ddcd..54367ed2 100644
--- a/.github/workflows/slycot-build-and-test.yml
+++ b/.github/workflows/slycot-build-and-test.yml
@@ -12,7 +12,7 @@ on:
 
 jobs:
 
-  build-setup:
+  build-sdist:
     # Super fast sniff build. If this fails, don't start the other jobs
     name: Build sdist on Ubuntu
     runs-on: ubuntu-latest
@@ -30,24 +30,26 @@ jobs:
         run: |
           sudo apt-get -y install gfortran cmake --fix-missing
           sudo apt-get -y install libblas-dev liblapack-dev
-          pip install scikit-build numpy scipy pytest
       - name: Create Slycot sdist
-        run: python setup.py sdist
-
+        run: |
+          pip install build
+          python -m build --sdist
       - name: Install Slycot sdist
         run: |
           mkdir cleancwd
           cd cleancwd
           tar xfz ../dist/slycot-*.tar.gz
           cd slycot-*
-          python setup.py install
+          pip install -v .
       - name: Run tests
-        run: pytest
+        run: |
+          pip install scipy pytest
+          pytest
 
   build-pip:
     name: Build pip Py${{ matrix.python }}, ${{ matrix.os }}, ${{ matrix.bla_vendor}} BLA_VENDOR
     runs-on: ${{ matrix.os }}-latest
-    needs: build-setup
+    needs: build-sdist
     strategy:
         fail-fast: false
         matrix:
@@ -56,24 +58,23 @@ jobs:
               - 'macos'
             python:
               - '3.7'
-              - '3.9'
               - '3.10'
             bla_vendor: [ 'unset' ]
             include:
               - os: 'ubuntu'
-                python: '3.9'
+                python: '3.10'
                 bla_vendor: 'Generic'
               - os: 'ubuntu'
-                python: '3.9'
+                python: '3.10'
                 bla_vendor: 'OpenBLAS'
               - os: 'macos'
-                python: '3.9'
+                python: '3.10'
                 bla_vendor: 'Apple'
               - os: 'macos'
-                python: '3.9'
+                python: '3.10'
                 bla_vendor: 'Generic'
               - os: 'macos'
-                python: '3.9'
+                python: '3.10'
                 bla_vendor: 'OpenBLAS'
 
     steps:
@@ -133,7 +134,7 @@ jobs:
   build-conda:
     name: Build conda Py${{ matrix.python }}, ${{ matrix.os }}
     runs-on: ${{ matrix.os }}-latest
-    needs: build-setup
+    needs: build-sdist
     strategy:
         fail-fast: false
         matrix:
@@ -156,7 +157,9 @@ jobs:
         with:
           python-version: ${{ matrix.python }}
           activate-environment: build-env
-          channels: conda-forge
+          environment-file: .github/conda-env/build-env.yml
+          miniforge-version: latest
+          miniforge-variant: Mambaforge
           channel-priority: strict
           auto-update-conda: false
           auto-activate-base: false
@@ -164,9 +167,9 @@ jobs:
         shell: bash -l {0}
         run: |
           set -e
-          conda install conda-build conda-verify numpy
+          mamba install boa numpy
           numpyversion=$(python -c 'import numpy; print(numpy.version.version)')
-          conda-build --python "${{ matrix.python }}" --numpy $numpyversion conda-recipe
+          conda mambabuild --python "${{ matrix.python }}" --numpy $numpyversion conda-recipe
           # preserve directory structure for custom conda channel
           find "${CONDA_PREFIX}/conda-bld" -maxdepth 2 -name 'slycot*.tar.bz2' | while read -r conda_pkg; do
             conda_platform=$(basename $(dirname "${conda_pkg}"))
@@ -326,9 +329,10 @@ jobs:
         uses: conda-incubator/setup-miniconda@v2
         with:
           python-version: ${{ matrix.python }}
+          miniforge-version: latest
+          miniforge-variant: Mambaforge
           activate-environment: test-env
           environment-file: slycot-src/.github/conda-env/test-env.yml
-          channels: conda-forge
           channel-priority: strict
           auto-activate-base: false
       - name: Download conda packages
@@ -341,23 +345,23 @@ jobs:
           set -e
           case ${{ matrix.blas_lib }} in
             unset        ) # the conda-forge default (os dependent)
-              conda install libblas libcblas liblapack
+              mamba install libblas libcblas liblapack
               ;;
             Generic      )
-              conda install 'libblas=*=*netlib' 'libcblas=*=*netlib' 'liblapack=*=*netlib'
+              mamba install 'libblas=*=*netlib' 'libcblas=*=*netlib' 'liblapack=*=*netlib'
               echo "libblas * *netlib" >> $CONDA_PREFIX/conda-meta/pinned
               ;;
             OpenBLAS     )
-              conda install 'libblas=*=*openblas' openblas
+              mamba install 'libblas=*=*openblas' openblas
               echo "libblas * *openblas" >> $CONDA_PREFIX/conda-meta/pinned
               ;;
             Intel10_64lp )
-              conda install 'libblas=*=*mkl' mkl
+              mamba install 'libblas=*=*mkl' mkl
               echo "libblas * *mkl" >> $CONDA_PREFIX/conda-meta/pinned
               ;;
           esac
           conda index --no-progress ./slycot-conda-pkgs
-          conda install -c ./slycot-conda-pkgs slycot
+          mamba install -c ./slycot-conda-pkgs slycot
           conda list
       - name: Slycot and python-control tests
         run: bash slycot-src/.github/scripts/run-tests.sh