2010-05-18 23 views
81

Lorsque je compile quelque chose sur mon PC Ubuntu Lucid 10.04, il est lié à la glibc. Lucid utilise 2.11 de la glibc. Quand j'exécute ce binaire sur un autre PC avec une ancienne glibc, la commande échoue en disant qu'il n'y a pas de glibc 2.11 ...Comment puis-je créer un lien vers une version spécifique de la glibc?

Autant que je sache, la glibc utilise le versioning des symboles. Puis-je forcer gcc à se lier à une version de symbole spécifique?

Dans mon usage concret que je tente de compiler un ensemble d'outils de croix gcc pour ARM.

+44

Argh c'est l'un de ces problèmes linux vraiment ennuyeux comme où la solution est toujours « vous ne devriez pas le faire », ce qui signifie bien sûr « cela ne fonctionne pas et personne n'a encore fixé ». – Timmmm

+0

Les gens se sont plaints de DLL enfer sur Windows. Je me souviens de Linux * certains * aficionados essayant d'en faire un exemple particulièrement horrible du monde de Windows. Quand j'ai commencé à faire ce * développement * Linux il y a plus de dix ans, tout ce que je faisais, c'était enterrer mon visage entre mes mains. – 0xC0000022L

Répondre

54

Vous avez raison dans ce que glibc utilise versioning symbole. Si vous êtes curieux, l'implémentation des versions de symboles introduite dans la glibc 2.1 est décrite here et est une extension du schéma de versionnement des symboles de Sun décrit here.

Une option consiste à lier statiquement votre binaire. C'est probablement l'option la plus facile.

Vous pouvez aussi construire votre binaire dans un environnement de construction chroot, ou en utilisant un glibc nouvelle => glibc vieux compilateur croisé.

Selon le blog http://www.trevorpounds.comLinking to Older Versioned Symbols (glibc), il est possible de forcer un symbole d'être liés à une version plus ancienne tant qu'il est valide en utilisant le même .symver pseudo-op qui est utilisé pour définir versionnée symboles en premier lieu. L'exemple suivant est extrait du blog post.

L'exemple suivant utilise la realpath de glibc, mais assure qu'il est lié avec une ancienne 2.2.5 la version.

#include <limits.h> 
#include <stdlib.h> 
#include <stdio.h> 

__asm__(".symver realpath,[email protected]_2.2.5"); 
int main() 
{ 
    char* unresolved = "/lib64"; 
    char resolved[PATH_MAX+1]; 

    if(!realpath(unresolved, resolved)) 
     { return 1; } 

    printf("%s\n", resolved); 

    return 0; 
} 
+10

La glibc ne supporte pas la liaison statique - les programmes glibc liés statiquement ne fonctionnent pas sur les systèmes avec différentes versions de la libc. –

+2

'libc.a' de la glibc continue d'exister, la glibc supporte ceci dans * quelques * cas, bien que ce soit [non recommandé (Drepper)] (http://www.akkadia.org/drepper/no_static_linking.html). Vous aurez des problèmes avec les programmes non triviaux, en particulier tout ce qui utilise NSS (solution de contournement dans [la FAQ] (https://sourceware.org/glibc/wiki/FAQ)). –

15

Lien avec -static. Lorsque vous établissez un lien avec -static l'éditeur de liens intègre la bibliothèque dans l'exécutable, de sorte que l'exécutable sera plus grand, mais il peut être exécuté sur un système avec une version de glibc plus ancienne parce que le programme utilisera sa propre bibliothèque au lieu de celui de le système.

+47

Souvent, la raison pour laquelle vous voulez faire cela est parce que vous distribuez une application à code source fermé. Dans ce cas, il est souvent interdit d'établir une liaison statique pour des raisons de licence (ce qui nécessiterait la publication de tout votre code source). Vous devez donc être prudent avec -static. – Malvineous

+1

Pendant ce temps, au moins on peut souvent utiliser musl-libc, mais avec les programmes C++, les choses peuvent devenir plus compliquées, donc spécifier une version de symbole peut être nécessaire. – 0xC0000022L