2

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
Shihe Zhang
  • 2,641
  • 5
  • 36
  • 57
  • 1
    Please show your CMakeLists.txt and the output from `make VERBOSE=1`. Also please don't post images of text. – n. m. could be an AI May 24 '17 at 07:00
  • @n.m. I added the output from make `VERBOSE=1` and remove the image from CMake GUI. – Shihe Zhang May 24 '17 at 07:10
  • 1
    You need to use `target_link_libraries`. `add_executable` lets you specify sources, not libraries. – n. m. could be an AI May 24 '17 at 07:14
  • I used `target_link_libraries`,have messed up CMakeLists.txt.After several failed try.After put it back,it still shows the same error. – Shihe Zhang May 24 '17 at 07:19
  • I can only tell what's wrong with the version you have posted. I cannot tell what's wrong with versions you have tried but didn't post. – n. m. could be an AI May 24 '17 at 07:22
  • It looks like the python libraries were not included in the makefile. Try removing your build directory and running cmake from the clen slate. – n. m. could be an AI May 24 '17 at 07:46
  • Removed build directory then rerun cmake,got same errors. – Shihe Zhang May 24 '17 at 08:03
  • 2
    You build the project with **MinGW**, but use python *imported* library `.lib`, which is for **MSVC**. Probably, you need to convert it for MinGW, like in that question: https://stackoverflow.com/questions/6731100/link-to-python-with-mingw – Tsyvarev May 24 '17 at 08:29
  • @Tsyvarev The link command doesn't seem to mention any python library. – n. m. could be an AI May 24 '17 at 08:46
  • @n.m.: I am unsure, but probably `@CMakeFiles\EmbedPython.dir\linklibs.rsp` contains list of libraries for link with. At least, the asker uses **proper variable** `PYTHON_LIBRARIES` for link with. – Tsyvarev May 24 '17 at 08:59
  • 2
    Is it possible to display `${PYTHON_LIBRARIES}` content? And to extend @Tsyvarev, suggestion, by default _Python_ is compiled with _VStudio_. So, unless you built yours from sources using _MinGW_, the easiest way would be to build your extension with _VStudio_ (assuming there are no restrictions related to using it) as well, and more: use the same version as listed on [\[Python\]: WindowsCompilers](https://wiki.python.org/moin/WindowsCompilers). – CristiFati May 24 '17 at 09:24
  • @Tsyvarev yes,I'm using mingw, the lib was manually set.After rerun cmake,it finds the `.a` file in same directory. – Shihe Zhang May 24 '17 at 12:04
  • Does error remain after rerunning `cmake` and finding `.a` library? – Tsyvarev May 24 '17 at 16:39
  • Yes.The EDIT part,it's the error message after rerun cmake. – Shihe Zhang May 25 '17 at 00:42
  • @CristiFati I checked the link you provided,it's said `MinGW is an alternative C/C++ compiler that works with all Python versions up to 3.4.`may be that's the problem. – Shihe Zhang May 25 '17 at 00:43

2 Answers2

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.

Equilibrius
  • 328
  • 1
  • 13
0

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 :-)

it_nazanin
  • 177
  • 1
  • 8