Python ImportError - undefined symbol - for custom C++ module - c++

I've been developing a Python module in C++ using OpenCV 2.3 through 2.4.2, on Ubuntu 11.04. OpenCV was built from source. I'm not using the version of OpenCV from the Ubuntu repositories.
My Python module compiles with no issues and is loaded in Python properly. However, when I compile this module on Ubuntu 11.10 or 12.04, I get an ImportError with the message "undefined symbol" when trying to load it in Python.
This is how I compile the module:
g++ -fPIC -shared `pkg-config --cflags --libs python` `pkg-config --cflags --libs opencv` -I/usr/local/include/opencv2/legacy -o mymodule.so mymodule.cpp
This is the output of "pkg-config --cflags --libs opencv"
-I/usr/local/include/opencv -I/usr/local/include /usr/local/lib/libopencv_calib3d.so /usr/local/lib/libopencv_contrib.so /usr/local/lib/libopencv_core.so /usr/local/lib/libopencv_features2d.so /usr/local/lib/libopencv_flann.so /usr/local/lib/libopencv_gpu.so /usr/local/lib/libopencv_highgui.so /usr/local/lib/libopencv_imgproc.so /usr/local/lib/libopencv_legacy.so /usr/local/lib/libopencv_ml.so /usr/local/lib/libopencv_nonfree.so /usr/local/lib/libopencv_objdetect.so /usr/local/lib/libopencv_photo.so /usr/local/lib/libopencv_stitching.so /usr/local/lib/libopencv_ts.so /usr/local/lib/libopencv_video.so /usr/local/lib/libopencv_videostab.so
The error I get is:
ImportError: /path/to/service/mymodule.so: undefined symbol: _ZN5CvSVMD1Ev
My understanding is that "undefined symbol" generally means that the given symbol can't be found in any of the linked libraries. But I know that this symbol is there in libopencv_ml.so because when I run this:
$ nm -g /usr/local/lib/libopencv_ml.so | grep _ZN5CvSVMD1Ev
I get:
000000000002fd40 T _ZN5CvSVMD1Ev
/usr/local/lib seems to be in the dynamic linker cache.
$ cat /etc/ld.so.conf.d/libc.conf
# libc default configuration
/usr/local/lib
And the so file is there in the cache too.
$ ldconfig -p | grep opencv | grep ml
libopencv_ml.so.2.4 (libc6,x86-64) => /usr/local/lib/libopencv_ml.so.2.4
libopencv_ml.so (libc6,x86-64) => /usr/local/lib/libopencv_ml.so
So can you give me any clue what I might be doing wrong? Has something changed between Ubuntu 11.04 and 11.10 in the manner in which shared libraries are loaded when running Python? Or is this a problem with OpenCV?

The solution is to put the generated module name before the other modules it depends on, on the g++ command-line.
g++ -fPIC -shared -o mymodule.so mymodule.cpp `pkg-config --cflags --libs python` `pkg-config --cflags --libs opencv` -I/usr/local/include/opencv2/legacy
The gcc man page says of the -l option,
It makes a difference where in the command you write this option; the
linker searches and processes libraries and object files in the order
they are specified. Thus, foo.o -lz bar.o searches library z after
file foo.o but before bar.o. If bar.o refers to functions in z, those
functions may not be loaded.
Since the name of mymodule.so was provided before the libraries it was supposed to be linked to, none of them were actually linked to the generated .so file.
Thanks for #J.F.Sebastian for pointing out how -l works.

Related

how to link specific version of shared library in g++

I have the following shared libraries:
libssl.so, libssl.so.1.1, libcurl.so, libcurl.so.4, libcurl.so.4.4.0, libcrypto.so, libcrypto.so.1.1.
All of the libraries are in the openssl folder.
My question is, how can I link version 1.1 of libssl? Is it done automatically?
I've tried the following:
g++ -c my_file_name.cpp -std=c++11 -w -fpermissive -lpthread --coverage $(INCLUDES) `pkg-config --cflags glib-2.0` `pkg-config --libs glib-2.0` -O0 -Lopenssl -lcrypto -lcurl -lssl
g++ my_file_name.o -o ex -std=c++11 -w -fpermissive -lpthread --coverage -lgtest -lgtest_main -lpthread `pkg-config --cflags glib-2.0` `pkg-config --libs glib-2.0` -O0 -Lopenssl -lcrypto -lcurl -lssl
But it seems that the link doesn't happen. As I still get errors like:
error: ‘X509_STORE_CTX_get0_chain’ was not declared in this scope
Later edit
nm libssl.so.1.1 | grep X509_STORE_CTX_get0_chain results in 0000000000218210 T X509_STORE_CTX_get0_chain. That would mean that the link that I've done does not happen.
It's worth mentioning that the error comes from a .c file included in the .cpp file.
Probably the libssl.so is a symbolic link to libssl.so.1.1 etc. etc.
The problem seems to be related to the missing implementation in one of these library of this function :X509_STORE_CTX_get0_chain.
Now you have to check if this symbol is defined in one of these library you link, or if you need to link someone else.
To check this you can execute the following command over each library:
nm libToCheck.so | grep X509_STORE_CTX_get0_chain
if no one have this symbol defined maybe you missing some library to link.
If exist, check the scope of the utilizzation of the function, it could not correspond to the scope declared in the library. Check the namespace or similar.

compile static binary while using <sqlite3>?

Is it possible to compile a program that uses sqlite3.h (-lsqlite3) into a static binary?
here is what happens when I try:
g++ -m64 -std=c++17 -static Database.cpp -o test.app `pkg-config --static --cflags --libs sqlite3`
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/libsqlite3.a(sqlite3.o): in function `unixDlOpen':
(.text+0x8d49): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking`
Linux x86_64

