Static linked library linux

@texasbruce why do you consider it a bad practice? There are reasons for and against of course, but not to the point where you should exclude a valid approach.

@MooingDuck If a dynamic library was previously loaded into memory by another program, then the loading time would be almost zero for the new program

2 Answers 2

Since nobody else has come up with an answer yet, I will give it a try. Unfortunately, I don’t know that Code::Blocks IDE so my answer will only be partial.

1 How to Create a Statically Linked Executable with GCC

This is not IDE specific but holds for GCC (and many other compilers) in general. Assume you have a simplistic “hello, world” program in main.cpp (no external dependencies except for the standard library and runtime library). You’d compile and statically link it via:

    Compile main.cpp to main.o (the output file name is implicit):

Especially at the beginning, I strongly recommend doing such things “by hand” as it will help get a better understanding of the build tool-chain.

As a matter of fact, the above two commands could have been combined into just one:

$ g++ -Wall -o main main.cpp -static 

Any reasonable IDE should have options for specifying such compiler / linker flags.

2 Pros and Cons of Static Linking

Reasons for static linking:

  • You have a single file that can be copied to any machine with a compatible architecture and operating system and it will just work, no matter what version of what library is installed.
  • You can execute the program in an environment where the shared libraries are not available. For example, putting a statically linked CGI executable into a chroot() jail might help reduce the attack surface on a web server.
  • Since no dynamic linking is needed, program startup might be faster. (I’m sure there are situations where the opposite is true, especially if the shared library was already loaded for another process.)
  • Since the linker can hard-code function addresses, function calls might be faster.
  • On systems that have more than one version of a common library (LAPACK, for example) installed, static linking can help make sure that a specific version is always used without worrying about setting the LD_LIBRARY_PATH correctly. Obviously, this is also a disadvantage since now you cannot select the library any more without recompiling. If you always wanted the same version, why would you have installed more than one in the first place?
Читайте также:  Read linux usb on windows

Reasons against static linking:

  • As you have already mentioned, the size of the executable might grow dramatically. This depends of course heavily on what libraries you link in.
  • The operating system might be smart enough to load the text section of a shared library into the RAM only once if several processes need the library at the same time. By linking statically, you void this advantage and the system might run short of memory more quickly.
  • Your program no longer profits from library upgrades. Instead of simply replacing one shared library with a (hopefully ABI compatible) newer release, a system administrator will have to recompile and reinstall every program that uses it. This is the most severe drawback in my opinion. Consider for example the OpenSSL library. When the Heartbleed bug was discovered and fixed earlier this year, system administrators could install a patched version of OpenSSL and restart all services to fix the vulnerability within a day as soon as the patch was out. That is, if their services were linking dynamically against OpenSSL. For those that have been linked statically, it would have taken weeks until the last one was fixed and I’m pretty sure that there is still proprietary “all in one” software out in the wild that did not see a fix up to the present day.
  • Your users cannot replace a shared library on the fly. For example, the torsocks script (and associated library) allows users to replace (via setting LD_PRELOAD appropriately) the networking system library by one that routes their traffic through the Tor network. And this even works for programs whose developers never even thought of that possibility. (Whether this is secure and a good idea is subject of an unrelated debate.) An other common use-case is debugging or “hardening” applications by replacing malloc and the like with specialized versions.

In my opinion, the disadvantages of static linking outweigh the advantages in all but very special cases. As a rule of thumb: link dynamically if you can and statically if you have to.

A Addendum

As Alf has pointed out (see comments), there is a special GCC option to selectively link in the C++ standard library statically but not link the whole program statically. From the GCC manual:

-static-libstdc++

When the g++ program is used to link a C++ program, it normally automatically links against libstdc++. If libstdc++ is available as a shared library, and the -static option is not used, then this links against the shared version of libstdc++. That is normally fine. However, it is sometimes useful to freeze the version of libstdc++ used by the program without going all the way to a fully static link. The -static-libstdc++ option directs the g++ driver to link libstdc++ statically, without necessarily linking other libraries statically.

Источник

Читайте также:  Configure iscsi target linux

Static Library

A static library is basically an archive (like a zip file) of object files, which are compiled from the .c/.cpp source code.

(The -c switch means: Compile and assemble, but do not link.)

Thus, we get two files test1.o and test2.o.

Now, we can use ar to put these object files together into a single static library.

ar rsv testlib.a test1.o test2.o

Now the testlib.a contains test1.o and test2.o.

gcc -o test.out test.c testlib.a

Alternatively, you could use the explicity linking options to link the static library (-L switch specifies the static library path and -l followed by the name of the static library):

gcc -o test.out test.c -L. -ltestlib

