Reputation: 121
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
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
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
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