I compile my my OpenCV programs as follows:
g++ `pkg-config --cflags opencv --libs opencv` <filename>.cpp
It works perfectly on my computer. Can I complile the shared libraries alone with the program so that it can be run on other computers which doesnt have opencv on it? If so, how do I do it?
The program during compilation are dynamically linked to Shared Libraries (.so files) on our computer. The executable compiled use these shared libraries during run-time. But these shared libraries may not be present on other computers, hence might not be able to run the executable.
Solution to this will be to statically link Archive Libraries (.a files) instead of dynamically linking Shared Libraries. OpenCV does not distribute archive libraries as such. So one will have to compile archive library from the its source using cmake -DBUILD_SHARED_LIBS=OFF. This archive library can be used to create standalone executable.
Yes to some degree: lookup static linking. Your opencv copy must have .a versions of the libraries (not just .so you mention) and that is also true for any other dependencies.
No. You need to use static libraries.
Related
I was using the SDL2 library I installed with homebrew. I was just wondering if the libraries I linked were statistic or dynamic and how to tell with these package managers.
Homebrew installs both libraries for dynamic and static linkage. It installs also the useful utility sdl2-config. Run
sdl2-config --cflags --static-libs
--cflags Print the compiler flags that are necessary to compile a program or library that uses SDL.
--static-libs Print the linker flags that are necessary to statically link a program that uses SDL.
If you have not linked SDL like --static-libs showed, you have linked the shared SDL library.
FYI A library can not be dynamic, it is either a shared or a static library, for either dynamic (at runtime) or static (at compile time) link respectively.
I wrote a mini client-server game that works fine on my computers (running linux), since I installed SFML (and GCC 4.8) on both the Client and Server. Now I want to deploy the server application to another Linux that does not have SFML.
First I tried to dynamic link the SFML libraries used (network and system):
g++ server.cpp -o ServerLinux -std=c++11 -Os -lsfml-network -lsfml-system
But when I run the Server application it says it could not find sfml-network.so.2 and sfml-system.so.2 even though those 2 files are on the same folder of the binary.
I then static linked both libraries:
g++ -DSFML_STATIC server.cpp -o ServerLinux -std=c++11 -Os -lsfml-network-s -lsfml-system-s
And then when I run it says it could not find GLIBC_2.15 and GLIBC_2.17
Finally on my last try I static linked both libstc++ and libgcc:
g++ -DSFML_STATIC server.cpp -o ServerLinux -std=c++11 -Os -lsfml-network-s -lsfml-system-s -static-libstdc++ -static-libgcc
But I still get the same error (could not find GLIBC_2.15 and GLIBC_2.17).
Reading similar problems it seems that one should never static link glibc. But I don't know how to proceed, how can I deploy my mini game-server to a Linux box that does not have SFML?
Linux systems search for shared libraries by utilizing the LD_LIBRARY_PATH environment variable and they don't automatically look for binary files next to the application, as it is the case on Windows.
An very often used method of deploying with shared libraries, is to include them in an sub-directory or similar and instead of launching the application directly run a shell script that would add the directory with the libraries temporarily to ?LD_LIBRARY_PTH` and then start the application.
The other issue you're having is related to dependencies.
For shared libraries you'd not only have to provide the shared SFML libraries, but also provide the shared libraries of the dependencies, unless you can 100% guarantee that the target system will have the equal library version.
If you just build static libraries of SFML, they'll still point to shared runtime libraries and alike, thus if you don't provide the matching version with the application, it will simply fail to start, since it can't find the library.
If you link statically against the runtime libraries you wouldn't need to provide shared libraries for your application, but since the SFML libraries were still link dynamically against the runtime libraries, they request the shared libraries anyways.
So if you don't want to any shared library files any more, you'll need to link SFML statically against the runtime library (uncheck BUILD_SHARED_LIBS and check SFML_USE_STATIC_STD_LIBS).
Keep in mind that when linking statically, you'll need to link statically against all dependencies - -static might be useful.
I'm working on a c++ app on linux using g++. My app links in a shared library that exposes a simple API I need. This library internally references a large number of additional shared libs. I've had to find each and every one and add them to my Makefile to get them linked in.
I assume my app has to link to any of the libs the primary lib depends on. Is the only way around this linking requirement, having the primary lib compile in the static libs of all its dependencies? Does this apply to using the plug-in model via dlopen/dlsym?
ty
Is the only way around this linking requirement, having the primary lib compile in the static libs of all its dependencies?
No. The shared library could itself link to the shared libraries it depends on. Most linkers would pick up those libraries as well, and link your executable to those libraries without you mentioning them at the linker stage.
In your case, it sounds like the shared library did not link to the libraries it required. the ldd tool can be useful in this regard.
As an example, say you produce this shared library:
gcc -shared foo.o -o libfoo.so -lm
Now the libfoo.so is linked to the math library (libm). Any application linked to libfoo.so
would be linked to libm as well, i.e. you'd just have to do
gcc -o prog main.o -lfoo
If on the other hand the shared library was not linked to lib, but was produced with only
gcc -shared foo.o -o libfoo.so
You'd have to explicitly link to libm when linking your application:
gcc -o prog main.o -lfoo -lm
When you dlopen() a shared library, the runtime linker will load all the libraries that shared library was also linked against - unless they're already loaded. So - if a library you dlopen() is not linked against libraries it depends on, and your executable are not linked against those libraries either, dlopen() will fail (unless you specify RTLD_LAZY, in which case things fail later on)
I assume my app has to link to any of the libs the primary lib depends on.
It sounds as though either your app is using those symbols directly (not just indirectly through the API shared lib) or that shared lib hasn't been linked properly, so it wasn't linked to the libraries it depends on. If when that shared library was created its dependencies were linked to with -l then it would cause them to be linked to automatically when linking your app to the API lib.
Is the only way around this linking requirement, having the primary lib compile in the static libs of all its dependencies?
That's one way, but not the only way.
Does this apply to using the plug-in model via dlopen/dlsym?
As long as the plugins are correctly linked to the libs they depend on ... No, in that case the linker cannot possibly know what libs you will dlopen at run-time, so can't know what their dependencies will be, so you don't need to name them at link-time. It wouldn't be possible to without knowing in advance all the plugins that might get loaded.
If the plugin libraries weren't properly linked you'd get the same problem when trying to dlopen them.
I assume my app has to link to any of the libs the primary lib depends on. Is the only way around this linking requirement, having the primary lib compile in the static libs of all its dependencies?
Off course. There are no ways around : either static linking, or having libraries (correct versions, if not ABI compatible) in libraries run-time search path.
Does this apply to using the plug-in model via dlopen/dlsym?
No. For that, you need to have shared library in a path from which you want to load it.
i have a c program that relies on a second library whose compilation i can control. i want to be able to compile my program into a shared object library without it linking to the second library. in other words i want a single monolithic shared object library at the end. how can i do this?
if i separately compile the second library into a .so and include that as a dependency when compiling my program, i can see that i need that file when i run ldd on the binary.
You need to compile your second library as a .a (static library) and statically link that into your c program.
Static linking is when object files are linked at compile time and are part of the final binary, the resulting executable can be executed with no dependencies..
Shared libraries (.so) are linked at run time and must be available when you execute the binary that links them.
the gcc flag to link statically is: -static this will automatically search for .a files.
What radman said above.
http://www.network-theory.co.uk/docs/gccintro/gccintro_25.html
I have one shared object (a.so) which has statically linked (s.so). b.so also has a static link of s.so.
a.so does a dlopen on b.so , will "s.so" code be shared between the two?
The .so are built on gcc 4.1 on RedHat linux.
The s.so is compiled against a.so and b.so with -Bstatic and --no-whole-archive option.
Static library code (s.a) is never shared between binaries.
Whenever you link with a static library, the code for the functions you use is taken from the static library and placed in the executable or shared library you are producing. So in your case, each shared library will contain its own copy of code from the static library.