Ссылка на Python с помощью MinGW
Я не хочу, чтобы создать кросс-платформа программа, которая embedds интерпретатор Python, и скомпилировать его с помощью MinGW. Но двоичный дистрибутив Python не предоставляет библиотек для MinGW для связи с (только python32.lib
для Visual C++), а исходный пакет Python не поддерживает компиляцию с MinGW.
Я попытался связать с python32.lib
в Mingw с -lpython32
но он по-прежнему выдает ошибки типа:
main.cpp: undefined reference to `_imp__Py_Initialize'
main.cpp: undefined reference to `_imp__Py_Finalize'
как связать Python в MinGW? Я правда не хочу. переключитесь на использование Visual C++.
3 ответов
С помощью nm и dlltool из binutils вы сможете перестроить библиотеку для 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
неофициальные двоичные файлы Windows для пакетов расширений Python.
редактировать: Вот версия Python, основанная на существующей функции, которая распространяется в 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
например:
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
попробуйте это...
- скачать gendef для вашей версии mingw (32 или 64 бит) и в оболочке msys...
- Run
gendef /c/windows/system32/python32.dll
- Run
dlltool -D python32.dll -d python32.def -l libpython32.a
- скопировать
libpython32.a
на .
если libpython32.a
файл 0 байт, что-то пошло не так. Дважды проверьте, что вы загрузили правильную версию gendef для вашей версии mingw / msys. Если вы используете 64-разрядную сборку, вероятно, вам придется загрузить двоичные файлы gendef и скомпилировать себя, но это достаточно просто.
надеюсь, что это поможет.
EmbeddingPython.c
#include <Python.h>
int main(int argc, char *argv[])
{
Py_SetProgramName((wchar_t *)argv[0]); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print('Today is', ctime(time()))\n");
Py_Finalize();
return 0;
}
и используйте gcc следующим образом:
gcc EmbeddingPython.c -I C:\Python34\include -LC:/Python34/libs -lpython34 -o a.exe
и он работает так, как мы ожидали.
D:\>a.exe
Today is Fri Aug 29 15:14:04 2014