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.
It does link to a simple working example. To compile the Cython source code to a C file that can then be compiled to an executable you use a command like cython myfile. pyx --embed and then compile with whichever C compiler you are using.
The Cython language is a superset of Python that compiles to C, yielding performance boosts that can range from a few percent to several orders of magnitude, depending on the task at hand. For work that is bound by Python's native object types, the speedups won't be large.
MinGW is an alternative C/C++ compiler that works with all Python versions up to 3.4.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With