# Grundlagen in C lernen - Shared Libraries.

## musv

Hallo, 

ich arbeite mich grad etwas in C/C++ ein. Dabei bin ich jetzt an die Stelle mit den Shared Libs gekommen. 

Tutorial: http://www.adp-gmbh.ch/cpp/gcc/create_lib.html

Das Problem hab ich beim Einbinden der dynamischen Lib:

```
ldd dynamically_linked
```

zeigt mir die Shared Lib nicht an. Und wenn ich die zuvor statische statische Lib (libmean.a) umbenenn, kann ich die main.c auch nicht mehr compilieren.

```
gcc main.c -o dynamisch -L. -lmean

/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.4/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lmean

collect2: ld gab 1 als Ende-Status zurück

```

Wo liegt mein Denkfehler?

----------

## franzf

Beim statisch linken ist es jedenfalls ein Lesefehler, kein Denkfehler  :Wink: 

Dir fehlt das "static" beim kompilieren und linken des executables.

// edit: Ups

seh grad erst das "umbenenn"; Das geht nicht, dynamisch erstellte lib ist was ganz anderes als nen statische, die kannst du nicht einfach umbenennen und fertig! Merkst du ja schon an den unterschiedlichen Befehlen, die man zum Erstellen braucht  :Very Happy: 

//

Was aber mit dem dynamisch linken ist, kann ich nicht genau sagen, da ich faule Sau nie selber Makefiles schreib, sondern die Arbeit an Makefilegeneratoren (vornehmlich cmake) delegiere  :Wink: 

Ein wenig spielen hat aber ergeben, dass die unterschiedlichen Angaben in "-soname, libmean.so.1" und tatsächlicher lib "libmean.so.1.0.1" etwas Probleme schafft. Nehm ich die Zeile mit dem "-soname" raus, linkt das Programm, in ldd ist das auch zu sehen. Dummerweise kommt aber dann kein Output mehr...

Hier noch ein kurzes CMakeLists.txt, wenn dich interessiert, wie cmake die ganzen Kommandos ausführen lässt:

```
add_library(mean SHARED calc_mean.c)

set_target_properties(mean PROPERTIES VERSION 1.0.1)

add_executable(dynamically main.c)

target_link_libraries(dynamically mean)
```

```
$ cmake .

$ VERBOSE=1 make
```

da siehst du dann die einzelnen Befehle samt Parametern.

----------

## SinoTech

 *musv wrote:*   

> Hallo, 
> 
> ich arbeite mich grad etwas in C/C++ ein. Dabei bin ich jetzt an die Stelle mit den Shared Libs gekommen. 
> 
> Tutorial: http://www.adp-gmbh.ch/cpp/gcc/create_lib.html
> ...

 

Das Problem ist ganz einfach das deine Bibliothek eine Versionsnummer am Ende hat. Gibst du dem Compiler das Flag -lmean mit, sucht der Linker erst nach einer Bibliothek "libmean.so" und wenn er die nicht findet nach "libmean.a" (also die statische Variante). Da es die "libmean.so" bei dir nicht gibt, benutzt er die statische Bibliothek. Deshalb taucht die Bibliothek auch nicht in der Ausgabe von ldd auf.

Bei der Option "-Wl,-soname,SO_NAME" musst du ein bisschen aufpassen. Normalerweise probiert dein fertiges Programm beim starten die Bibliotheken zu laden, gegen die es gelinkt wurde. Die Namen der Bibliotheken entsprechen dabei den Dateinamen beim linken. Mit der Option "-Wl,-soname,..." kannst du beim erstellen der shared library einen beliebigen Namen angeben, dieser wird als Attribute in ihr gespeichert. Wenn du gegen diese Bibliothek linkst, ignoriert dein Programm den Dateinamen dieser Bibliothek und benutzt stattdessen den Namen der in diesem Attribut gespeichert ist.

Du hast in dem Tutorial also eigentlich zwei Probleme:

1. Die shared library heißt "libmean.so.1.0.1" statt "libmean.so", der Linker kann sie also nicht finden.

2. Wenn du die shared library umbenennst ist zwar der Linker zufrieden, dein Programm startet aber nicht weil es nach der Bibliothek "libmean.so.1" sucht (der Name wurde über die Option "-Wl,-soname,..." angegeben).

Also entweder zum erstellen der shared library diese Zeile benutzen:

```

gcc -shared -o libmean.so  calc_mean.o

```

oder symbolische Links erstellen so das alle zufrieden sind  :Wink: :

```

$ ln -s libmean.so.1.0.1 libmean.so.1

$ ln -s libmean.so.1.0.1 libmean.so

$ ls -l libmean*

-rw-r--r-- 1 sinotech wheel 1598 Jun 27 01:24 libmean.a

lrwxrwxrwx 1 sinotech wheel   16 Jun 27 01:27 libmean.so -> libmean.so.1.0.1

lrwxrwxrwx 1 sinotech wheel   16 Jun 27 01:56 libmean.so.1 -> libmean.so.1.0.1

-rwxr-xr-x 1 sinotech wheel 7849 Jun 27 01:26 libmean.so.1.0.1

```

Cheers,

Sino

----------

## musv

Vielen Dank, hab dadurch wieder eine Menge begriffen.

----------

## mv

Übrigens macht man die Links normalerweise natürlich nicht händisch. Dazu gibt es autools (hier insbesondere: libtool) oder als Minimum: ldconfig -N

----------

## musv

Das ist durchaus richtig. Mir ist es allerdings wichtig, dass ich wenigstens weiß, wie es händisch funktioniert. Wenn die IDE mit autoconf durchrattert, hab ich hinterher sonst keine Ahnung, warum irgendeine Lib nicht gefunden wurde.

----------

