Skip to content

Wheels built for the Python limited API on Windows should link against python3.dll, not minor version specific library like python39.dll #13167

@lpsinger

Description

@lpsinger

Describe the bug
According to the Python C API reference manual:

On Windows, extensions that use the Stable ABI should be linked against python3.dll rather than a version-specific library such as python39.dll.

However, on Windows, Meson incorrectly links against the version-specific library when building limited API extensions in limited API Python packages. As a result, the packages are broken and cannot be used with Python versions that are newer than the version used at build time.

To Reproduce
See https://github.com/lpsinger/meson-windows-limited-api. Take a look at a recent GitHub Actions workflow log such as https://github.com/lpsinger/meson-windows-limited-api/actions/runs/8918072559/job/24492117501. Notice that when cibuildwheel gets to cp310-win_amd64, it does notice the limited API wheel that it had already built with Python 3.9, as expected:

Found previously built wheel example-0.0.1-cp39-abi3-win_amd64.whl, that's compatible with cp310-win_amd64. Skipping build step...

Then when it runs the unit tests, they fail with this error:

  ______________________ ERROR collecting test_example.py _______________________
  ImportError while importing test module 'D:\a\meson-windows-limited-api\meson-windows-limited-api\test_example.py'.
  Hint: make sure your test modules/packages have valid Python names.
  Traceback:
  ..\..\..\..\pypa\cibuildwheel\Cache\nuget-cpython\python.3.10.11\tools\lib\importlib\__init__.py:126: in import_module
      return _bootstrap._gcd_import(name[level:], package, level)
  D:\a\meson-windows-limited-api\meson-windows-limited-api\test_example.py:1: in <module>
      from example import hello
  E   ImportError: DLL load failed while importing example: The specified module could not be found.

Take a look at one of the recent build artifacts containing the built packages, such as https://github.com/lpsinger/meson-windows-limited-api/actions/runs/8918072559/artifacts/1465707788.

If you unpack the wheel and look inside it, you can see that the C extension module example.pyd was linked against the wrong python DLL:

$ strings example.pyd | grep dll
KERNEL32.dll
api-ms-win-crt-environment-l1-1-0.dll
api-ms-win-crt-heap-l1-1-0.dll
api-ms-win-crt-runtime-l1-1-0.dll
api-ms-win-crt-stdio-l1-1-0.dll
api-ms-win-crt-string-l1-1-0.dll
api-ms-win-crt-time-l1-1-0.dll
python39.dll      <------------------------------- OOPS!
crtdll.c
dllentry.c
dllmain.c
__dll__
.rdata$.refptr.__native_dllmain_reason
.rdata$.refptr.__mingw_module_is_dll
__dll_characteristics__
__mingw_module_is_dll
.refptr.__mingw_module_is_dll
__native_dllmain_reason
_head_python39_dll
python39_dll_iname
.refptr.__native_dllmain_reason

Expected behavior
This Python C extension module should be linked against python3.dll, not python39.dll. The module should be importable and the tests should pass under Python 3.9, 3.10, 3.11, 3.12, etc.

system parameters

  • Is this a cross build or just a plain native build (for the same computer)? native build
  • what operating system (e.g. MacOS Catalina, Windows 10, CentOS 8.0, Ubuntu 18.04, etc.) _ Microsoft Windows Server 2022_
  • what Python version are you using 3.9.13
  • what meson --version 1.4.0
  • what ninja --version if it's a Ninja build 1.11.1.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    OS:windowsWinodows OS specific issuesmodules:pythonIssues specific to the python module

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions