Create Python C extension using MacOS 10.15 (Catalina) that is backwards compatible (MacOS10.9+)
Asked Answered
B

2

10

How can I create a Python C extension wheel for MacOS that is backwards compatible (MacOS 10.9+) using MacOS 10.15?

This is what I have so far:

export MACOSX_DEPLOYMENT_TARGET=10.9
python -m pip wheel . -w wheels --no-deps
python -m pip install delocate
for whl in wheels/*.whl; do
    delocate-wheel -w wheels_fixed -v "$whl"
done

Unfortunately, pip wheel generates a file myapp-0.0.1-cp37-cp37m-macosx_10_15_x86_64.whl, and unlike auditwheel on Linux, delocate-wheel does not modify the name of the wheel. As a result, if I upload it on PyPI using twine, only users with MacOS 10.15 are able to install it using pip. I guess I could manually rename it to myapp-0.0.1-cp37-cp37m-macosx_10_9_x86_64.whl, but this does not sound right to me.

For the builds I am just using the GitHub Actions MacOS virtual machines.

Thank you.

PS: The compiler used for the build is GCC9

Borrero answered 27/2, 2020 at 12:11 Comment(0)
B
5

I found the solution to my problem and I will post the answer here in case someone else has the same problem.

In order to fix the problem I had to also set export MACOSX_DEPLOYMENT_TARGET=10.9 before I install python using pyenv. Now pip wheel creates my wheel with the tag macosx_10_9_x86_64.

Thank you.

PS: When installing python via pyenv, python is compiled from source, and somehow it takes into account the flag MACOSX_DEPLOYMENT_TARGET.

Borrero answered 27/2, 2020 at 21:23 Comment(0)
F
3

According to this answer, the value of MACOSX_DEPLOYMENT_TARGET that the python interpreter was built with determines both the default and minimum value that can be used for wheel creation.

As you noticed, the python from actions/setup-python uses a relatively recent version (currently 10.14), making it incompatible with older versions. There is an open issue about this in actions/setup-python#26.

As another workaround I suggest setting up python via conda. This incurs some additional overhead (~2min) but should still be much better than building python manually. For example:

      - uses: goanpeca/setup-miniconda@v1
        with:
          architecture: x64
          python-version: '3.8'
          # must be explicitly specified if architecture is not x64:
          miniconda-version: latest

      - run: |
          conda create -qyf py35 python=3.5 wheel -c anaconda
          conda activate py35
          python setup.py sdist bdist_wheel
        shell: bash -l {0}

      - run: |
          conda create -qyf py36 python=3.6 wheel -c anaconda
          conda activate py36
          python setup.py sdist bdist_wheel
        shell: bash -l {0}

      ...

which will result in the following deployment targets:

  • py2.7: 10.7
  • py3.5: 10.6
  • py3.6: 10.9
  • py3.7: 10.9
  • py3.8: 10.9
Federalese answered 7/10, 2020 at 22:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.