Link with static library in 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;
}

Читайте также:  Linux enigma2 спутниковый ресивер

// 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.

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.

Читайте также:  Системный вызов open linux

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 

Источник

Thanks for the replies! Turns out the problem was due to link order. Apparently, if you use a library which in turn has other library dependencies, those other dependencies must be listed after the library, not before as I had been doing. Learned something new!

Doesn’t answer the question. Yes, it solves some specific problem which perhaps prompted you to ask this general question. Unfortunately, most people will come here to get an answer for the question as asked (and the sub-questions).

Incidentally, I googled this because I thought I was linking incorrectly, but it turns out the order was wrong. So, this ended up being the answer for me, too

Читайте также:  Ошибка нет доверия сертификату astra linux

Have you cared to indicate to GCC the path of your library (using -L) ? By using -l solely, GCC will only be able to link libraries available in standard directories.

Yes, the paths to each library are provided using -L, before the corresponding -l flag. GCC can find the library, but gives a large number of undefined reference errors from within the library.

The correct way to link a static library is using -l, but that only works if the library can be found on the search path. If it’s not then you can add the directory to the list using -L or name the file by name, as you say.

The same is true for shared libraries, actually, although they’re more likely to be found, perhaps.

What’s the difference though, between linking the static library with -l and putting in on the link line without any -l prefix, as .o are? See the questions the OP asks at the end of his question.

The reason is historical. The «ar» tool was original the file archive tool on PDP11 unix, though it was later replaced entirely by «tar» for that purpose. It stores files (object files, in this case) in a package. And there’s a separate extension containing the symbol table for the linker to use. It’s possible if you are manually managing files in the archive that the symbol table can get out of date.

The short answer is that you can use the «ranlib» tool on any archive to recreate the symbol table. Try that. More broadly, try to figure out where the corrupt libraries are coming from and fix that.

Linked

Hot Network Questions

Subscribe to RSS

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.14.43533

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

Источник

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