Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CPython sources - how to build a STATIC python26.lib?

I'm trying to compile my hello.pyx file to an exe using Cython.

First step was to compile the hello.pyx into a hello.cpp file using command "cython --cplus --embed hello.pyx". Embed option means to Generate a main() function that embeds the Python interpreter. I'm trying to create an independent exe with no dependencies.

In hello.cpp I have an #include "Python.h", so I'm downloading Python sources from here: http://www.python.org/download/releases/2.6.6/ , choosing Gzipped source tar ball (2.6.6). I add include dir and get error about missing Python26.lib. So I am trying to compile it. The default build creates python26.lib but it's only 200 KB, this is not a static lib, when trying to compile hello.cpp I get missing references errors.

In README I don't see any useful instructions of how to build it statically. However, I've googled an online README file, for the latest version of python in trunk (3.x), there is some useful info about static building:

http://svn.python.org/projects/python/trunk/PCbuild/readme.txt

The solution has no configuration for static libraries. However it is easy it build a static library instead of a DLL. You simply have to set the "Configuration Type" to "Static Library (.lib)" and alter the preprocessor macro "Py_ENABLE_SHARED" to "Py_NO_ENABLE_SHARED". You may also have to change the "Runtime Library" from "Multi-threaded DLL (/MD)" to "Multi-threaded (/MT)".

But still there aren't too many details here, do I set all projects in the solution to build as static library? Or pythoncore only? "Python" and "Pythonw" projects are "Applications", so there I can only change runtime library to /MT. These are the steps I am doing:

  • Changing to "Release" mode.
  • Project "Python" - setting /MT and adding preprocessor definition Py_NO_ENABLE_SHARED
  • Project "Pythoncore" - configuration type to Static library (.lib), /MT, replacing preprocessor definition Py_ENABLE_SHARED with Py_NO_ENABLE_SHARED
  • Project "Pythonw" - the same as in "Python".
  • I right click build on "Python".

Summary of the build:

Build: 5 succeeded, 1 failed, 0 up-to-date, 0 skipped

kill_python (ok)
make_buildinfo (ok)
make_versioninfo (ok)
pythoncore (ok)
w9xpopen (ok)
python (4 errors)

The project that failed is "Python", here is the log:

------ Build started: Project: python, Configuration: Release Win32 ------
Compiling...
python.c
Compiling resources...
Microsoft (R) Windows (R) Resource Compiler Version 6.1.7600.16385
Copyright (C) Microsoft Corporation.  All rights reserved.
Linking...
pythoncore.lib(sysmodule.obj) : error LNK2019: unresolved external symbol __Py_svnversion referenced in function _svnversion_init
pythoncore.lib(getversion.obj) : error LNK2019: unresolved external symbol _Py_GetBuildInfo referenced in function _Py_GetVersion
pythoncore.lib(dynload_win.obj) : error LNK2019: unresolved external symbol __Py_DeactivateActCtx referenced in function __PyImport_GetDynLoadFunc
pythoncore.lib(dynload_win.obj) : error LNK2019: unresolved external symbol __Py_ActivateActCtx referenced in function __PyImport_GetDynLoadFunc
d:\python\src4\PCbuild\\python.exe : fatal error LNK1120: 4 unresolved externals
Build Time 0:02

I look at the /PCbuild/ directory and I see that "pythoncore.lib" exists (10MB), but there is no "python26.lib".

When I google for these errors, I only find one conversation at mail.pythong.org: http://www.groupsrv.com/computers/about397568.html

I tried removing prepreocessor definition "_USRDLL" in pythoncore project, but still the errors are the same.

The preprocessor definitions in pythoncore are:

_USRDLL
Py_BUILD_CORE
Py_NO_ENABLE_SHARED
WIN32

When I click edit I see in another box "Inherited values" which are:

NDEBUG
_WIN32

That Ndebug is strange, because I've changed the mode to Release.

I am using Visual Studio 2008 (not Express) with all service packs installed.

Btw. earlier I tried to build the whole solution, but there were some errors about missing files, whose path start with: "../../dba-".


I tried compiling 2.6.2 and 2.6.6 versions of Python, but they both throw the same errors: pythoncore.lib(sysmodule.obj) : error LNK2019: unresolved external symbol

like image 327
Czarek Tomczak Avatar asked Nov 05 '22 10:11

Czarek Tomczak


1 Answers

I've been building Python static from 2.4 through to 2.7, and it does take a bit of work to set up.

You do need to update the configuration for all enabled projects in the solution, setting them to /MT. To build Python static, everything that it references - including libraries like SQLite or OpenSSL - must also be static. This is true even of the .pyd modules, which aren't actually included, since otherwise they won't be importable later.

You may also need to make this edit near the top of Modules/socketmodule.h:

#else /* MS_WINDOWS */
# define inet_pton _msvc_inet_pton
# define inet_ntop _msvc_inet_ntop
# include <winsock2.h>
# include <ws2tcpip.h>
# include <wspiapi.h>
# undef inet_pton
# undef inet_ntop

Once you get beyond the immediate error, some other things that are probably necessary:

  • Disable creation of embedded manifests; see line ~650 in distutils msvc9compiler.py; the fact that it creates these even when building with /MT is a bug.

  • Change /MD to /MT in distutils msvccompiler/msvc9compiler.py, since otherwise thirdparty libs won't build correctly.

like image 180
DNS Avatar answered Nov 09 '22 06:11

DNS