Comment appliquer l'option-fvisibility aux symboles dans les bibliothèques statiques?

, j'ai une bibliothèque partagée projet qui est construit à partir de 4 bibliothèques statiques (.a) et un objet (.o) fichier. J'essaie d'ajouter l'option -fvisibility=hidden pour limiter les symboles dans la sortie à ceux que je marque dans la source avec un _ _ attribut__.

J'ai ajouté l'option -fvisibility=hidden aux options de compilation pour le projet .so (qui couvre le fichier .o) et pour les projets .a.

Les symboles dans le fichier objet sont supprimés comme prévu du .so final. Cependant, l' les symboles des projets .a sont toujours dans le fichier .so final. L'ajout de l'option -fvisibility=hidden à la commande .so link n'a aucun effet.

Ce que je fais mal?

Mon but ici est de supprimer de la {[4] } tous les symboles sauf les fonctions d'interface à la bibliothèque.

EDIT: j'ai en fait utilisé une carte de version pour résoudre ce problème pour l'instant. Cependant, il nécessite une maintenance continue du script de version car les symboles externes changent. Réponse acceptée a une meilleure idée.

36
demandé sur jww 2010-02-08 17:23:48

3 réponses

Fondamentalement, la visibilité est gérée pendant la liaison, et l'éditeur de liens ne semble pas l'imposer aux archives statiques. Une question connexe (mais pas un doublon) a été posée sur SO ici .

Ce que je vous conseille de faire est de remplacer votre étape de liaison: gcc -shared -o mylib.so foo.o libbar.a dans un processus en deux étapes où vous récupérez les fichiers objet:

  • ar x libbar.a (éventuellement dans un répertoire vide approprié)
  • gcc -fvisibility=hidden -shared -o mylib.so foo.o tempdir/*.o
29
répondu F'x 2017-05-23 12:34:10

Passez simplement -Wl,--exclude-libs,ALL à gcc

Cela indiquera à l'éditeur de liens de transformer tous les symboles dans les bibliothèques statiques en cachés.

--exclude-libs accepte également une liste d'archives (c'est-à-dire des noms de bibliothèques statiques) pour une granularité plus fine sur laquelle les bibliothèques doivent cacher les symboles.

Remarque: cela ne fonctionnera que dans les systèmes utilisant GNU binutils (par exemple Linux) ou avec un éditeur de liens supportant --exclude-libs (par exemple, cela ne fonctionnera pas avec le ld64 D'OSX)

53
répondu fons 2015-04-12 21:42:43

Ceci est une réponse au problème pour OS X.

Le Mac {[1] }ne prend pas en charge --exclude-libs, mais il prend en charge -exported_symbol symet l'applique aux fichiers objet dans les bibliothèques statiques. Et lorsque vous filtrez vers une API publique, la liste blanche est assez petite pour l'épeler.

J'ai fini avec ce qui suit dans mon Makefile pour générer un drapeau -Wl,-exported_symbol,_api_func_1 pour chaque symbole exporté:

SYMBOLS   = api_func_1 api_func_2 api_func_3 api_func_4
SYMBOLS   += api_func_5 # add more as necessary
COMMA     = ,
LDFLAGS   += $(addprefix -Wl$(COMMA)-exported_symbol$(COMMA)_,$(SYMBOLS))

# ...

libmyapi.so: # ...
    $(CC) -shared -o $@ ... $(LDFLAGS)

Alors vous pouvez if-gate entre cette version des drapeaux et la version GNU LD après détection de l'éditeur de liens le système.

4
répondu Riking 2018-05-30 15:45:08