I cannot seem to get the simple hello.cpp example in Boost.Python to work.
hello.cpp:
char const* greet()
{
return "hello, world";
}
BOOST_PYTHON_MODULE(hello_ext)
{
using namespace boost::python;
def("greet", greet);
}
I am using cmake with mingw-w64 and am not entirely sure of the difference between using the static and shared boost libraries. If the extension is linked with the shared library will the extension library have to be distributed with the boost library as well? I would like to only have to distribute a single dll. What is the difference between Boost_USE_STATIC_LIBS and Boost_USE_STATIC_RUNTIME? If either of these flags are set to ON the subsequent compilation will fail with undefined symbols. If they are both set to OFF a file called libhello_ext.dll is created. However, I cannot get python to use it with either import hello_ext or import libhello_ext.
This is my CMakeLists.txt file:
cmake_minimum_required(VERSION 3.12)
project(hello VERSION 1.0)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Wextra -pedantic -g")
set(BOOST_LIBRARYDIR C:/boost_1_67_0/stage/x64/lib)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME ON)
find_package(Boost 1.67.0 REQUIRED python37)
if (Boost_FOUND)
message(" Boost include directory found at ${Boost_INCLUDE_DIRS}")
message(" Boost libraries found at ${Boost_LIBRARIES}")
else()
message(" Boost not found")
return()
endif()
find_package(PythonLibs 3.7 REQUIRED)
if (PYTHONLIBS_FOUND)
message(" Python include directory found at ${PYTHON_INCLUDE_DIRS}")
message(" Python libraries found at ${PYTHON_LIBRARIES}")
else()
message(" Python not found")
endif()
set(SOURCE_FILES hello.cpp)
add_library(hello_ext SHARED ${SOURCE_FILES})
target_include_directories(hello_ext SYSTEM PRIVATE ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})
target_link_libraries(hello_ext ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
This is the output for mingw32-make:
[ 50%] Linking CXX shared library libhello_ext.dll
CMakeFiles\hello_ext.dir/objects.a(hello.cpp.obj): In function `PyInit_hello_ext':
C:/boost_1_67_0/libs/python/example/tutorial/hello.cpp:15: undefined reference to `__imp__ZN5boost6python6detail11init_moduleER11PyModuleDefPFvvE'
CMakeFiles\hello_ext.dir/objects.a(hello.cpp.obj): In function `boost::python::type_info::name() const':
C:/boost_1_67_0/boost/python/type_id.hpp:160: undefined reference to `__imp__ZN5boost6python6detail12gcc_demangleEPKc'
CMakeFiles\hello_ext.dir/objects.a(hello.cpp.obj): In function `boost::python::to_python_value<char const* const&>::operator()(char const* const&) const':
C:/boost_1_67_0/boost/python/converter/builtin_converters.hpp:157: undefined reference to `__imp__ZN5boost6python9converter19do_return_to_pythonEPKc'
CMakeFiles\hello_ext.dir/objects.a(hello.cpp.obj): In function `void boost::python::def<char const* (*)()>(char const*, char const* (*)())':
C:/boost_1_67_0/boost/python/def.hpp:91: undefined reference to `__imp__ZN5boost6python6detail17scope_setattr_docEPKcRKNS0_3api6objectES3_'
CMakeFiles\hello_ext.dir/objects.a(hello.cpp.obj): In function `boost::python::api::object boost::python::detail::make_function_aux<char const* (*)(), boost::python::default_call_policies, boost::mpl::vector1<char const*> >(char const* (*)(), boost::python::default_call_policies const&, boost::mpl::vector1<char const*> const&)':
C:/boost_1_67_0/boost/python/make_function.hpp:38: undefined reference to `__imp__ZN5boost6python7objects15function_objectERKNS1_11py_functionE'
CMakeFiles\hello_ext.dir/objects.a(hello.cpp.obj): In function `boost::python::objects::py_function_impl_base::py_function_impl_base()':
C:/boost_1_67_0/boost/python/object/py_function.hpp:20: undefined reference to `__imp__ZTVN5boost6python7objects21py_function_impl_baseE'
CMakeFiles\hello_ext.dir/objects.a(hello.cpp.obj): In function `boost::python::objects::caller_py_function_impl<boost::python::detail::caller<char const* (*)(), boost::python::default_call_policies, boost::mpl::vector1<char const*> > >::~caller_py_function_impl()':
C:/boost_1_67_0/boost/python/object/py_function.hpp:30: undefined reference to `__imp__ZN5boost6python7objects21py_function_impl_baseD2Ev'
CMakeFiles\hello_ext.dir/objects.a(hello.cpp.obj): In function `boost::python::converter::expected_pytype_for_arg<char const*>::get_pytype()':
C:/boost_1_67_0/boost/python/converter/pytype_function.hpp:67: undefined reference to `__imp__ZN5boost6python9converter8registry5queryENS0_9type_infoE'
C:/boost_1_67_0/boost/python/converter/pytype_function.hpp:70: undefined reference to `__imp__ZNK5boost6python9converter12registration25expected_from_python_typeEv'
collect2.exe: error: ld returned 1 exit status
mingw32-make[2]: *** [CMakeFiles\hello_ext.dir\build.make:88: libhello_ext.dll] Error 1
mingw32-make[1]: *** [CMakeFiles\Makefile2:72: CMakeFiles/hello_ext.dir/all] Error 2
mingw32-make: *** [Makefile:83: all] Error 2
For some strange reason, the naming convention must be forced for Boost Python (and only for Boost Python, other Boost modules don't need this) in Windows (not in Linux nor MacOSX).
In summary, you need to add:
add_definitions(/DBOOST_PYTHON_STATIC_LIB)
to your CMake config file. Otherwise, your linker will try to use boost_python37-vc141-mt-x64-1_70.lib (the import library associated to the DLL, boost_python37-vc141-mt-x64-1_70.dll) instead of libboost_python37-vc141-mt-x64-1_70.lib, which is the "real" static library (Stupid Windows and its weird convention to use the same extension for Import libraries and Static libraries).
Related
Now that I've successfully installed Cython on Windows 7, I try to compile some Cython code using Cython, but gcc makes my life hard.
cdef void say_hello(name):
print "Hello %s" % name
Using gcc to compile the code throws dozens of undefined reference to -erros, and I'm pretty sure the libpython.a is available (as the installation tutorial said, undefined reference to -errors are thrown if this file is missing).
$ cython ctest.pyx
$ gcc ctest.c -I"C:\Python27\include"
C:\Users\niklas\AppData\Local\Temp\cckThGrF.o:ctest.c:(.text+0x1038): undefined reference to `_imp__PyString_FromStringAndSize'
C:\Users\niklas\AppData\Local\Temp\cckThGrF.o:ctest.c:(.text+0x1075): undefined reference to `_imp___Py_TrueStruct'
C:\Users\niklas\AppData\Local\Temp\cckThGrF.o:ctest.c:(.text+0x1086): undefined reference to `_imp___Py_ZeroStruct'
C:\Users\niklas\AppData\Local\Temp\cckThGrF.o:ctest.c:(.text+0x1099): undefined reference to `_imp___Py_NoneStruct'
C:\Users\niklas\AppData\Local\Temp\cckThGrF.o:ctest.c:(.text+0x10b8): undefined reference to `_imp__PyObject_IsTrue'
c:/program files/mingw/bin/../lib/gcc/mingw32/4.5.2/../../../libmingw32.a(main.o):main.c:(.text+0xd2): undefined reference to `WinMain#16'
collect2: ld returned 1 exit status
The weird thing is, using pyximport* or a setup-script works pretty fine, but it's both not very handy when still working on a module.
How to compile those .c files generated with Cython using gcc ?
or any other compiler, important is that it will work !
*pyximport: Is it normal that only python-native functions and classes are contained in the imported module and not cdef-functions and classes ?
like:
# filename: cython_test.pyx
cdef c_foo():
print "c_foo !"
def foo():
print "foo !"
c_foo()
import pyximport as p; p.install()
import cython_test
cython_test.foo()
# foo !\nc_foo !
cython_test.c_foo()
# AttributeError, module object has no attribute c_foo
UPDATE
Calling $ gcc ctest.c "C:\Python27\libs\libpython27.a" kills the undefined reference to -erros, but this one:
c:/program files/mingw/bin/../lib/gcc/mingw32/4.5.2/../../../libmingw32.a(main.o):main.c:(.text+0xd2): undefined reference to `WinMain#16'
Try:
gcc -c -IC:\Python27\include -o ctest.o ctest.c
gcc -shared -LC:\Python27\libs -o ctest.pyd ctest.o -lpython27
-shared creates a shared library. -lpython27 links with the import library C:\Python27\libs\libpython27.a.
That is a linker (ld) error and not a compiler error. You should provide the path to the library (-l and -L) and not only to the headers (-I).
Is it possible (and how) to use MinGW-w64 for building of C-extensions for Python or embeding Python on Windows?
Let's take as example the following cython-extension foo.pyx:
print("foo loaded")
from which the C-code can be generated either via cython -3 foo.pyx or cython -3 --embed foo.pyx if interpreter should be embedded.
While mingw-w64-compiler is not really supported (the only supported windows compiler is MSVC), it can be used to create C-extensions or to embed Python. There are however no guarantee, this won't break in the future versions.
distutils does not support mingw-w64, so there is no gain in setting up a setup.py-file - the steps must be performed manually.
First we need some information usually provided by distutils:
Headers: We need the path to the Python includes. For a way to find them see this SO-post.
DLL: mingw-w64's linker works differently than MSVC's: python-dll and not python-lib is needed. So we need the path to the pythonXY.dll which is usually next the the python.exe.
Once the C-code is created/generated, the extension can be build via
x86_64-w64-mingw32-gcc -shared foo.c -DMS_WIN64 -O2 <other_options> -I <path_to_python_include> -L <path_to_python_dll> -lpython37 -o foo.pyd
The important details are:
it is probably Ok to use only use -O2 for optimization and leave <other_options> empty-
It is important to define MS_WIN64-macro (e.g. via -DMS_WIN64). In order to build for x64 on windows it must be set, but it works out of the box only for MSVC (defining _WIN64 could have slightly different outcomes):
#ifdef _WIN64
#define MS_WIN64
#endif
if it is not done, at least for files generated by Cython the following error message will be generated by the compiler:
error: enumerator value for ‘__pyx_check_sizeof_voidp’ is not an integer constant
201 | enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) };
pyd is just a dll in disguise, thus we need the -shared option, which means a dynamic library (i.e. shared-object in Linux-world) will be created.
It is important, that the python-library (pythonXY) should be the dll itself and not the lib (see this SO-post). Thua we use the path to pythonXY.dll (in my case python37) and not pythonXY.lib, as it would be the case for MSVC.
One probably should add the proper suffix to the resulting pyd-file, I use the old convention for simplicity here.
Embeded Python:
In this case an executable should be build (e.g. the C-file is generated by Cython with --embed option: cython -3 --embed foo.pyx) and thus the command line looks as follows:
x86_64-w64-mingw32-gcc foo.c -DMS_WIN64 -O2 <other_options> -I <path_to_python_include> -L <path_to_python_dll> -lpython37 -o foo.exe -municode
There are two important differences:
-shared should no longer be used, as the result is no longer a dynamic library (that is what *.pyd-file is after all) but an executable.
-municode is needed, because for Windows, Cython defines int wmain(int argc, wchar_t **argv) instead of int main(int argc, char** argv). Without this option, an error message like
/build/mingw-w64-_1w3Xm/mingw-w64-4.0.4/mingw-w64-crt/crt/crt0_c.c:18: undefined reference to 'WinMain'
collect2: error: ld returned 1 exit status
would appear (see this SO-post for more information).
Note: for the resulting executable to run, a whole python-distribution (and not only the dll) is needed (see also this SO-post), otherwise the resulting executable will abort with error (either the python dll wasn't found or the python installation or the site packages - depending on the configuration of the machine on which the exe has to run).
mingw-w64 can also be used on Linux for cross-compilation for Windows, see this SO-post.
Is it possible (and how) to use MinGW-w64 for building of C-extensions for Python or embeding Python on Windows?
Let's take as example the following cython-extension foo.pyx:
print("foo loaded")
from which the C-code can be generated either via cython -3 foo.pyx or cython -3 --embed foo.pyx if interpreter should be embedded.
While mingw-w64-compiler is not really supported (the only supported windows compiler is MSVC), it can be used to create C-extensions or to embed Python. There are however no guarantee, this won't break in the future versions.
distutils does not support mingw-w64, so there is no gain in setting up a setup.py-file - the steps must be performed manually.
First we need some information usually provided by distutils:
Headers: We need the path to the Python includes. For a way to find them see this SO-post.
DLL: mingw-w64's linker works differently than MSVC's: python-dll and not python-lib is needed. So we need the path to the pythonXY.dll which is usually next the the python.exe.
Once the C-code is created/generated, the extension can be build via
x86_64-w64-mingw32-gcc -shared foo.c -DMS_WIN64 -O2 <other_options> -I <path_to_python_include> -L <path_to_python_dll> -lpython37 -o foo.pyd
The important details are:
it is probably Ok to use only use -O2 for optimization and leave <other_options> empty-
It is important to define MS_WIN64-macro (e.g. via -DMS_WIN64). In order to build for x64 on windows it must be set, but it works out of the box only for MSVC (defining _WIN64 could have slightly different outcomes):
#ifdef _WIN64
#define MS_WIN64
#endif
if it is not done, at least for files generated by Cython the following error message will be generated by the compiler:
error: enumerator value for ‘__pyx_check_sizeof_voidp’ is not an integer constant
201 | enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) };
pyd is just a dll in disguise, thus we need the -shared option, which means a dynamic library (i.e. shared-object in Linux-world) will be created.
It is important, that the python-library (pythonXY) should be the dll itself and not the lib (see this SO-post). Thua we use the path to pythonXY.dll (in my case python37) and not pythonXY.lib, as it would be the case for MSVC.
One probably should add the proper suffix to the resulting pyd-file, I use the old convention for simplicity here.
Embeded Python:
In this case an executable should be build (e.g. the C-file is generated by Cython with --embed option: cython -3 --embed foo.pyx) and thus the command line looks as follows:
x86_64-w64-mingw32-gcc foo.c -DMS_WIN64 -O2 <other_options> -I <path_to_python_include> -L <path_to_python_dll> -lpython37 -o foo.exe -municode
There are two important differences:
-shared should no longer be used, as the result is no longer a dynamic library (that is what *.pyd-file is after all) but an executable.
-municode is needed, because for Windows, Cython defines int wmain(int argc, wchar_t **argv) instead of int main(int argc, char** argv). Without this option, an error message like
/build/mingw-w64-_1w3Xm/mingw-w64-4.0.4/mingw-w64-crt/crt/crt0_c.c:18: undefined reference to 'WinMain'
collect2: error: ld returned 1 exit status
would appear (see this SO-post for more information).
Note: for the resulting executable to run, a whole python-distribution (and not only the dll) is needed (see also this SO-post), otherwise the resulting executable will abort with error (either the python dll wasn't found or the python installation or the site packages - depending on the configuration of the machine on which the exe has to run).
mingw-w64 can also be used on Linux for cross-compilation for Windows, see this SO-post.
Try to embed python3.6 in C++ on Win10 64bit system.
Python is installed by python-3.6.1-amd64.exe.
The CMakeList.txt is showing below
cmake_minimum_required(VERSION 3.8)
project(EmbedPython)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
find_package(PythonLibs REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
add_executable(EmbedPython ${SOURCE_FILES} ${PYTHON_INCLUDE_DIRS})
target_link_libraries(EmbedPython ${PYTHON_LIBRARIES})
And CMake found the Python package.
PYTHON_INCLUDE_DIR C:/Program Files (x86)/Python36/include
PYTHON_LIBRARY C:/Program Files (x86)/Python36/libs/python36.lib
Find a comment on github it's talking about the API problem.
# used to embed python script
find_package(PythonLibs 2.7 REQUIRED) # this has to be 2.7 because the 3.0 API requires argv to be wchar_t** rather than the default char**
include_directories(${PYTHON_INCLUDE_DIRS})
target_link_libraries( assignment ${PYTHON_LIBRARIES})
The errors below is what I'm facing.
[ 50%] Building CXX object CMakeFiles/EmbedPython.dir/main.cpp.obj
[100%] Linking CXX executable EmbedPython.exe
CMakeFiles\EmbedPython.dir/objects.a(main.cpp.obj): In function `main':
D:/Projects/EmbedPython/main.cpp:16: undefined reference to `_imp__Py_Initialize'
D:/Projects/EmbedPython/main.cpp:17: undefined reference to `_imp__PyUnicode_DecodeFSDefault'
D:/Projects/EmbedPython/main.cpp:20: undefined reference to `_imp__PyImport_Import'
D:/Projects/EmbedPython/main.cpp:24: undefined reference to `_imp__PyObject_GetAttrString'
D:/Projects/EmbedPython/main.cpp:27: undefined reference to `_imp__PyCallable_Check'
D:/Projects/EmbedPython/main.cpp:28: undefined reference to `_imp__PyTuple_New'
D:/Projects/EmbedPython/main.cpp:30: undefined reference to `_imp__PyLong_FromLong'
D:/Projects/EmbedPython/main.cpp:38: undefined reference to `_imp__PyTuple_SetItem'
D:/Projects/EmbedPython/main.cpp:40: undefined reference to `_imp__PyObject_CallObject'
D:/Projects/EmbedPython/main.cpp:43: undefined reference to `_imp__PyLong_AsLong'
D:/Projects/EmbedPython/main.cpp:49: undefined reference to `_imp__PyErr_Print'
D:/Projects/EmbedPython/main.cpp:55: undefined reference to `_imp__PyErr_Occurred'
D:/Projects/EmbedPython/main.cpp:56: undefined reference to `_imp__PyErr_Print'
D:/Projects/EmbedPython/main.cpp:63: undefined reference to `_imp__PyErr_Print'
D:/Projects/EmbedPython/main.cpp:67: undefined reference to `_imp__Py_FinalizeEx'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [EmbedPython.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFiles/EmbedPython.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles/EmbedPython.dir/rule] Error 2
mingw32-make.exe: *** [EmbedPython] Error 2
CMakeFiles\EmbedPython.dir\build.make:96: recipe for target 'EmbedPython.exe' failed
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/EmbedPython.dir/all' failed
CMakeFiles\Makefile2:78: recipe for target 'CMakeFiles/EmbedPython.dir/rule' failed
Makefile:117: recipe for target 'EmbedPython' failed
Not sure what to do to make the project run.Any help would be appreciated.
EDIT:
the result from make VERBOSE=1
D:\Projects\EmbedPython\cmake-build-debug>make VERBOSE=1
"C:\Program Files\JetBrains\CLion 172.2273.4\bin\cmake\bin\cmake.exe" -HD:\Projects\EmbedPython -BD:\Projects\EmbedPython\cmake-build-debug --check-build-system CMakeFiles\Makefile.cmake 0
"C:\Program Files\JetBrains\CLion 172.2273.4\bin\cmake\bin\cmake.exe" -E cmake_progress_start D:\Projects\EmbedPython\cmake-build-debug\CMakeFiles D:\Projects\EmbedPython\cmake-build-debug\CMakeFiles\progress.marks
make -f CMakeFiles\Makefile2 all
make[1]: Entering directory 'D:/Projects/EmbedPython/cmake-build-debug'
make -f CMakeFiles\EmbedPython.dir\build.make CMakeFiles/EmbedPython.dir/depend
make[2]: Entering directory 'D:/Projects/EmbedPython/cmake-build-debug'
"C:\Program Files\JetBrains\CLion 172.2273.4\bin\cmake\bin\cmake.exe" -E cmake_depends "MinGW Makefiles" D:\Projects\EmbedPython D:\Projects\EmbedPython D:\Projects\EmbedPython\cmake-build-debug D:\Projects\EmbedPython\cmake-build-debug D:\Projects\EmbedPython\cmake-build-debug\CMakeFiles\EmbedPython.dir\DependInfo.cmake --color=
make[2]: Leaving directory 'D:/Projects/EmbedPython/cmake-build-debug'
make -f CMakeFiles\EmbedPython.dir\build.make CMakeFiles/EmbedPython.dir/build
make[2]: Entering directory 'D:/Projects/EmbedPython/cmake-build-debug'
[ 50%] Linking CXX executable EmbedPython.exe
"C:\Program Files\JetBrains\CLion 172.2273.4\bin\cmake\bin\cmake.exe" -E cmake_link_script CMakeFiles\EmbedPython.dir\link.txt --verbose=1
"C:\Program Files\JetBrains\CLion 172.2273.4\bin\cmake\bin\cmake.exe" -E remove -f CMakeFiles\EmbedPython.dir/objects.a
C:\PROGRA~2\MINGW-~1\I686-6~1.0-P\mingw32\bin\ar.exe cr CMakeFiles\EmbedPython.dir/objects.a #CMakeFiles\EmbedPython.dir\objects1.rsp
C:\PROGRA~2\MINGW-~1\I686-6~1.0-P\mingw32\bin\G__~1.EXE -g -Wl,--whole-archive CMakeFiles\EmbedPython.dir/objects.a -Wl,--no-whole-archive -o EmbedPython.exe -Wl,--out-implib,libEmbedPython.dll.a -Wl,--major-image-version,0,--minor-image-version,0 #CMakeFiles\EmbedPython.dir\linklibs.rsp
CMakeFiles\EmbedPython.dir/objects.a(main.cpp.obj): In function `main':
D:/Projects/EmbedPython/main.cpp:16: undefined reference to `_imp__Py_Initialize'
D:/Projects/EmbedPython/main.cpp:17: undefined reference to `_imp__PyUnicode_DecodeFSDefault'
D:/Projects/EmbedPython/main.cpp:20: undefined reference to `_imp__PyImport_Import'
D:/Projects/EmbedPython/main.cpp:24: undefined reference to `_imp__PyObject_GetAttrString'
D:/Projects/EmbedPython/main.cpp:27: undefined reference to `_imp__PyCallable_Check'
D:/Projects/EmbedPython/main.cpp:28: undefined reference to `_imp__PyTuple_New'
D:/Projects/EmbedPython/main.cpp:30: undefined reference to `_imp__PyLong_FromLong'
D:/Projects/EmbedPython/main.cpp:38: undefined reference to `_imp__PyTuple_SetItem'
D:/Projects/EmbedPython/main.cpp:40: undefined reference to `_imp__PyObject_CallObject'
D:/Projects/EmbedPython/main.cpp:43: undefined reference to `_imp__PyLong_AsLong'
D:/Projects/EmbedPython/main.cpp:49: undefined reference to `_imp__PyErr_Print'
D:/Projects/EmbedPython/main.cpp:55: undefined reference to `_imp__PyErr_Occurred'
D:/Projects/EmbedPython/main.cpp:56: undefined reference to `_imp__PyErr_Print'
D:/Projects/EmbedPython/main.cpp:63: undefined reference to `_imp__PyErr_Print'
D:/Projects/EmbedPython/main.cpp:67: undefined reference to `_imp__Py_FinalizeEx'
collect2.exe: error: ld returned 1 exit status
CMakeFiles\EmbedPython.dir\build.make:97: recipe for target 'EmbedPython.exe' failed
make[2]: *** [EmbedPython.exe] Error 1
make[2]: Leaving directory 'D:/Projects/EmbedPython/cmake-build-debug'
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/EmbedPython.dir/all' failed
make[1]: *** [CMakeFiles/EmbedPython.dir/all] Error 2
make[1]: Leaving directory 'D:/Projects/EmbedPython/cmake-build-debug'
Makefile:82: recipe for target 'all' failed
make: *** [all] Error 2
I had the exactly same problem, just with Python 3.7 while trying to build the example from the Python manual.
My system is a 64-bit Windows, the installed Python is a 64-bit 3.7 (from Anaconda3), and the compiler is a 32-bit MinGW 5.3.0 (from Qt 5.11).
The simplest solution that worked for me is the following:
Download Windows x86 embeddable zip file from this page.
Put the content of that archive to a folder inside the project you're building.
Do not install anything from that archive and do not put it on the system PATH.
Add the above folder to the gcc library search path, using: -L"path/to/folder/"
Add the python library to the linker, using -l"python37" ( replace 37 with whatever version you download)
As noted here (this was a hard one to find!), add a definition, using -DPy_BUILD_CORE_BUILTIN=1 (It is also possible to write #define DPy_BUILD_CORE_BUILTIN 1 just before #include-ing the Python header, though I would not recommend it)
Provide the path to the Python headers, using -I"path/to/include". I used the one from Anaconda, e.g. -I"c:/Users/user/Anaconda3/include/". Any installed header will do, just make sure its from the same version (headers from an older version might also be used, but this may cause a rupture in the space-time continuum)
Make sure that #include <Python.h> is before any other include, as stated in the manual.
As a side note, the MinGW linker (ld) is perfectly content, for many years now, if you just give it the "dll" file. No "lib", nor "a", is needed if you don't have one and only perform dynamic linking. This is why I just told the linker to use python37.
It it actually smart enough to look for files like python37.lib, python37.dll & libpython37.a.
Also note that the "embedable zip" is just the bare minimum needed for, well, embedding Python.
And as a last comment, contrary to what is stated here, there is no problem whatsoever linking from GCC with a library compiled using MSVS (and vice versa), as long as the library uses the plain C interface, since that interface is pretty much the only thing that is compatible across different compilers for any given platform.
This is pretty much the exact reason why Python is using the C interface (and nothing else, not even C++) for extending & embedding - to allow code written in any language, using any tool set, to interface with Python.
I had the same problem.
probably the problem is because of using 32 bit MinGW and 64 bit Python. you should install 32 bit version of python
Hope it will be useful to you :-)
I try to use Python/C API on msys2-mingw, so I install
this package mingw-w64-x86_64-python2, and I write main.cpp:
#include <python2.7\Python.h>
int main(){
return 0;
}
And when I enter this $ g++ main.cpp -o main,
It gives me these msg:
In file included from \msys64\mingw64\include/python2.7\Python.h:58:0,
from main.cpp:1:
\msys64\mingw64\include/python2.7\pyport.h:907:2: 錯誤:#error "LONG_BIT definition appears wrong for platform (bad gcc/glibc config?)."
#error "LONG_BIT definition appears wrong for platform (bad gcc/glibc config?)."
^
In file included from \msys64\mingw64\include/python2.7\Python.h:8:0,
from main.cpp:1:
/usr/include/cygwin/types.h:78:20: 錯誤:一個宣告指定了多個類型
typedef __uint32_t uid_t;
^
/usr/include/cygwin/types.h:78:20: 錯誤:沒有宣告任何東西 [-fpermissive]
/usr/include/cygwin/types.h:84:20: 錯誤:一個宣告指定了多個類型
typedef __uint32_t gid_t;
^
/usr/include/cygwin/types.h:84:20: 錯誤:沒有宣告任何東西 [-fpermissive]
makefile:2: recipe for target 'main' failed
make: *** [main] Error 1
I have no idea why these happen. It's not a error about linking file(since I hadn't link any file.). Is my method wrong, or I include the wrong file ?
You mix GCC's: mingw-w64 GCC and msys GCC. For mingw-w64 GCC under MSYS2 you must not have includes from /usr. See your error message /usr/include/cygwin/types.h