Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 600
abramus Avatar asked Jun 14 '14 10:06

abramus


People also ask

Does Cython create executable?

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.

Does Cython compile to C?

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.

Can MinGW compile Python?

MinGW is an alternative C/C++ compiler that works with all Python versions up to 3.4.


2 Answers

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.

like image 77
GriMel Avatar answered Oct 05 '22 07:10

GriMel


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

like image 30
abramus Avatar answered Oct 05 '22 08:10

abramus