This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Embedding Python on Windows
Type: compile error Stage:
Components: Windows Versions: Python 3.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: steve.dower Nosy List: Joakim.Karlsson, loewis, r-englund, steve.dower, tim.golden, zach.ware
Priority: normal Keywords:

Created on 2014-09-14 17:57 by Joakim.Karlsson, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (9)
msg226882 - (view) Author: Joakim Karlsson (Joakim.Karlsson) Date: 2014-09-14 17:57
When I embed Python 3.4 in an existing app, I run in to a few issues when our app is built in debug mode. I build against the headers, libs and dlls that I get when installing python, I don't build python myself.

1. When I include python.h it will, via pyconfig.h, automatically attempt to link to python34_d.lib. This lib, along with its accompanying dll is not included in the python installation.

I'd rather explicitly link to the release lib than having header files implicitly selecting libs based on the _DEBUG flag. I ended up killing the #pragma comment(lib...) statements in pyconfig.h, and I can now link with the lib included.

2. Now when I build, I get a linker error telling me that '__imp__Py_RefTotal' and '__imp_Py_NegativeRefCount' cannot be found. This seems to be caused by Py_DEBUG being defined automatically in pyconfig.h as a result of _DEBUG being defined for my application. This causes the reference counting macros to use functionality that is only present in the debug version of python34.dll.

I ended up including pyconfig.h first, undefed Py_DEBUG, and then including python.h. This seems rather clunky.

Keeping with "explicit is better than implicit", wouldn't it be better to having to explicitly link to the desired lib from the embedding app, and explicitly set Py_DEBUG without having it inferred from _DEBUG? 

That way the provided headers and libs would work right out of the box while still leaving me the option to get the debug behaviour if I need to.
msg233675 - (view) Author: Rickard Englund (r-englund) Date: 2015-01-08 18:19
I have also had this problem. 
The way I solved it was to undef _DEBUG before including python and then redefine it again:

    #undef _DEBUG //Prevent linking debug build of python
    #include <Python.h>
    #define _DEBUG 1

This is just a hack though and it would be interesting to know if there is a correct way to do it.
msg233763 - (view) Author: Joakim Karlsson (Joakim.Karlsson) Date: 2015-01-09 16:15
You shouldn't mix headers with and without the _DEBUG symbol defined. At least on some versions of MSVC this can lead to errors as some standard headers start referencing functions that are not available in both debug and release versions of the MSV C runtime.
msg233767 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-01-09 16:47
Yeah, unfortunately the only correct way to do this is to use a debug build of Python. It isn't that difficult to build, but it is extra work and may not be an option at all depending on context (for example, some businesses won't let employees access source code to open-source projects).

If you link against python3.dll rather than python34.dll (there's a pre-processor variable to set, but I don't remember it off the top of my head) then you should avoid most of the debug/non-debug issues. I think you'll still need the #undef _DEBUG code though, and you'll lose access to some functionality, so it may not be an appropriate solution for you.

I don't think there's any good fix for this for 3.4, short of someone building and releasing a debug build from the same changeset as the actual release. For 3.5 I may be able to add an installer option to install debug binaries alongside the release ones. I'll put some thought into it and try some things out.
msg233773 - (view) Author: Joakim Karlsson (Joakim.Karlsson) Date: 2015-01-09 17:37
A complicating factor is that the debug and release versions of the dll:s seem to behave differently, which makes it hard to replace one with the other.

For instance, in dynload_win.c, the suffix of files looked for are "_d.pyd" in debug mode and ".pyd" in release mode. This causes python not to find any .pyd files if I link to the debug version.

This might be a separate issue, but it is tighly connected to this as the _DEBUG setting of the embedding app changes how the Python interpreter works.
msg233774 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-01-09 17:46
Right, so when using python34_d.dll you need the _d.pyd versions (and if you're building your own .pyd you need to add the _d suffix too). There's nothing wrong with this difference, since the debug and release builds are subtly incompatible with each other, so the alternative is that you'd get random crashes when mixing them. Better off getting blatant errors that files can't be found.

Any option to install a debug build in 3.5 would obviously install a complete debug build - not just the one DLL.
msg233821 - (view) Author: Joakim Karlsson (Joakim.Karlsson) Date: 2015-01-10 17:41
Sounds reasonable.

It would also require that all third party packages supply a "*_d.pyd" version of any extensions.

Does setuptools and pip have any support for automatically creating debug versions of extensions with the correct naming scheme when creating wheels or compiling during installation? A (really shallow) search didn't find any info on this.

Anyway, thanks for stepping up and taking charge of the windows installers!
msg233824 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-01-10 20:48
distutils will (now, after some changes in 3.5) build debug versions of packages on installation when running with python_d.exe. I haven't tested exactly how pip behaves here, but it should work fine if you run with a command line like this:

python_d.exe -m pip install --no-use-wheel --no-clean --build <build dir> <package>

I don't think pip will create a pip_d.exe, and it's likely that if a wheel is available it will grab that and you really need to build it locally. Using --no-clean and --build to specify where to build it will ensure that the symbols for the package aren't deleted, which may help with debugging, but if you don't care about that you can omit those two parameters.

I've also been experimenting with adding an option to download and install debug binaries as part of the installer, and it looks like it'll work fine. So that at least will make things simpler for developers. Another change for 3.5 that will also help is #22980 (though that one isn't quite settled yet and may change again).
msg241155 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2015-04-15 20:24
The 3.5 installer contains the option to install the debug binaries, so that side is solved and I'm closing this as fixed.

In the video at https://www.youtube.com/watch?v=D9RlT06a1EI I demonstrate how you can build a debug EXE against a release python34.dll without issues (though you lose a bit of debugging support) - in short, use the compiler option to link against the release runtime.
History
Date User Action Args
2022-04-11 14:58:08adminsetgithub: 66601
2015-04-15 20:24:21steve.dowersetstatus: open -> closed
versions: + Python 3.5, - Python 3.4
messages: + msg241155

assignee: steve.dower
resolution: fixed
2015-01-10 20:48:14steve.dowersetmessages: + msg233824
2015-01-10 17:41:47Joakim.Karlssonsetmessages: + msg233821
2015-01-09 17:46:59steve.dowersetmessages: + msg233774
2015-01-09 17:37:23Joakim.Karlssonsetmessages: + msg233773
2015-01-09 16:47:18steve.dowersetmessages: + msg233767
2015-01-09 16:15:50Joakim.Karlssonsetmessages: + msg233763
2015-01-08 18:21:17pitrousetnosy: + tim.golden, zach.ware, steve.dower
2015-01-08 18:19:41r-englundsetnosy: + r-englund
messages: + msg233675
2014-09-15 01:38:10ned.deilysetnosy: + loewis
2014-09-14 17:57:04Joakim.Karlssoncreate