2010-02-08 3 views
33

J'ai un projet de bibliothèque partagée qui est construit à partir de 4 bibliothèques statiques (.a) et d'un fichier objet (.o). 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 __attribute__.Comment appliquer l'option gcc -fvisibility aux symboles dans les bibliothèques statiques?

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

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

Qu'est-ce que je fais mal?

Mon but ici est d'enlever du .so tous les symboles sauf les fonctions d'interface à la bibliothèque.

EDIT: J'ai effectivement utilisé un version map pour résoudre ce problème pour le moment. Cependant, cela nécessite une maintenance continue du script de version lorsque les symboles externes changent. La réponse acceptée a une meilleure idée.

+0

Plate-forme non mentionné, mais une solution pour Ce faisant sous iOS/OS X voir http://stackoverflow.com/a/18949281/316487 – bleater

Répondre

24

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

Ce que je vous conseille de le faire est de remplacer l'étape qui relie: gcc -shared -o mylib.so foo.o libbar.a en deux processus étapes où vous obtenez les fichiers d'objet:

  • ar x libbar.a (peut-être dans un répertoire approprié, vide)
  • gcc -fvisibility=hidden -shared -o mylib.so foo.o tempdir/*.o
+0

Belle idée. Convient à ce que j'ai appris par l'expérimentation. Peut essayer ceci plus tard. –

46

Il suffit de passer -Wl,--exclude-libs,ALL gcc

Ceci va dire le lin Ker pour transformer tous les symboles dans les bibliothèques statiques à caché.

--exclude-libs--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 des symboles.

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

+1

Merci beaucoup! Je l'utilise avec -fvisibility = caché et exporter sélectivement uniquement l'API publique (IMO seule l'approche de la whitelisting est sensée spécialement quand il s'agit de bibliothèques statiques externes au projet). Peut-être que si vous pouvez ajouter des tags, le futur de Googler sera reconnaissant. – dashesy

+2

Je crois que c'est -Wl, - exclude-libs = ALL (remplacez la deuxième virgule par un =) –

+0

Malheureusement, cela ne fonctionne pas sur Mac OS puisque ld ne connait pas cette option sous Mac OS. – rsp1984

Questions connexes