abramus
abramus

Reputation: 121

Building standalone application with Cython + MinGW

I'm trying to build standalone application from Python code. At the moment it is only a "hello world" program. I compile it with Cython to get a .c file:

"c:\python34\scripts\cython.exe" --embed hello.py

That works fine. Then I try to compile and link the generated .c file as follows:

"c:\mingw32\bin\gcc.exe" -I"c:\python34\include" -L"c:\python34\libs" -lpython34 -ohello.exe hello.c

That gives me a whole lot of link errors:

...\cc7PmSei.o:hello.c:(.text+0xe9): undefined reference to `_imp__PyTuple_New'

...\cc7PmSei.o:hello.c:(.text+0x130): undefined reference to `_imp__PyBytes_FromStringAndSize'

...\cc7PmSei.o:hello.c:(.text+0x177): undefined reference to `_imp__PyModule_Create2'

...

...\cc7PmSei.o:hello.c:(.text+0x12b7): undefined reference to `_imp__PyUnicode_Decode'

...\cc7PmSei.o:hello.c:(.text+0x12dd): undefined reference to `_imp__PyUnicode_FromStringAndSize'

...\cc7PmSei.o:hello.c:(.text+0x1303): undefined reference to `_imp__PyBytes_FromStringAndSize'

.../libmingw32.a(main.o):main.c:.text.startup+0xa7): undefined reference to `WinMain@16'

collect2.exe: error: ld returned 1 exit status

Some more info: I have Windows 7 Home 64-bit OS. I use Python 3.4.1 32-bit, Cython-0.20.1, and TDM-GCC 4.7.1 32-bit.

I did some research. Some people say that it can be caused for example by using 32-bit C compiler and 64-bit Python. But it is not the case here. Other (http://eli.thegreenplace.net/2008/06/28/compiling-python-extensions-with-distutils-and-mingw/) say that I need to create libpython34.a. But my version of Python already came with this file.

Does anyone have an idea what I do wrong? Thanks in advance.

Upvotes: 9

Views: 4560

Answers (3)

greblus
greblus

Reputation: 21

In mingw-w64 (32-bit version from win-builds.org) gcc-4.8.1 has -municode option and it'll use wmain() as entrypoint, also UTF-16 command line will work correctly. It's a pity that it's not mentioned anywhere in the official docs. Found it on some irc log after three days of experiments :)

Upvotes: 1

GriMel
GriMel

Reputation: 2320

In hello.c find:

#if PY_MAJOR_VERSION < 3
int main(int argc, char** argv) {
#elif defined(WIN32) || defined(MS_WINDOWS)
int wmain(int argc, wchar_t **argv)

and replace wmain by main. This worked for me.

Upvotes: 3

abramus
abramus

Reputation: 121

Ok. I figured it out. There are two problems here:

First, undefined reference to 'WinMain@16' is due to to the fact that Cython generates 'wmain' instead of 'main' for Python 3. There is a '-municode' command line option in MinGW to support 'wmain', but it looks that it is only implemented in the latest 64-bit versions of MinGW. It is not implemented in MinGW 4.8.1 32-bit I have installed. An alternative is to use a wrapper 'main' function in C, or just use Python 2.7. I chose the latter.

The remaining undefined references are due to a wrong order of parameters. I can build the application just fine with the following command:

"c:\mingw\bin\gcc.exe" -I"c:\python27\include" -L"c:\python27\libs" hello.c -ohello.exe -lpython27

Upvotes: 3

Related Questions