The static library is distributed with a function declaration header files .h, so that you know how to invoke them and the compiler takes care of them e.g. linking .a static libraries into your executables.

The Dynamic Link Library (DLL) is stored separately from the target application and shared among different applications, compared to Static Library. The DLL is the file extension on Windows while on Linux, it is *.so (Shared Object).

The .so/.dll can be loaded right before the application starts or during the application’s runtime. On Windows, the Win32 API LoadLibrary is used while on Linux gcc compiler, the dlopen function is used.

gcc -shared -o libhello.so -fPIC hello.c
g++ Application.cpp -o Application -I/home/wjw/dev/Youtube/OpenGL/Dependencies/GLFW/include -L/home/wjw/dev/Youtube/OpenGL/Dependencies/GLFW/lib -lglfw
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/dev/Youtube/OpenGL/Dependencies/GLFW/lib

Calling C++ Shared Library from Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// https://helloacm.com
extern «C»
{
// A function adding two integers and returning the result
int SampleAddInt(int i1, int i2)
{
return i1 + i2;
}

// A function doing nothing 😉
void SampleFunction1()
{
// insert code here
}

// A function always returning one
int SampleFunction2()
{
// insert code here

return 1;
}
}
g++ -Wall -O3 -shared TestLib.c -o TestLib.so
#!/usr/bin/python

import ctypes

def main():
TestLib = ctypes.cdll.LoadLibrary(‘/home/wjw/misc/cpp_static_dynamic_lib/TestLib.so’)
print(TestLib.SampleAddInt(1, 2))

if __name__ == ‘__main__’:
main()

Источник

What do you mean by statically linked? Do you want your executable to be distribuited without requiring the .so?

6 Answers 6

You need the static version of the library to link it.

A shared library is actually an executable in a special format with entry points specified (and some sticky addressing issues included). It does not have all the information needed to link statically.

You can’t statically link a shared library (or dynamically link a static one).

The flag -static will force the linker to use static libraries (.a) instead of shared (.so) ones. But static libraries aren’t always installed by default, so you may have to install the static library yourself.

Читайте также:  Команды linux установить дату

Another possible approach is to use statifier or Ermine. Both tools take as input a dynamically linked executable and as output create a self-contained executable with all shared libraries embedded.

What information does the static library have, so that it can be statically linked, that the dynamic library doesn’t have?

If you want to link, say, libapplejuice statically, but not, say, liborangejuice, you can link like this:

gcc object1.o object2.o -Wl,-Bstatic -lapplejuice -Wl,-Bdynamic -lorangejuice -o binary 

There’s a caveat — if liborangejuice uses libapplejuice , then libapplejuice will be dynamically linked too.

You’ll have to link liborangejuice statically alongside with libapplejuice to get libapplejuice static.

And don’t forget to keep -Wl,-Bdynamic else you’ll end up linking everything static, including libc (which isn’t a good thing to do).

Isn’t there a way to tell gcc directly what to link statically, and not to bypass him and talk with the linker?

@EugeneBujak: The caveat does not apply on my system. Example: gcc -o main main.cc -Wl,-rpath=. -Wl,-Bdynamic -lB -Wl,-Bstatic -lA -Wl,-Bdynamic -L. libB uses libA, it linked and ldd does not show a reference to libA. The executable works fine. Tested with g++ 4.7.3.

An indirect (nested), static, dependency of a direct, dynamic, dependency does not itself become dynamically linked.

Consider the following: binA depends on libB.so which depends on libC.a As others have already stated, .so’s are themselves executables, so when a shared object is linked, any static library dependents are processed by the linker much the same as if an executable was being linked: the only symbols pulled in from the .a static lib are those referenced (and unresolved) by the .so. This means that if binA references a symbol in libC.a, not referenced anywhere in libB.so, then even if binA links to libB.so, that symbol will be undefined (unless -Wl,—whole-archive is used when linking libB.so).

Yeah, I know this is an 8 year-old question, but I was told that it was possible to statically link against a shared-object library and this was literally the top hit when I searched for more information about it.

To actually demonstrate that statically linking a shared-object library is not possible with ld ( gcc ‘s linker) — as opposed to just a bunch of people insisting that it’s not possible — use the following gcc command:

gcc -o executablename objectname.o -Wl,-Bstatic -l:libnamespec.so 

(Of course you’ll have to compile objectname.o from sourcename.c , and you should probably make up your own shared-object library as well. If you do, use -Wl,—library-path,. so that ld can find your library in the local directory.)

The actual error you receive is:

/usr/bin/ld: attempted static link of dynamic object `libnamespec.so' collect2: error: ld returned 1 exit status 

Источник

Оцените статью
Adblock
detector