Skip to content

Incorrect Python Library Linking in Debug Builds on Windows (MSVC): Should Use python{vernum}_d.lib #14429

Open
@zicowarn

Description

@zicowarn

Describe the bug
When building the numpy project that depends on Python using Meson on Windows with MSVC in debug mode, the final linking step incorrectly uses the release Python library (e.g. python313.lib) instead of the debug library (python313_d.lib). Even though the build logs indicate that python313_d.lib is used during compilation (as evidenced by the modifications in pyconfig.h with #pragma message directives), the resulting .pyd files are linked against the release DLL. This causes runtime issues when using a debug Python interpreter.

To Reproduce

  1. Use a minimal Meson project that depends on Python. For example, create a simple meson.build that finds Python using Meson’s built-in dependency module.
  2. Modify your Python installation's pyconfig.h to include:
    #if defined(_DEBUG)
        #pragma message("Use debug library, python313_d.lib")
        #pragma comment(lib,"python313_d.lib")
    #elif defined(Py_LIMITED_API)
        #pragma message("Use release library (Limited API), python3t.lib")
        #pragma comment(lib,"python3.lib")
    #else
        #pragma message("Use release library, python313.lib")
        #pragma comment(lib,"python313.lib")
    #endif
  3. Create and activate a debug virtual environment using the debug interpreter (e.g. python_d.exe).
  4. Run the following command to build using Spin (which uses Meson under the hood):
    python_d -m spin build -v --clean -- -Dbuildtype=debug -Ddisable-optimization=true
  5. Check the final linked .pyd file (for example using Dependency Walker). You will see that it depends on python313.dll instead of python313_d.dll.

Expected behavior
In a debug build, the final linking should correctly use the debug Python library (i.e. python313_d.lib) so that the resulting .pyd depends on python313_d.dll. Our expectation is that Meson’s Python dependency module should detect the debug interpreter and adjust the link arguments accordingly. For instance, the code in mesonbuild/dependencies/python.py should choose python{vernum}_d.lib when LIBRARY ends with _d.dll.

System parameters

  • Build type: Native build (no cross-compilation)
  • Operating System: Windows 10
  • Python Version: Python 3.13 (debug interpreter, e.g. python313_d.exe)
  • Meson Version: 1.7.0
  • Ninja Version: 1.11.1.git.kitware.jobserver-1

I propose modifying the get_windows_link_args function in mesonbuild/dependencies/python.py by adjusting the conditional block for debug builds as follows:

if is_debug_build and vscrt_debug:
    library = self.variables.get('LIBRARY', '')
    if library.endswith('_d.dll'):
        libpath = Path('libs') / f'python{vernum}_d.lib'
        mlog.warning("Using python static library with debug Python interpreter. " + libpath.name)
    if not self.variables.get('Py_DEBUG'):
        mlog.warning(textwrap.dedent('''\
            Using a debug build type with MSVC or an MSVC-compatible compiler
            when the Python interpreter is not also a debug build will almost
            certainly result in a failed build. Prefer using a release build
            type or a debug Python interpreter.
            '''))

Could this be considered for a fix? I'd be happy to submit a pull request with this change if the approach is acceptable.


Feel free to adjust any details as needed before submission.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions