# \`FindPython\` option to skip debug binaries on Windows

**URL:** https://discourse.cmake.org/t/findpython-option-to-skip-debug-binaries-on-windows/15366
**Category:** Development
**Created:** [December 6, 2025, 6:22am UTC](https://discourse.cmake.org/t/findpython-option-to-skip-debug-binaries-on-windows/15366 "2025-12-06T06:22:52Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![Andrej730](https://discourse.cmake.org/user_avatar/discourse.cmake.org/andrej730/32/5752_2.png) [@Andrej730](https://discourse.cmake.org/u/Andrej730)
#### Post date: [December 6, 2025, 6:22am UTC](https://discourse.cmake.org/t/findpython-option-to-skip-debug-binaries-on-windows/15366/1 "2025-12-06T06:22:52Z")

</div>

Hi! There’s an issue when trying to build debug version of some Python extension on Windows - it require… debug Python libraries (e.g. `python_d.exe` , `python311_d.dll`, `python311_d.lib`)

They’re becoming less accessible - the only way to get them, outside of compiling them yourself, is official Python official installer which is not very good for portable installations and it’s now deprecated ([it will be gone in 3.16+](https://docs.python.org/3/using/windows.html#the-full-installer-deprecated)), in the future Windows installation will switch to Python Installation Manager which won’t have debug binaries.  
And if you have them, the chances are that you don’t actually want to use them - because it creates more problems than solves, since then you also need to make sure all other Python modules you use are in debug mode too (e.g. `numpy_d.pyd` instead of `numpy.pyd`) and there’s really no simple way to get them.  
So debug Python binaries really needed if you want to either debug Python itself or part of your extension that interacts with Python (e.g. debugging reference counts, etc). But more typical scenario is that you need debug verison of your extension to debug it’s main code, without getting deep into Python internals.

On Unix using Python Debug API requires `Py_DEBUG` option to be set, so using debug Python is deliberate. But on Windows it’s set automatically on `_DEBUG`, which is set automatically when `/MDd` flag is used during compilation and this flag is used in any default Windows Debug build to link `VCRUNTIME140D.dll`.

> <https://github.com/python/cpython/blob/eba449a1989265a923174142dd67dee074f90967/PC/pyconfig.h#L97-L100>

To go arround this users either don’t do full debug builds or do some `# undef _DEBUG` hacks before including `Python.h`, e.g. code from `swig`:

> <https://github.com/swig/swig/blob/5a46275a33398d6f05d196cf6e8334a570d359fd/Lib/python/pyruntime.swg#L18-L32>

Since Python 3.9 its debug and release ABI became mostly compatible, but there are two issues left:

- On Windows it’s automatically linking against `python315_d` if `Py_DEBUG` is set. Which is annoying practice and general and probably mostly historical. Good news that in Python 3.14 `Py_NO_LINK_LIB` flag was [added](https://docs.python.org/3/extending/windows.html#c.Py_NO_LINK_LIB) to avoid this behaviour.

> <https://github.com/python/cpython/blob/eba449a1989265a923174142dd67dee074f90967/PC/pyconfig.h#L340-L346>

- `Py_DEBUG` also automatically implies `Py_REF_DEBUG` which includes couple symbols for debugging ref count and they’re not available in release binaries leading to issues on linking. As of Pyhon 3.14 there’s no way to avoid it.

> <https://github.com/python/cpython/blob/eba449a1989265a923174142dd67dee074f90967/Include/refcount.h#L229-L234>

From [discussion](https://discuss.python.org/t/building-debug-version-of-extensions-on-windows-without-debug-binaries/105012) on Python forum and tests, `Py_REF_DEBUG` is the last thing preventing linking against release binaries on Windows, so I plan to submit a PR to CPython to add some kind of `Py_WIN_NO_PY_DEBUG` or `Py_NO_REF_DEBUG` flag to avoid this behaviour.

So in theory in Python 3.15 it will be finally possible to use release binaries for debug builds.

And I wanted to propose adding some kind flag to cmake’s `FindPython` to set those automatically - e.g. before `find_package(Python)` to set `Python_WIN_NO_PY_DEBUG` that would

- define `Py_NO_LINK_LIB` and `Py_WIN_NO_PY_DEBUG` / `Py_NO_REF_DEBUG` for Python targets.
- would avoid setting `IMPORTED_IMPLIB_DEBUG` / `IMPORTED_LOCATION_DEBUG`.
- avoid setting debug postfix for targets.

Or maybe `Py_NO_LINK_LIB` should be separated to another option, not sure.

Anyways, issue should be first fixed upstream of course, but wanted to ask for your thoughts if this makes sense or maybe there some other caveats to consider.

---

<div class="post-metadata">

### Author: ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)
#### Post date: [December 6, 2025, 10:19am UTC](https://discourse.cmake.org/t/findpython-option-to-skip-debug-binaries-on-windows/15366/2 "2025-12-06T10:19:18Z")

</div>

FYI, starting with CMake 3.31.8, flag `Py_NO_LINK_LIB` is automatically set when `python*_add_library()` command is used.

Regarding debug library, the various debug artifacts are defined only if the debug library is found. Otherwise, these artifacts are not defined (debug artifacts are optional), so there is no need to introduce some specific configuration for that.

---

<div class="post-metadata">

### Author: ![Andrej730](https://discourse.cmake.org/user_avatar/discourse.cmake.org/andrej730/32/5752_2.png) [@Andrej730](https://discourse.cmake.org/u/Andrej730)
#### Post date: [December 6, 2025, 11:10am UTC](https://discourse.cmake.org/t/findpython-option-to-skip-debug-binaries-on-windows/15366/3 "2025-12-06T11:10:39Z")

</div>

> [@marc.chevrier](#):
>
> FYI, starting with CMake 3.31.8, flag `Py_NO_LINK_LIB` is automatically set when `python*_add_library()` command is used.

Missed it, that’s very neat!

> [@marc.chevrier](#):
>
> Regarding debug library, the various debug artifacts are defined only if the debug library is found. Otherwise, these artifacts are not defined (debug artifacts are optional), so there is no need to introduce some specific configuration for that.

Understandable, but still - user might have release and debug Python binaries and both of them would be found by `FindPython`, but it still might be not desirable to use debug version of Python for the extensions build, because of all the downsides it has.

Though it’s more rare - most of the time users will indeed have just release binaries. Maybe it would make sense to set hypothetical `Python_WIN_NO_PY_DEBUG` (that would define `Py_WIN_NO_PY_DEBUG`) automatically if no debug libraries were found? So it would work for the most of the users seamlessly, without setting additional config variable.
