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.
Related
I've installed the libglfw3-dev:amd64 package on Ubuntu using the standard sudo apt get etc. My following compiling line is:
g++ -o output -IL/usr/lib/x86_64-linux-gnu -lglfw driver.o
My current c++ file is:
#include <GLFW/glfw3.h>
int main(void)
{
GLFWwindow* window;
if (!glfwInit())
return -1;
}
I've tried using local libraries of glfw and setting the -I and -L locations but nothing has seemed to work. I've made sure the .so and .h files are in their respective locations but I always get this error while running make:
g++ -o output -I/usr/include/GLFW -L/usr/lib/x86_64-linux-gnu -lglfw
driver.o
driver.o: In function `main':
driver.cpp:(.text+0x5): undefined reference to `glfwInit'
collect2: error: ld returned 1 exit status
Makefile:2: recipe for target 'output' failed
make: *** [output] Error 1
I've tried looking at all the other SO posts and they recommend compiling with tons of extra flags, but the only thing I've been able to draw from them is that something is wrong with my library since VScode detects the .h files. How can I compile this without any errors?
Have you tried swapping the linker arguments around? That is, compile with
g++ -o output driver.o -lglfw
The linker goes through the files from left to right, and it has to know which symbols from libraries you need, before the libraries are processed.
All is perfectly explained in the manual https://www.glfw.org/docs/latest/build_guide.html#build_link_pkgconfig
The key problem is in your -I/usr/include/GLFW and #include <GLFW/glfw3.h> that gives in sum the path /usr/include/GLFW/GLFW/glfw3.h. I suppose this is a wrong path to glfw3.h. compilation was successful because of the system default include path -I/usr/include.
Do not tune compiler flags manually, let pkg-config do
it for you.
A typical compile and link command-line when using the static version of the GLFW library may look like this:
g++ -o output `pkg-config --cflags glfw3` yourprog.c `pkg-config --static --libs glfw3`
If you are using the shared version of the GLFW library, simply omit the --static flag.
g++ -o output `pkg-config --cflags glfw3` yourprog.c `pkg-config --libs glfw3`
I am making a simple hello world program to learn about linking shared libraries in linux. I have managed to compile the main program into an executable with the shared library using the following:
g++ -fPIC -c lab2_hello_main.cpp <--create position independent objects
g++ -fPIC -c lab2_hello_sub.cpp
g++ -fPIC -shared -Wl,-soname=libfuncs.so.1.0 *.o -o libfuncs.so.1.0 -lc <--make the shared library
ln -s libfuncs.so.1.0 libfuncs.so <-- soft links for compiling and running
ln -s libfuncs.so.1.0 libfuncs.so.1
g++ -o hello_dyn lab2_hello_main.cpp -L/mypath -lfuncs <-- Linking the library to main
When I do an ldd on hello_dyn I get an output stating that the library can't be found:
"libfuncs.so.1.0 => not found"
The other libraries it looks for automatically are fine.
Anyone know why this might be?
Your shared library's location is not in the linker's search path. You can confirm this by adding the directory in which your library is located to the LD_LIBRARY_PATH environment variable and then run ldd again. See the ld.so(8) man page for details.
I'm trying to compile an executable file which i want also to use as shared library. When i'm clearly compile and linking it as "executable" - everything fine - file could start and work correctly. At this phase i cant correctly linking other libraries with it (tons of redefinitions in log). When i'm trying to add options -Fpic -shared - program copiles successfully, but starting with segmentation fault. How can i make it executable and "sharedlibrary" at the same time?
A single file cannot be a shared library and an executable at the same time. But you can link your object files twice to make both. It'd go something like this:
g++ -c -o module.o module.cpp # create an object that has no main()
g++ -shared -fPIC -o libmodule.so module.o # build shared library
g++ -o program module.o main.cpp # build executable
Or instead, the last line could link the shared library (in which case you'll need the library present when you run the executable):
g++ -o program -l module main.cpp
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.
I can't seem to compile this basic program using glib.h...
#include glib.h
#include stdio.h
int main ()
{
return ((glib_major_version) || (glib_minor_version) || (glib_micro_version)); ;
return 0;
}
glib.h is located in /usr/local/include/glib-2.0
So I compiled with
$ gcc -v -c -mcpu=v9 -I/usr/local/include/glib-2.0 testme2.c
Now I get missing glibconfig.h. But it is in /usr/local/lib/glib-2.0/include/glibconfig.h
Strangely glibconfig.h is the only file in /usr/local/lib/glib-2.0/include directory and more strangely it is not in /usr/local/include/glib-2.0 directory
Here are some more error messages...
from /usr/local/include/glib-2.0/glib.h:32,
from testme.c:40:
:34:24: glibconfig.h: No such file or directory
Here is an extract of /usr/local/include/glib-2.0/glib/gtypes.h
ifndef __G_TYPES_H__
define __G_TYPES_H__
include glibconfig.h
include glib/gmacros.h
G_BEGIN_DECLS
typedef char gchar;
typedef short gshort;
The question is how is GCC supposed to find glibconfig.h?
Glib installs a glib-2.0.pc file that describes all the options necessary to compile and link.
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
g++ -c `pkg-config --cflags glib-2.0` testme2.c
g++ -o testme2 testme.o `pkg-config --libs glib-2.0`
Note the use of pkg-config within backquotes.
$ pkg-config --cflags --libs glib-2.0
-I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -lglib-2.0
It is advisable to use pkg-config instead of manual configuration if .pc files for desired libraries exist and fall back to manual configuration if you have specific needs or no configuration for the library you are going to use exists. As you can see, pkg-config tells the compiler to put both glib-2.0 and glib-2.0/include directories into the search path as the root header searches in the global path.
You can infer pkg-config output into your compilation command via
gcc `pkg-config ...` ...
.pc files are usually installed in /usr/include/pkgconfig
There should be a program in the glib distribution called glib-config. If you run it with the --cflags argument, it will list all the gcc flags necessary. For example on my system:
$ glib-config --cflags
-I/usr/include/glib-1.2 -I/usr/lib/glib/include
As you can see, both directories are specified as include directories. There is also a --libs flags, which you can pass to your linker, so all the correct libs are linked, and the linker search path is correctly specified.