Cannot link boost.python with mingw - python

I have already build boost.python lib by mingw,Got two lib files:
libboost_python-mgw45-mt-1_46_1.a
libboost_python-mgw45-mt-d-1_46_1.a
But I cant link these libs in my test programs.And the other components like regex works fine.I dont know how to solve this.
my user-config.jam:
using python
: 2.7
: F:\\Programs\\Python\\python # cmd-or-prefix
: F:\\Programs\\Python\\include
: F:\\Programs\\Python\\lib
: <toolset>gcc # condition
;
and the build command:
bjam toolset=gcc --with-python
My Enviroment:
python 2.7
mingw 4.5.1
boost 1.46.1
OS:windows xp
Hope I explained my problem clearly, I'm not english native speaker.
Any advise will be appreciate.

I don't know why (and I never really cared enough to dig for the reason), but Boost.Python refuses to link statically on Windows. This is easily solved, though — just rebuild it as a DLL (bjam toolset=gcc --with-python link=shared).

Related

Py_Initialize undefined reference

I want to add python functions in C++ code.
I made a GUI in gtk (on the Raspberry PI) and now I want to work with a camera module which is easy to handle in python. (I want to start a video directly when I push a button.)
So I included the file Python.h
#include <python3.4m/Python.h>
#include <python3.4m/pythonrun.h>
then I thought it should work, but when I try to compile Py_Initialize()
I get the error:
undefined reference to Py_Initialize.
I think this is strange because, when I type in, there came the selection for Py_Initialize.
In terms of headers you should be fine, since it compiled but failed at linking.
Now you need to link against the Python libraries. The way this is done largely depends on what toolchain you are using.
Maybe you can see my answer in another question:
if with python 3.x installed, maybe this command can work:
g++ hw.cpp `/usr/bin/python3-config --cflags` `/usr/python3-config --ldflags`
By the way, you should check you gcc and python version.
As I know, if gcc version is 5.4 and python version is 3.7, it doesn't work.(python 3.5 >is work)
When you run /usr/bin/python3-config --cflags, in fact, it is the compile option.
Set the python include folder and it static lib on gcc command line and put the python dynamic lib on LD_LIBRARY_PATH. Before Py_Initialize(), do not forget to set python home with Py_SetPythonHome(). These steps must be sufficient for your code compile and run.

What does "Symbol not found / Expected in: flat namespace" actually mean?

When I import a module I built, I get this boost-python related error:
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: dlopen(./myMod.so, 2): Symbol not found: __ZN5boost6python7objects15function_objectERKNS1_11py_functionERKSt4pairIPKNS0_6detail7keywordES9_E
Referenced from: ./myMod.so
Expected in: flat namespace
in ./myMod.so
What does this actually mean? Why was this error raised?
Description
The problem was caused by mixing objects that compiled with libc++ and object that compiled with libstdc++.
In our case, the library myMod.so (compiled with libstdc++) need boost-python that compiled with libstdc++ (boost-python-libstdc++ from now). When boost-python is boost-python-libstdc++, it will work fine. Otherwise - on computer that its boost-python has compiled with libc++ (or another c++ library), it will have a problem loading and running it.
In our case, it happens because that libc++ developers intentionally changed the name of all of their symbols to prevent you (and save you) from mixing code from their library and code from a different one: myMod.so need a function that take an argument from the type. In libc++, this type's name is std::__1::pair. Therefore, this symbol was not found.
To understand why mixing two version of the same API is bad, consider this situation: There are two libraries: Foo and Bar. They both have a function that takes a std::string and uses it for something but they use a different c++ library. When a std::string that has been created by Foo will be passed to Bar, Bar will think that this is an instance of its c++ library's std::string and then bad things can happen (they are a completely different objects).
Note: In some cases, there would be no problem with two or more different versions of the same API in a completely different parts of a program. There will be a problem if they will pass this API's objects between them. However, checking that can be very hard, especially if they pass the API object only as a member of another object. Also, a library's initialization function can do things that should not happen twice. Another version may do these things again.
How to solve that?
You can always recompile your libraries and make them match each other.
You can link boost-python to your library as a static library. Then, it will work on almost every computer (even one that doesn't has boost-python installed). See more about that here.
Summary
myMod.so need another version of boost-python, one that compiled with a specific c++ library. Therefore, It would not work with any another version.
In my case I was receiving:
ImportError: dlopen(/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/xmlsec.cpython-38-darwin.so, 0x0002): symbol not found in flat namespace '_xmlSecDSigNs'
BACKGROUND:
M1 MacBook Pro with Montery
I was working with a python virtualenv (using pyenv) to use an earlier version of python3.8 (3.8.2), while my system had 3.8.10 installed natively.
While I was in the activated 3.8.2 virtualenv I noticed the path in dlopen() was pointing to the package in the native python install NOT the virtualenv install.
SOLUTION:
In my case, I did not need the native 3.8 version at all so I simply removed it and this solved the problem.
I encounter the same problem.
Expected in: flat namespace
Add the linker flag fixes the problem
-lboost_python37
change the dynamic library name to the one installed on the os.
By the way, my os is macOS High Sierra and I use brew to install boost_python3.
Symbol not found means the definition of the declared function or variable was not found. When a header file of a shared object is compiled with your program, linker adds symbols of declared functions and objects to your compiled program. When your program is loaded by the OS's loader, the symbols are resolved so that their definition will be loaded. It is only at this time where if the implementation is missing, loader complains it couldn't find the definition due to may be failing to resolve the actual path to the library or the library itself wasn't compiled with the implementation/source file where the definition of the function or object resides. There is a good article on this on the linux journal http://www.linuxjournal.com/article/6463.
In my case I was just failing to import all the required sources (c++ files) when compiling with Cython.
From the string after "Symbol not found" you can understand which library you are missing.
One of the solutions I found was to uninstall and reinstall it using the no-binary flag, which forces pip to compile the module from source instead of installing from precompiled wheel.
pip install --no-binary :all: <name-of-module>
Found this solution here
Here's what I've learned (osx):
If this is supposed to work (i.e. it works on another computer), you may be experiencing clang/gcc issues. To debug this, use otool -l on the .so file which is raising the error, or a suspect library (in my example it's a boost-python dylib file) and examine the contents. Anything in the /System/ folder is built with clang, and should be installed somewhere else with the gcc compiler. Never delete anything in the /System folder.
.so files are dynamic libraries (so = shared object). On Windows they are called .dll (dynamic-link library). They contain compiled code which contains functions available for usage to any executable which links them.
What is important to notice here is that those .so are not Python files. They were probably compiled from C or C++ code and contain public functions which can be used from Python code (see documentation on Extending Python with C or C++).
On your case, well, you have a corrupt .so. Try reinstalling the affected libraries, or Python, or both.
Problem
I had this same issue when running puma as part of Rails app
LoadError:
dlopen(/Users/alucard/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/puma-5.6.4/lib/puma/puma_http11.bundle, 0x0009): symbol not found in flat namespace '_ERR_load_crypto_strings'
/Users/alucard/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/puma-5.6.4/lib/puma/puma_http11.bundle
Solution
It was solved just by installing puma gem again gem install puma

undefined symbol: _ZN2cv3Mat10deallocateEv

I've been trying to extend my python script with a C++ code. I was able to do that with the simple libraries of C++ (print "hello world"). I followed the tutorial available in the link below:
http://www.tutorialspoint.com/python/python_further_extensions.htm
When I tried to add to my C++ code opencv libraries I encountered the following problem:
ImportError: /usr/local/lib/python2.7/dist-packages/kalman.so: undefined symbol: _ZN2cv3Mat10deallocateEv
I searched for many solutions on the internet, and I found one common answer that didn't workout for me:
"I was able to solve this by going to /usr/lib64/pkgconfig and modified opencv.pc to explicitly have all libraries. I also had to move the plugins from /usr/lib/gstreamer-0.10 to /usr/lib64/gstreamer-0.10"
Please note that I am using ubuntu 14.04 LTS 64-bit and I am planning to run my code later on on a raspberry pi model B running Raspbian OS.
Thank you.
NJ
Check your shared library kalman.so with ldd like so:
$ ldd kalman.so
And you will see that you are missing some libraries. That means that you have to provide some correct path to one of the libraries you use in your code at the linkage stage. something like
$ ...the way you do linking ... -L path_to_the_missing_library
For more information, please, consult this link.
I've met the same problem as you do, and at last I figured out that this is because I didn't add the linking library of opencv when compiling. Try to add the "opencv_core" or other related library when you compile the c++ source file.
Wish this to be helpful to you.

How do I get bjam to detect my Python installation on Windows?

I am inheriting a project that uses bjam and boost-python to build some Python modules written in C++. The Jamroot previously contained:
constant PYTHON_ROOT : C:/Python26 ;
using python : 2.6 : $(PYTHON_ROOT) ;
use-project boost : C:/boost_1_40_0 ;
I have Python 2.7 installed instead, so I changed it to:
using python : 2.7 : C:/Python27 ;
I then ran bjam --toolset=msvc --with-python, which failed (after a very slow "...patience..." set of messages) because it couldn't find pyconfig.h or any of the Boost lib files. I changed it to:
using python : 2.7 : C:/Python27/python.exe : C:/Python27/include : C:/Python27/lib ;
to be explicit about the paths, which appears to have solved the pyconfig.h problem, although I was having issues with a 2.6 version of the above line even though I was specifying --python=2.7.
Now I get a bunch of Boost linker errors like LINK : fatal error LNK1104: cannot open file 'libboost_filesystem-vc90-mt-1_40.lib', even though they exist in C:/boost_1_40_0/stage/lib/.
Any ideas what configuration flags I'm missing?
I think this is that "Boost.Python" within the "C:/boost_1_40_0" was built with Python2.6
But you want to use the "Boost.Python" of Python2.6 for nowadays Python2.7 binaries and libraries. This is a common error. You should rebuilt the Boost source package with Python2.7 !
Depending on what is in your Jamroot file, you might need to add a couple of lines toward the beginning:
use-project boost : <Full path to your boost root directory> ;
This should tell your project to use boost found in the directory.
Also, in your project line, once you have the use-project boost command, you can add the library requirement for boost python in the requirements section of your project definition:
<library>/boost/python//boost_python
With these two lines added to my Jamroot file, I ceased to have the linking issues.
If you could post your Jamroot file, we could see if there is anything more specific needed.

From where can I get python27.dll and wxmsw dll

Our current project is made up of Python2.3 and wxPython-2.4.1.2. It is working fine. But now we are upgrading it to Python2.7 and wxPython2.8.12.1.
As I am new to Python and installation dlls, I need little guidence.
There are following files present in my NSIS installation folder for old Python:
python23.dll
wxmsw24h.dll
As this project was made by previous programmer, I don't know from where he got these dlls or how he made this dll.
I think, to make the installation program for my new python, I will need the following dlls:
python27.dll
wxmsw28h.dll
As per I understand, for wxmsw dll, I need to compile wxPython-src but not sure what can I do for this?
Please let me know, from where can I get these dlls? If I need to create it then please let me know, how can I create these dlls?
Thanks in advance.
Python DLL:
c:\WINDOWS\system32\python27.dll
or:
C:\Windows\SysWOW64\python27.dll
wxPython DLLs:
c:\Python27\Lib\site-packages\wx-2.8-msw-unicode\wx\wxbase28uh_net_vc.dll
c:\Python27\Lib\site-packages\wx-2.8-msw-unicode\wx\wxbase28uh_vc.dll
c:\Python27\Lib\site-packages\wx-2.8-msw-unicode\wx\wxbase28uh_xml_vc.dll
c:\Python27\Lib\site-packages\wx-2.8-msw-unicode\wx\wxmsw28uh_adv_vc.dll
c:\Python27\Lib\site-packages\wx-2.8-msw-unicode\wx\wxmsw28uh_aui_vc.dll
c:\Python27\Lib\site-packages\wx-2.8-msw-unicode\wx\wxmsw28uh_core_vc.dll
c:\Python27\Lib\site-packages\wx-2.8-msw-unicode\wx\wxmsw28uh_gizmos_vc.dll
c:\Python27\Lib\site-packages\wx-2.8-msw-unicode\wx\wxmsw28uh_gizmos_xrc_vc.dll
c:\Python27\Lib\site-packages\wx-2.8-msw-unicode\wx\wxmsw28uh_gl_vc.dll
c:\Python27\Lib\site-packages\wx-2.8-msw-unicode\wx\wxmsw28uh_html_vc.dll
c:\Python27\Lib\site-packages\wx-2.8-msw-unicode\wx\wxmsw28uh_media_vc.dll
c:\Python27\Lib\site-packages\wx-2.8-msw-unicode\wx\wxmsw28uh_qa_vc.dll
c:\Python27\Lib\site-packages\wx-2.8-msw-unicode\wx\wxmsw28uh_richtext_vc.dll
c:\Python27\Lib\site-packages\wx-2.8-msw-unicode\wx\wxmsw28uh_stc_vc.dll
c:\Python27\Lib\site-packages\wx-2.8-msw-unicode\wx\wxmsw28uh_xrc_vc.dll
But if you install Python and wxPython using installer, you should not need to copy it anywhere if you are not building binary. If you are building standalone binary, see Blender's comment.

Categories