I wan't want to create a cross-plattform programm that embedds the python interpreter, and compile it with MinGW. But the Python Binary distribution provides no libraries for MinGW to link with (only python32.lib
for Visual C++), and the Python Source package provides no support for compiling with MinGW.
I tried linking to python32.lib
in Mingw with -lpython32
but it still generates errors like:
main.cpp: undefined reference to `_imp__Py_Initialize'
main.cpp: undefined reference to `_imp__Py_Finalize'
How do I link Python in MinGW? I really don't want to switch to using Visual C++.
MinGW is an alternative C/C++ compiler that works with all Python versions up to 3.4.
MinGW is a compiler system based on the GNU GCC and Binutils projects that compiles and links code to be run on Win32 (Windows) systems. It provides C, C++ and Fortran compilers plus other related tools. 'MinGW' refers to the "Minimalist GNU for Windows" project.
With nm and dlltool from binutils, you should be able to rebuild the library for gcc:
echo EXPORTS > python32.def
nm python32.lib | grep " T _" | sed "s/.* T _//" >> python32.def
dlltool --input-def python32.def --dllname python32 --output-lib libpython32.a
python_test.c:
#include "Python.h"
int main(int argc, char *argv[]) {
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print('Today is',ctime(time())\n)");
Py_Finalize();
return 0;
}
Compile:
gcc -Wall -IC:\Python32\include -LC:\Python32\libs -o python_test.exe python_test.c -lpython32
Test:
C:\python_test.exe
Today is Mon Jul 18 08:50:53 2011
Edit: If you'd prefer to skip building this yourself on x64, you can download it for several versions from Christoph Gohlke's Unofficial Windows Binaries for Python Extension Packages.
Edit: Here's a Python version based on the existing function that's distributed in Tools/msi/msi.py:
import subprocess
import warnings
import re
NM = 'x86_64-w64-mingw32-nm'
DLLTOOL = 'x86_64-w64-mingw32-dlltool'
EXPORT_PATTERN = r'^[_]{1,2}imp_(?P<export>.*) in python\d+\.dll'
def build_libpython(ver, nm=NM, dlltool=DLLTOOL,
export_pattern=EXPORT_PATTERN):
pylib = 'python%s.lib' % ver
pydef = 'python%s.def' % ver
pydll = 'python%s.dll' % ver
libpy = 'libpython%s.a' % ver
warning = '%s failed - ' + '%s not built' % libpy
match_export = re.compile(export_pattern).match
cmd_nm = [nm, '-Cs', pylib]
cmd_dlltool = [dlltool,
'--dllname', pydll,
'--def', pydef,
'--output-lib', libpy]
with open(pydef, 'w') as f:
f.write('LIBRARY %s\nEXPORTS\n' % pydll)
p_nm = subprocess.Popen(cmd_nm,
stdout=subprocess.PIPE,
universal_newlines=True)
for line in sorted(p_nm.stdout):
m = match_export(line)
if m:
f.write(m.group('export') + '\n')
if p_nm.wait() != 0:
warnings.warn(warning % nm)
return False
if subprocess.call(cmd_dlltool) != 0:
warnings.warn(warning % dlltool)
return False
return True
For example:
import os
for n in (27, 33, 35):
pylib = 'python%s.lib' % n
if os.path.exists(pylib):
build_libpython(n)
pydef = 'python%s.def' % n
lc_def = sum(1 for line in open(pydef))
libpy = 'libpython%s.a' % n
lc_lib = sum(1 for line in os.popen('ar -t %s' % libpy))
assert lc_def == lc_lib
Try this...
gendef /c/windows/system32/python32.dll
dlltool -D python32.dll -d python32.def -l libpython32.a
libpython32.a
to your ./python32/libs
directory.If your libpython32.a
file is 0 bytes, something went wrong. Double-check that you downloaded the correct version of gendef for your version of mingw/msys. If you're running a 64-bit build, you'll likely have to download the gendef binaries and compile yourself, but that's simple enough.
Hope that helps.
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