3 votes

Lier une bibliothèque statique à une bibliothèque partagée sans -fPIC

Je veux combiner des fichiers objets et une bibliothèque statique dans une bibliothèque partagée, mais la bibliothèque statique ne doit pas être exposée, elle est seulement référencée dans les fichiers objets qui vont dans la bibliothèque partagée. Je pense que dans ce cas, je n'ai pas besoin de compiler la bibliothèque statique avec -fPIC mais je ne sais pas comment indiquer au linker que le fait que je n'utiliserai pas les symboles de la bibliothèque statique. Pour illustrer mon problème, prenons les fichiers suivants :

Fichier foo.cpp :

#include "static.h"
using namespace std;

string version_info()
{
    return static_version_info();
}

Fichier static.cpp :

#include"static.h"
#include <vector>
using namespace std;
string static_version_info()
{
    std::vector<int> ivec;
    return to_string(ivec.size());
}

Fichier static.h :

#ifndef STATIC_H
#define STATIC_H
#include<iostream>
using namespace std;
std::string static_version_info();
#endif 

Ensuite, faites

$ g++ -c foo.cpp -o foo.o -fPIC
$ g++ -c static.cpp -o static.o
$ gcc-ar rcs static.a static.o
$ g++ -shared foo.o static.a
/usr/bin/ld: static.a(static.o): relocation R_X86_64_PC32 against symbol `_ZNSt6vectorIiSaIiEEC1Ev' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status

Question : Comment puis-je ajuster la dernière commande pour ne pas avoir d'erreur ? Est-ce possible ?

Notez que je ne veux pas compiler static.cpp avec -fPIC et je n'ai pas besoin des symboles (ici return_static_version_info() ) dans la bibliothèque partagée.

11voto

Basile Starynkevitch Points 67055

Vous ne pouvez pas (ou du moins vous ne devriez pas) lier une bibliothèque statique à une bibliothèque partagée .

Même si vous réussissez apparemment à lier une bibliothèque statique non-PIC libX.a dans une bibliothèque partagée libY.so le résultat n'aura pas de code indépendant de la position (il y aura donc beaucoup de relocalisations "inutiles" ou "gênantes").

Une bibliothèque partagée ne doit contenir que du code indépendant de la position (en pratique) ; mais une bibliothèque statique ne contient pas de PIC.

Je ne veux pas compiler static.cpp avec -fPIC

Mais vous devriez vraiment.

Lisez l'article de Drepper Comment écrire des bibliothèques partagées pour les détails.

BTW, certaines distributions de Linux (par exemple, Debian) fournissent une fonction libc6-pic donnant des fichiers tels que /usr/lib/x86_64-linux-gnu/libc_pic.a qui constituent une bibliothèque statique de code indépendant de la position. Vous pouvez l'utiliser pour étendre les fonctionnalités de votre système. libc.so.6 avec, par exemple, votre propre fonction (ou votre propre malloc etc...).

En pratique, il est préférable de recompiler le code de votre bibliothèque statique avec -fPIC ; BTW l'ISA x86-64 a été conçu pour faciliter le PIC.

Enfin, si vous vous souciez d'optimisations, il y a beaucoup de d'entre eux. Avez-vous envisagé de compiler et liaison avec gcc -O3 -fPIC -flto ? Dans certains cas, vous pouvez envisager -ffast-math (qui permet des optimisations par rapport au standard C), ou en remplaçant -O3 avec -Ofast .

Et vous devriez sûrement utiliser un compilateur GCC ou Clang (ou un compilateur propriétaire récent). icc ). Ce vieux (mentionné dans vos commentaires) est d'environ 4,7. Le CCG actuel à l'automne 2018 est de CCG 8 et CCG 9 est en cours d'élaboration (il devrait donc apparaître au printemps 2019). La version actuelle de Clang est Clang 7 . Les compilateurs font continuellement des progrès en matière d'optimisation.

Vous pouvez télécharger le source tarball de la dernière version de GCC ou de Clang et construisez-la sur votre ordinateur. C'est un bon moyen d'avoir une version récente de ces compilateurs, car les fabricants de distributions préfèrent souvent une variante plus ancienne de ceux-ci (qui est compatible même avec du code conforme non standard).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X