koordinates / kart

Distributed version-control for geospatial and tabular data
https://kartproject.org
Other
515 stars 39 forks source link

cmake: simplify Python ABI/wheel id detection #985

Closed rcoup closed 2 months ago

rcoup commented 2 months ago

Fix build issues on macOS with newer python interpreter releases.

Description

Python3.11, macOS 14

kart (master) » cmake --build build
~/code/personal/kart 130 ↵
[  1%] VirtualEnv: wheelBuildEnv
[  3%] Built target wheelBuildEnv
[  4%] Performing install step for 'reflink'
Error copying file "/Users/hamish/code/kx/kart/build/vcpkg-vendor/reflink-prefix/tmp/dist/reflink-0.2.2-cp311-cp311-macosx_14_0_0_arm64.whl" to "/Users/hamish/code/kx/kart/build/vcpkg-vendor/reflink-prefix".
make[2]: *** [vcpkg-vendor/reflink-prefix/src/reflink-stamp/reflink-install] Error 1
make[1]: *** [vcpkg-vendor/CMakeFiles/reflink.dir/all] Error 2

The issue is this bit: cp311-cp311-macosx_14_0_0_arm64 should be cp311-cp311-macosx_14_0_arm64

It comes from Python3_WHEEL_ID in CMake, calcuated from calling python3 -m sysconfig and friends in cmake/PythonGetABIInfo.cmake

-- Python3 ABI flags: []
-- Python3 interpreter platform tag: macosx-14.0-arm64
-- Python3 interpreter macOS deployment target: 14.0
-- Final Python3 platform tag: macosx_14_0_0_arm64
-- Python3 Wheel identifier: cp311-cp311-macosx_14_0_0_arm64

But with Py3.9 (also homebrew)

-- Found Python3: /opt/homebrew/opt/python@3.9/bin/python3.9 (found suitable version "3.9.19", minimum required is "3.9") found components: Development Interpreter Development.Module Development.Embed
-- Python3 ABI flags: []
-- Python3 interpreter platform tag: macosx-14-arm64
CMake Warning at cmake/PythonGetABIInfo.cmake:63 (message):
  CMAKE_OSX_DEPLOYMENT_TARGET is 11.0.  The Python3 interpreter macOS
  deployment target is 14.  Greater one will be used.
Call Stack (most recent call first):
  CMakeLists.txt:124 (pythongetabiinfo)
-- Python3 interpreter macOS deployment target: 14.0
-- Final Python3 platform tag: macosx_14_0_arm64
-- Python3 Wheel identifier: cp39-cp39-macosx_14_0_arm64

(which is correct)

I think it’s the difference between Python3 interpreter platform tag: macosx-14-arm64 and Python3 interpreter macOS deployment target: 14.0, so it used to be macosx-(14)-arm64macosx_(14_0)_arm64 and now it’s macosx-(14).0-arm64macosx_(14_0)_0_arm64

Anyhow, there's a simpler approach (in theory, lets see what CI says). pip debug -v produces a big list, which is also available as:

from pip._internal.models.target_python import TargetPython
TargetPython().get_sorted_tags()

Grab the first/primary one, and use that instead. Drop all the other variables set in PythonGetABIInfo that aren't used anywhere else while we're at it.

Only behaviour change is warning if CMAKE_OSX_DEPLOYMENT_TARGET is different from the Python interpreter's MACOSX_DEPLOYMENT_TARGET rather than forcing it to the greater of the two. We pass this to pip/setuptools for building vendor wheels.

Related links:

Checklist:

rcoup commented 2 months ago

It CI since it ends up with manylinux_2_99 or whatever, i'll try a slightly different tack.

rcoup commented 2 months ago

Closed in favour of #986 for now.

I think the right future approach is probably one of:

  1. adapt this to do more during tag selection to exclude manylinux, universal2, etc
  2. currently we do python -m build -w[heel], but we need to know the wheel name upfront (which is where we get into the wheel-id mess) — either extract that into a script which could use wheel tags to remove/generalise tags after builds; or force it to build generic tags upfront (eg. cp312_linux_x86-64).
  3. avoid knowing the wheel name upfront by using cmake generator-expressions, etc.
  4. work to bring the vendor bit in-tree more and avoid building wheels altogether, building them directly into our build venv.