What I am trying to do is to have a dynamic library (lib_utils.so) that links libstdc++ statically and includes also other utility functions (created by me).
Then I want other binaries to use this library instead of libstdc++.
Seems stupid but I cannot deploy both lib_utils.so and libstdc++.so.6 to my customers and I try to combine them into one single library. I also want to avoid static linking with libstdc++ because I have 5 binaries that need libstdc++.
Is this possible?
Thank you
I managed to do it:
g++ -std=c++14 -Wl,-whole-archive /usr/lib/gcc/x86_64-linux-gnu/5/libstdc++.a -Wl,-no-whole-archive -shared -fPIC lib.cpp -o libviata.so
Then I loaded this library into a simple app and this app does not require libstdc++ anymore, cause it loads my custom library (which is quite big now, 2.1MB)
g++ -std=c++14 test.cpp -o test -L/home/tawfic/Desktop/test -lviata && ldd test
Related
I am having a piece of code (test.cpp) which depends on OpenSSL. I would like to create a static library with my piece of code, but it should really include already all dependencies. So that in the end I really only need to link against libtest.a file (also on other distros).
I have tried this
g++-7 -c -std=c++17 -static -L/usr/local/lib -lssl -lcrypto test.cpp -o test.o
ar crf libtest.a test.o
g++-5 main.cpp -std=c++11 libtest.a
but it still gives undefined references to OpenSSL stuff.
Don't judge me, my knowledge about compiling is equal 0, usually I let Qt handle this.
I would appreciate it if somebody could sketch how to accomplish it.
A .a file is a collection of .o files and no more. There is no possibility of linking.
Perhaps you could make a .so file (shared library) which does allow things to be statically linked to it.
Note: If you statically link OpenSSL and the person using your library also uses OpenSSL then it means their binary will be bloated by having two copies of it (linkers are not smart enough to optimize this), so it may be a good idea to also publish a version of your library that doesn't statically link OpenSSL.
Suppose you're developing a shared library libshared.so.
And you have a static library libstatic.a with some internal classes and functionality you need. You'd like to link it to your .so like this:
g++ -o libshared.so -shared myObj.o -lstatic
Also you have an executable.sh which will use your .so and dynamically open it in the runtime
dlopen("libshared.so", RTLD_NOW)
You know this executable was as well statically linked against libstatic.a (but you're not sure the version of the library is exactly the same as yours).
So the question is:
Is it safe and correct to statically link your libshared.so against libstatic.a when you know the same library is already used in executable.sh?
You should avoid linking a static library into a shared one.
Because a shared library should have position independent code (otherwise, the dynamic linker has to do too much relocation, and you lose the benefits of shared libraries), but a static library usually does not have PIC.
Read Drepper's paper: How to write a shared library
You build your library with
g++ -Wall -O -fPIC mySrc.cc -c -o myObj.pic.o
g++ -o libshared.so -shared myObj.pic.o -lotherlib
I'm trying to run the standard example from the SFML Library in Linux. I have download the Rep. from Github, build and install it with CMake. I have build 2 Libraries for static/shared debug, and 2 Libraries for static/shared Release.
The problem now, I don't know much about compiling in the Terminal. I use the commands I found on the SFML Website:
g++ -c test.cpp
g++ test.o -o sfml-app -lsfml-graphics -lsfml-window -lsfml-system
that works. I can run my SFML Application by ./sfml-app and double-click. But other people who (who have not installed SFML) using Linux cant. And I think it's because the compiler does not use the static libraries. Of course - how he could? It's not written in the command. But I also don't know how to write it.
The name of the static-release libraries is for example
libsfml-graphics-s.a
libsfml-window-s.a
libsfml-system-s.a
what must I write in g++, that he is using this libs when he link the stuff?
To link your program against the static versions of the libraries, you would do the following:
g++ test.o -o sfml-app libsfml-graphics-s.a libsfml-window-s.a libsfml-system-s.a
(Assuming, of course, that these files are in your local directory.)
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Can I mix static and shared-object libraries when linking?
I want to compile my app, linking statically only boost_system library. Other(glibc and etc) should be linked dynamically. How can i do it?
My command to compile dynamically:
g++ -o newserver server.cpp ... -lboost_system -std=c++0x
Command to compile statically:
g++ -static -o newserver server.cpp ... -pthread -lboost_system -std=c++0x
But this command link statically all! And app weights 2mb more!
Can you advice me what command to compile statically only boost lib?
Thanks!
Replace -lboost_system with -Wl,-Bstatic -lboost_system -Wl,-Bdynamic. The -Wl option sends the thing after it to the linker, in the order it appears on the command-line.
There are two solutions. You can specify -Bstatic and
-Bdynamic in the command line, each affects all of the
libraries which follow it. Or you can arrange it that the
static versions of the libraries which you want to be linked
statically are present in a directory which is searched before
the directory which contains the dynamic version. This allows
you to make some sort of global decision: you create the
directory once, and all users you do a -L for it before the
-L general will use the static versions.
In practice, I can't think of a case where you'ld want to link
the Boost libraries other than statically, so the simplest
solution might just be to remove the .so files. The only time
g++ will make a decision (and take into account the -Bstatic
and -Bdynamic) is if it finds both in the same directory. It
searches the directories in the given order, and when it finds
a directory which has either the static or the dynamic version
of the library, it stops. And if only one version is present,
it uses that one, regardless.
I have a shared library used by a another application beyond my control which requires *.so objects. My library makes use of sqlite3 which needs to be statically linked with it (I absolutely need a self-contained binary).
When I try to compile and link my library:
-fpic -flto -pthread -m64
-flto -static -shared
I end up with the following error:
/usr/bin/ld: /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbeginT.o: relocation R_X86_64_32 against `__DTOR_END__' can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbeginT.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
What is recompile with -fPIC related to? My code or CRT?
I have already tried to compile my object with -fPIC with the same result.
Thanks.
EDIT:
The problem does not seem to be related to SQLite3.
I wrote a simple one-line-do-nothing library which compiles and links like this:
g++ -c -fPIC -o bar.o bar.cpp
g++ -shared -o bar.so bar.o
but not like this:
g++ -c -fPIC -o bar.o bar.cpp
g++ -static -shared -o bar.so bar.o
The problem seems to be related to CRT (crtbeginT.o). Am I supposed to recompile GCC --with-pic or anything?
You shouldn't use the -static flag when creating a shared library, it's for creating statically linked executables.
If you only have a static version of the library, you can just link it in using -lsqlite3. But if there's both a dynamic version(.so) and a static version, the linker will prefer the dynamic one.
To instruct the linker to pick the static one, give the linker the -Bstatic flag, and make it switch back to dynamic linking for other stuff (like libc and dynamic runtime support) with -Bdynamic. That is, you use the flags:
-Wl,-Bstatic -lsqlite3 -Wl,-Bdynamic
Alternativly, you can just specify the full path of the .a file, e.g. /usr/lib/libsqlite3.a instead of any compiler/linker flags.
With the GNU ld, you can also use -l:libsqlite3.a instead of -lsqlite3. This will force the use of the library file libsqlite3.a instead of libsqlite3.so, which the linker prefers by default.
Remember to make sure the .a file have been compiled with the -fpic flag, otherwise you normally can't embed it in a shared library.
Any code that will somehow make its way into a dynamic library should be relocatable. It means that everything that is linked with your .so, no matter statically or dynamically, should be compiled with -fPIC. Specifically, static sqlite library should also be compiled with -fPIC.
Details of what PIC means are here: http://en.wikipedia.org/wiki/Position-independent_code
I had the same problem. Apparently -static is not the same as -Bstatic. I switched to -Bstatic and everything worked.