Shared Object Library not linked after compiling

My program uses the libuvc-library and therefore the libuvc.so.0.
But after successful compilation, i can't run the program, because:
root#Raspi_DataHarvest:~/Schreibtisch# g++ UVCCameraHandler.cpp `pkg-config --libs --cflags opencv` `pkg-config --libs --cflags libuvc` -o UVCCameraHandler.o
./UVCCameraHandler.o: error while loading shared libraries: libuvc.so.0: cannot open shared object file: No such file or directory
The reason is:
root#Raspi_DataHarvest:~/Schreibtisch# ldd UVCCameraHandler.o
linux-vdso.so.1 (0x7edff000)
/usr/lib/arm-linux-gnueabihf/libarmmem.so (0x76f1a000)
libopencv_dnn.so.3.4 => /usr/local/lib/libopencv_dnn.so.3.4 (0x76bc7000)
libopencv_ml.so.3.4 => /usr/local/lib/libopencv_ml.so.3.4 (0x76b20000)
****** libuvc.so.0 => not found *******
...
The file is located in: /usr/local/lib/arm-linux-gnueabihf/libuvc.so.0.0.6
But I don't know how to link the .so file ...
You need to tell the run-time loader where to find your library, because this is not a normal path.
Use this command to run:
LD_LIBRARY_PATH="/usr/local/lib/arm-linux-gnueabihf:$LD_LIBRARY_PATH" ./a.out
Or you can export this LD_LIBRARY_PATH as a environment variable, and run ./a.out directly afterwards.

libxml++/libxml++.h: No such file or directory

I am using ubuntu 12.4 g++ i'm working on libxml++ library I have included this library in my program but I am getting an error saying
libxml++/libxml++.h: No such file or directory
i also tried compiling using g++ main.cc -o main pkg-config --cflags --libs libxml++-2.6 but it is not working. I have installed the latest libraries using sudo apt-get install libxml++.
While compiling for libxml we have to use these options. pkg-config --cflags --libs libxml++-2.6 this should be in single quotation mark / Backticks ("`", grave accents), .
So the command should be like this.
$ g++ main.cc -o program `pkg-config --cflags --libs libxml++-2.6`
or go through this once. http://developer.gnome.org/libxml++/stable/

Linking OpenCV libraries with Eclipse Ubuntu [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
OpenCV on ubuntu 11.10
I am having a very hard time trying to install OpenCV on Ubuntu. I believe that I have already installed OpenCV; however, I am trying to compile one of the samples program kalman.cpp with Eclipse, and I am not able to compile it. My problem I believe is linking with the libraries.
I have seen a lot of tutorial, and I do not understand why after installing opencv in my computer, I get the following output after using the command pkg-confi opencv --libs:
manuel#manuel:~$ sudo pkg-config opencv --libs
/usr/local/lib/libopencv_calib3d.so
/usr/local/lib/libopencv_contrib.so /usr/local/lib/libopencv_core.so
/usr/local/lib/libopencv_features2d.so
/usr/local/lib/libopencv_flann.so /usr/local/lib/libopencv_gpu.so
/usr/local/lib/libopencv_highgui.so
/usr/local/lib/libopencv_imgproc.so /usr/local/lib/libopencv_legacy.so
/usr/local/lib/libopencv_ml.so /usr/local/lib/libopencv_nonfree.so
/usr/local/lib/libopencv_objdetect.so
/usr/local/lib/libopencv_photo.so
/usr/local/lib/libopencv_stitching.so /usr/local/lib/libopencv_ts.so
/usr/local/lib/libopencv_video.so
/usr/local/lib/libopencv_videostab.so
Every tutorial out there the libraries appear as:
-L/where/you/have/installed/opencv/lib -lcxcore -lcv -lhighgui -lcvaux
This is really annoying because Eclipse cannot find the library as libopencv_contrib.so. It is waiting for something as -lopencv_contrib
I really appreciate the help. Please let me know what I am doing wrong.
I have never used OpenCV with Eclipse. I basically compile it using gcc or g++ (depending on c or C++) file.
for C file,
$ gcc -ggdb `pkg-config --cflags opencv` -o `basename opencvtest.c .c` opencvtest.c `pkg-config --libs opencv`
for C++ file,
$ g++ -ggdb `pkg-config --cflags opencv` -o `basename opencvtest.cpp .cpp` opencvtest.cpp `pkg-config --libs opencv`
For more information, see http://jayrambhia.wordpress.com/2012/05/08/beginning-opencv/
If you are comfortable with this, I don't think you would need to use Eclipse.
Hope this helps.
To link to a library you need to specify the path to the directory where it is located using the -L /path/to/libraries flag.
You also need the specific libraries you want using -l my_library.
Usually you also need to specify the necessary include paths using -I /path/to/headers
pkg-config can be used as a helper to do this, as it returns the exact parameters you need in order to use a library.
You should rather use it like this:
echo `pkg-config opencv --cflags --libs`
resp.
g++ my_first_opencv_app.cc `pkg-config opencv --cflags --libs`
which on my system evaluates to
g++ my_first_opencv_app.cc -I/usr/include/opencv -lml -lcvaux -lhighgui -lcv -lcxcore
To get it to work with eclipse, you probably need to specify the include path (/usr/local/include/opencv ?), the library path (/usr/local/lib ?) and the libraries you need via some GUI element somewhere in the project settings. You probably shouldn't need pkgconfig then.