web-dev-qa-db-fra.com

Compiler avec une ancienne libc (version `GLIBC_2.14 'introuvable)

Je dois compiler un programme sur un Ubuntu actuel (12.04). Ce programme devrait ensuite s'exécuter sur un cluster utilisant CentOS avec un noyau plus ancien (2.6.18). Je ne peux pas compiler directement sur le cluster, malheureusement. Si je compile et copie le programme sans aucune modification, j'obtiens le message d'erreur "noyau trop ancien".

D'après ce que j'ai compris, la raison n'est pas tant la version du noyau, mais la version de libc qui a été utilisée pour la compilation. J'ai donc essayé de compiler mon programme en liant dynamiquement la libc du cluster et en liant statiquement tout le reste.

Recherche

Il y a déjà beaucoup de questions à ce sujet sur SO mais aucune des réponses n'a vraiment fonctionné pour moi. Alors voici mes recherches sur ce sujet:

  • Cette question explique la raison du message trop ancien du noyau
  • Cette question est similaire mais plus spécialisée et n'a pas de réponses
  • Lier statiquement comme proposé ici n'a pas fonctionné car la libc est trop ancienne sur le cluster. Une réponse mentionne également la construction à l'aide de l'ancienne libc, mais n'explique pas comment procéder.
  • ne façon est de compiler dans un VM exécutant un ancien OS. Cela a fonctionné mais est compliqué. J'ai également lu cela vous ne devez pas lier la libc statiquement
  • Apparemment it est possible pour compiler pour une version libc différente avec l'option -rpath mais cela n'a pas fonctionné pour moi (voir ci-dessous)

État actuel

J'ai copié les fichiers suivants du cluster dans le répertoire /path/to/copied/libs

  • libc-2.5.so
  • libgcc_s.so.1
  • libstdc ++. so.6

et je compile avec les options -nodefaultlibs -Xlinker -rpath=/path/to/copied/libs -Wl,-Bstatic,-lrt,-lboost_system,-lboost_filesystem -Wl,-Bdynamic,-lc,-lstdc++,-lgcc_s

La sortie de ldd sur le binaire compilé est

mybin: /path/to/copied/libs/libc.so.6: version `GLIBC_2.14' not found (required by mybin)
mybin: /path/to/copied/libs/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by mybin)
linux-vdso.so.1 =>  (0x00007ffff36bb000)
libc.so.6 => /path/to/copied/libs/libc.so.6 (0x00007fbe3789a000)
libstdc++.so.6 => /path/to/copied/libs/libstdc++.so.6 (0x00007fbe37599000)
libgcc_s.so.1 => /path/to/copied/libs/libgcc_s.so.1 (0x00007fbe3738b000)
/lib64/ld-linux-x86-64.so.2 (0x00007fbe37bf3000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fbe37071000)

Je suis quelque peu confus par l'erreur, car il utilise le bon chemin (c'est-à-dire la libc du cluster) mais se plaint toujours d'une version manquante de la glibc. Lors de l'exécution de ldd sur le cluster, il renvoie not a dynamic executable et l'exécution du binaire entraîne les deux mêmes erreurs mentionnées ci-dessus. Il semble également que d'autres bibliothèques soient incluses (linux-vdso.so.1, ld-linux-x86-64.so.2 et libm.so.6). Dois-je également utiliser les anciennes versions?

Alors maintenant, j'ai deux questions principales:

  • Est-ce même la bonne approche ici?
  • Si oui: comment lier correctement l'ancienne libc?
37
Flogo

Voir cette réponse.

Est-ce même la bonne approche ici

Non: vous ne pouvez pas utiliser des versions incompatibles de glibc comme le fait votre commande de lien. Vous avez utilisé crt0.o et ld-linux.so de nouvelle (installée par le système) libc, mais libc.so.6 à partir d'une ancienne libc (copiée du cluster). Cela ne fonctionnera tout simplement pas.

10
Employed Russian

-rpath définit la balise DT_RPATH mais ne dit pas à l'éditeur de liens de rechercher les bibliothèques, vous voulez -L pour ça.

2
Jonathan Wakely