OVH Cloud OVH Cloud

probleme de dylib encore plus precis

4 réponses
Avatar
Saïd
Bonjour,

Soit deux fichiers c appeles malib.c et monprog.c
malib.c:
---------
extern int reponse;
int demander_a_librairie(void)
{
return reponse;
}
-------

monprog.c:
---------
#include <stdio.h>

int demander_a_librairie(void);
int reponse;

int main(void)
{
reponse=42;
printf("la reponse est %d\n",demander_a_librairie());
}
---------
Sous linux je peux creer une librairie partagee a partir de malib.c

ladjal/kahina - bin/sostuff $ gcc -c -o malib.o malib.c
ladjal/kahina - bin/sostuff $ ld -shared -soname libmalib.so -o libmalib.so
malib.o
ladjal/kahina - bin/sostuff $ gcc -L. -o monprog monprog.c -lmalib
ladjal/kahina - bin/sostuff $ LD_LIBRARY_PATH=. ./monprog
la reponse est 42

Autrement dit libmalib.so connait un symbole qui lui est externe et elle
attend qu'il soit defini par le programme qui l'appelle.

Sous Mac OS X (10.3) je ne peux meme pas creer la libraire libmalib.dylib:
brian-~/bin/sostuff $ gcc -c -o malib.o malib.c
brian-~/bin/sostuff $ gcc -dynamiclib -install_name libmalib.dylib -o
libmalib.dylib malib.o
ld: Undefined symbols:
_reponse
/usr/bin/libtool: internal link edit command failed

Est-ce qu'il y a moyen de creer des librairies qui ne deinissent pas tous
leurs symboles sous Mac OS X? une idee pour contourner le probleme?

Toute aide serait tres appreciable. Merci.

--
Saïd.

4 réponses

Avatar
Saïd
Matt :
<http://developer.apple.com/technotes/tn2002/tn2071.html> (§ "Shared
Libraries, Bundles and Linker")

et

<http://www.metapkg.org/wiki/12>
<http://www.metapkg.org/wiki/15> (la dernière QR est pertinente pour
l'erreur de ld "Undefined symbols").



Merci, mais tout ceci n'explique pas pourquoi une librairie dynamique ne
peut-etre creee si elle fait appelle a un symbole "extern".

Je vais me rabattre sur les librairies statiques. Mon exemple marche dans
ce cas-la.

--
Saïd.
C programmers never die - they're just cast into void.

Avatar
Schmurtz
Saïd wrote:

Merci, mais tout ceci n'explique pas pourquoi une librairie dynamique ne
peut-etre creee si elle fait appelle a un symbole "extern".


Tu peux utiliser des symboles "extern" dans une bibliothèque, mais il
faut elle même qu'elle soit liée avec la bibliothèque qui contient la
définition effective des symboles "extern".

La raison est décrite ici :
<http://developer.apple.com/releasenotes/DeveloperTools/TwoLevelNamespace
s.html>

Dans ton exemple, on obtiendrai des dépendances circulaires, ce qui
n'est pas possible à réaliser dans MacOS X (où alors en se cassant bien
la tête).

Pour contourner le problème :

- mettre reponse dans malib

- passer un pointeur vers reponse en paramètre à demander_a_librairie ou
à une fonction d'initialisation de malib qui stocke le pointeur dans une
variable global de malib :

malib.c:
---------
int* reponse;
void init(int* rep)
{
reponse = rep;
}
int demander_a_librairie(void)
{
return *reponse;
}
-------

monprog.c:
---------
#include <stdio.h>

init(int* rep);
int demander_a_librairie(void);
int reponse;

int main(void)
{
init(&reponse);
...
reponseB;
printf("la reponse est %dn",demander_a_librairie());
}
---------

--
Schmurtz

Avatar
Saïd
Schmurtz :
Saïd wrote:

Merci, mais tout ceci n'explique pas pourquoi une librairie dynamique ne
peut-etre creee si elle fait appelle a un symbole "extern".


Tu peux utiliser des symboles "extern" dans une bibliothèque, mais il
faut elle même qu'elle soit liée avec la bibliothèque qui contient la
définition effective des symboles "extern".

La raison est décrite ici :
<http://developer.apple.com/releasenotes/DeveloperTools/TwoLevelNamespace
s.html>

Dans ton exemple, on obtiendrai des dépendances circulaires, ce qui
n'est pas possible à réaliser dans MacOS X (où alors en se cassant bien
la tête).

Pour contourner le problème :

- mettre reponse dans malib

- passer un pointeur vers reponse en paramètre à demander_a_librairie ou
à une fonction d'initialisation de malib qui stocke le pointeur dans une
variable global de malib :



C'est ce qu'il faudrait faire. Mais dans le cas qui m'interesse, il faudrait
revoir plein de choses. Le programme qui definit la variable (equivalente de
int reponse) est generé par un autre programme a partir d'un fichier C. Le
programme de taduction est généré par flex/yacc...

L'autre solution serait de ne jamais creer la librairie et de linker tous
les .o au moment ou le programme qui "appelle" la librairie est connu.

--
Saïd.
C programmers never die - they're just cast into void.


Avatar
Martin Costabel
Saïd wrote:

Merci, mais tout ceci n'explique pas pourquoi une librairie dynamique ne
peut-etre creee si elle fait appelle a un symbole "extern".


Mais elle peut, et c'est expliqué dans le wiki cité:
Tu as 2 possibilités, soit tu utilises

setenv MACOSX_DEPLOYMENT_TARGET 10.3
gcc -dynamiclib -undefined dynamic_lookup -install_name libmalib.dylib
-o libmalib.dylib malib.o

soit tu utilises

gcc -dynamiclib -flat_namespace -undefined suppress -install_name
libmalib.dylib -o libmalib.dylib malib.o


Dans les 2 cas, ça marche. Pas besoin de librairies statiques.

--
Martin