Bibliothèques glibc multiples sur un seul hôte

bibliothèques glibc multiples sur un seul hôte

mon serveur linux (SLES-8) a actuellement glibc-2.2.5-235, mais j'ai un programme qui ne fonctionnera pas sur cette version et nécessite glibc-2.3.3.

est-il possible d'avoir plusieurs glibcs installés sur le même hôte?

C'est l'erreur que j'obtiens lorsque j'exécute mon programme sur l'ancienne bibliothèque glibc:

./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./myapp)
./myapp: /lib/i686/libpthread.so.0: version `GLIBC_2.3.2' not found (required by ./myapp)
./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./libxerces-c.so.27)
./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by ./libstdc++.so.6)
./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./libstdc++.so.6)

donc j'ai créé un nouveau répertoire appelé newglibc et copié les fichiers suivants:

libpthread.so.0
libm.so.6
libc.so.6
ld-2.3.3.so
ld-linux.so.2 -> ld-2.3.3.so

et

export LD_LIBRARY_PATH=newglibc:$LD_LIBRARY_PATH

mais je reçois une erreur:

./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libpthread.so.0)
./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by libstdc++.so.6)
./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libm.so.6)
./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by ./newglibc/libc.so.6)
./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libc.so.6)

il semble donc qu'ils sont toujours en lien avec /lib et ne répondent pas à l'endroit où je les ai mis?

Merci

117
demandé sur dogbane 2009-05-11 12:20:37

10 réponses

il est très possible d'avoir plusieurs versions de glibc sur le même système (nous le faisons tous les jours).

cependant, vous devez savoir que glibc se compose de nombreux morceaux (plus de 200 bibliothèques partagées) qui tous doivent correspondre. Une des pièces est ld-linux.alors?2, et it must match libc.alors?6, ou vous verrez les erreurs que vous voyez.

the absolute path to ld-linux.alors?2 est codé en dur dans l'exécutable au moment du lien, et peut ne pas être facilement modifiés après le lien est fait.

pour construire un exécutable qui fonctionnera avec la nouvelle glibc, faites ceci:

g++ main.o -o myapp ... \
   -Wl,--rpath=/path/to/newglibc \
   -Wl,--dynamic-linker=/path/to/newglibc/ld-linux.so.2

l'option de linker -rpath va faire la recherche de bibliothèques dans /path/to/newglibc (donc vous n'aurez pas à définir LD_LIBRARY_PATH avant de l'exécuter), et l'option -dynamic-linker va "cuire" chemin pour corriger ld-linux.so.2 dans l'application.

si vous ne pouvez pas myapp application (par exemple parce que c'est un tiers binaire), pas tout est perdu, mais il devient plus délicat. Une solution est de définir un environnement chroot approprié pour cela. Une autre possibilité est d'utiliser rtldi et un éditeur binaire .

176
répondu Employed Russian 2012-05-29 00:35:37

Use LD_PRELOAD: mettez votre bibliothèque quelque part hors des répertoires de man lib et exécutez:

LD_PRELOAD='mylibc.so anotherlib.so' program

voir: L'article de Wikipedia

17
répondu PiedPiper 2009-05-11 22:36:00

Cette question est ancienne, les autres réponses sont vieux. "Employé russe"S réponse est très bonne et informative, mais il ne fonctionne que si vous avez le code source. Si vous ne le faites pas, les alternatives à l'époque étaient très délicates. Heureusement aujourd'hui, nous avons une solution simple à ce problème (commentée dans l'une de ses réponses), en utilisant patchelf . Tout ce que vous avez à faire est:

$ ./patchelf --set-interpreter /path/to/newglibc/ld-linux.so.2 --set-rpath /path/to/newglibc/ myapp

Et après cela, vous pouvez exécuter votre fichier:

$ ./myapp

pas besoin de chroot ou éditer manuellement les binaires, heureusement. Mais n'oubliez pas de sauvegarder votre binaire avant de le corriger, si vous n'êtes pas sûr de ce que vous faites, parce qu'il modifie votre fichier binaire. Après le patch, vous ne pouvez pas restaurer l'ancien chemin de l'interpréteur/rpath. Si cela ne fonctionne pas, vous devrez continuer à le corriger jusqu'à ce que vous trouviez le chemin qui fonctionnera réellement... Ça n'a pas à être un processus d'essai et d'erreur. Par exemple, dans OP exemple, il avait besoin de GLIBC_2.3 , de sorte que vous pouvez facilement trouver qui lib fournit cette version en utilisant strings :

$ strings /lib/i686/libc.so.6 | grep GLIBC_2.3
$ strings /path/to/newglib/libc.so.6 | grep GLIBC_2.3

en théorie, le premier grep serait vide parce que le système libc n'a pas la version qu'il veut, et le second devrait sortir GLIBC_2.3 parce qu'il a la version myapp utilise, donc nous savons que nous pouvons patchelf notre binaire en utilisant ce chemin.

quand vous essayez d'exécuter un binaire sous linux, le binaire essaie de chargez le linker, puis les bibliothèques, et elles devraient toutes ÊTRE dans le chemin et/ou au bon endroit. Si votre problème est avec le linker et que vous voulez savoir quel chemin votre binaire cherche, Vous pouvez le découvrir avec cette commande:

$ readelf -l myapp | grep interpreter
  [Requesting program interpreter: /lib/ld-linux.so.2]                                                                                                                                                                                   

Si votre problème est avec les libs, les commandes qui vous donnera les libs utilisées sont:

$ readelf -d myapp | grep Shared
$ ldd myapp 

ce sera la liste des libs que vos besoins binaires, mais vous connaissez probablement déjà le ceux qui posent problème, puisqu'ils produisent déjà des erreurs comme dans le cas de L'OP.

"patchelf" fonctionne pour beaucoup de problèmes différents que vous pouvez rencontrer en essayant d'exécuter un programme, liés à ces 2 problèmes. Par exemple , si vous obtenez: ELF file OS ABI invalid , il peut être corrigé en mettant un nouveau chargeur (la partie --set-interpreter de la commande) comme je l'explique ici . Un autre exemple est pour le problème de No such file or directory lorsque vous exécutez un fichier qui est là et exécutable, comme illustré ici . Dans ce cas précis, OP manquait un lien vers le chargeur, mais peut-être que dans votre cas vous n'avez pas accès à root et ne pouvez pas créer le lien. La mise en place d'un nouvel interprète résoudrait votre problème.

Merci employé russe et Michael Pankov pour la perspicacité et la solution!

16
répondu msb 2018-03-06 22:52:13

pouvez-vous envisager D'utiliser Nix http://nixos.org/nix / ?

Nix supporte la gestion de paquets multi-utilisateurs: plusieurs utilisateurs peuvent partager un magasin Nix commun en toute sécurité, n'ont pas besoin d'avoir les privilèges de installez le logiciel et pouvez installer et utiliser plusieurs versions d'un paquet.

6
répondu Igor 2014-08-31 11:10:46

tout d'abord, la dépendance la plus importante de chaque programme dynamiquement lié est le linker. Toutes les bibliothèques doivent donc correspondre à la version du linker.

prenons un exemple simple: j'ai le système Newset ubuntu où j'exécute un programme (dans mon cas, c'est le compilateur D - ldc2). J'aimerais l'exécuter sur les vieux CentOS, mais à cause de l'ancienne bibliothèque glibc, c'est impossible. J'ai

ldc2-1.5.0-linux-x86_64/bin/ldc2: /lib64/libc.so.6: version `GLIBC_2.15' not found (required by ldc2-1.5.0-linux-x86_64/bin/ldc2)
ldc2-1.5.0-linux-x86_64/bin/ldc2: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by ldc2-1.5.0-linux-x86_64/bin/ldc2)

je dois copier toutes les dépendances de ubuntu à centos. La méthode appropriée est la suivante:

tout d'abord, vérifions toutes les dépendances:

ldd ldc2-1.5.0-linux-x86_64/bin/ldc2 
    linux-vdso.so.1 =>  (0x00007ffebad3f000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f965f597000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f965f378000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f965f15b000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f965ef57000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f965ec01000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f965e9ea000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f965e60a000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f965f79f000)

linux-vdso..1 n'est pas une vraie bibliothèque et nous n'avons pas à s'en soucier.

/lib64 / ld-linux-x86-64.alors?2 est le linker, qui est utilisé par le lien linux do l'exécutable avec toutes les bibliothèques dynamiques.

le reste des fichiers sont de vraies bibliothèques et tous ensemble avec le linker doivent être copiés quelque part dans les centos.

supposons que toutes les bibliothèques et linker sont dans le répertoire" /mylibs".

ld-linux-x86-64.alors?2-comme je l'ai déjà dit - est le linker. Ce n'est pas une bibliothèque dynamique mais un exécutable statique. Vous pouvez l'exécuter et voir qu'il a même quelques paramètres, par exemple --library-path (je vais y revenir).

sur linux, programme dynamiquement lié peut être lunchéjuste par son nom, par exemple

/bin/ldc2

Linux charge un tel programme en RAM, et vérifie quel linker est paramétré pour lui. Habituellement, sur un système 64 bits, c'est /lib64/ld-linux-x86-64.alors?2 (dans votre système de fichiers, il s'agit d'un lien symbolique vers le véritable exécutable). Puis linux exécute le linker et charge les bibliothèques dynamiques.

vous pouvez aussi changer cela un peu et faire un tel tour:

/mylibs/ld-linux-x86-64.so.2 /bin/ldc2

c'est la méthode pour forcer linux à utiliser un linker spécifique.

et maintenant nous pouvons retour au paramètre mentionné plus haut --library-path

/mylibs/ld-linux-x86-64.so.2 --library-path /mylibs /bin/ldc2

il exécutera ldc2 et chargera les bibliothèques dynamiques à partir de /mylibs.

c'est la méthode pour appeler l'exécutable avec des bibliothèques choisies (pas par défaut).

5
répondu Arkadiusz Rychliński 2017-11-04 21:01:45

si vous regardez attentivement la deuxième sortie, vous pouvez voir que le nouvel emplacement pour les bibliothèques est utilisé. Peut-être qu'il manque encore des bibliothèques qui font partie de la glibc.

je pense aussi que toutes les bibliothèques utilisées par votre programme devraient être compilées par rapport à cette version de glibc. Si vous avez accès au code source du programme, une nouvelle compilation semble être la meilleure solution.

1
répondu rsarro 2009-05-11 16:06:08

"Employé russe" est parmi la meilleure réponse, et je pense que tous les autres réponses proposées peuvent ne pas fonctionner. La raison en est simplement que lorsqu'une application est créée pour la première fois, tous les API dont elle a besoin sont résolus au moment de la compilation. En utilisant "ldd" u peut voir toutes les dépendances statiquement liées:

ldd /usr/lib/firefox/firefox
    linux-vdso.so.1 =>  (0x00007ffd5c5f0000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f727e708000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f727e500000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f727e1f8000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f727def0000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f727db28000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f727eb78000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f727d910000)

mais à l'exécution, firefox chargera aussi beaucoup d'autres bibliothèques dynamiques, par exemple (pour firefox) il y a beaucoup de bibliothèques étiquetées "glib"chargées (même si lié statiquement il n'en existe pas):

 /usr/lib/x86_64-linux-gnu/libdbus-glib-1.so.2.2.2
 /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0
 /usr/lib/x86_64-linux-gnu/libavahi-glib.so.1.0.2

de nombreuses fois, vous pouvez voir les noms d'une version être soft-linked dans une autre version. Par exemple:

lrwxrwxrwx 1 root root     23 Dec 21  2014 libdbus-glib-1.so.2 -> libdbus-glib-1.so.2.2.2
-rw-r--r-- 1 root root 160832 Mar  1  2013 libdbus-glib-1.so.2.2.2

cela signifie donc que des versions différentes de" bibliothèques " existent dans un système - ce qui n'est pas un problème car c'est le même fichier, et il fournira des compatibilités lorsque les applications ont des dépendances de versions multiples.

Donc, au niveau du système, tous les les bibliothèques sont presque interdépendantes l'une de l'autre, et le simple fait de changer la priorité de chargement des bibliothèques via la manipulation de LD_PRELOAD ou de LD_LIBRARY_PATH n'aidera pas - même si elle peut charger, l'exécution peut encore se planter.

http://lightofdawn.org/wiki/wiki.cgi/-wiki/NewAppsOnOldGlibc

la meilleure alternative est chroot (mentionné par ER brièvement): mais pour cela, vous aurez besoin de recréer l'environnement entier dans lequel est l'original binaire exécuter - en général à partir de /lib, /usr/lib/, /usr/lib/x86 etc. Vous pouvez utiliser "Buildroot", ou YoctoProject, ou tout simplement tar à partir d'un environnement Distro existant. (comme Fedora / Suse etc).

1
répondu Peter Teoh 2015-07-09 00:41:34

Je ne suis pas sûr que la question soit toujours pertinente, mais il y a une autre façon de régler le problème: Docker. On peut installer un conteneur presque vide de la Distribution Source (la Distribution utilisée pour le développement) et copier les fichiers dans le conteneur. De cette façon, vous n'avez pas besoin de créer le système de fichiers nécessaire pour chroot.

1
répondu user1396055 2018-07-19 18:44:10

Setup 1: compilez votre propre glibc sans GCC dédié et utilisez-le

cette configuration pourrait fonctionner et est rapide car elle ne recompile pas L'ensemble de la chaîne D'outils GCC, juste glibc.

mais il n'est pas fiable car il utilise des objets crt1.o , crti.o , et crtn.o fournis par glibc. Ceci est mentionné à: https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_location ces objets font une configuration précoce sur laquelle glibc s'appuie, donc je ne serais pas surpris si les choses se sont écrasées de manière merveilleuse et subtile.

pour une configuration plus fiable, voir Configuration 2 ci-dessous.

construire glibc et installer localement:

export glibc_install="$(pwd)/glibc/build/install"

git clone git://sourceware.org/git/glibc.git
cd glibc
git checkout glibc-2.28
mkdir build
cd build
../configure --prefix "$glibc_install"
make -j `nproc`
make install -j `nproc`

Configuration 1: vérification de la compilation

test_glibc.c

#define _GNU_SOURCE
#include <assert.h>
#include <gnu/libc-version.h>
#include <stdatomic.h>
#include <stdio.h>
#include <threads.h>

atomic_int acnt;
int cnt;

int f(void* thr_data) {
    for(int n = 0; n < 1000; ++n) {
        ++cnt;
        ++acnt;
    }
    return 0;
}

int main(int argc, char **argv) {
    /* Basic library version check. */
    printf("gnu_get_libc_version() = %s\n", gnu_get_libc_version());

    /* Exercise thrd_create from -pthread,
     * which is not present in glibc 2.27 in Ubuntu 18.04.
     * /q/how-do-i-start-threads-in-plain-c-24995/"The atomic counter is %u\n", acnt);
    printf("The non-atomic counter is %u\n", cnt);
}

compiler et exécuter avec test_glibc.sh :

#!/usr/bin/env bash
set -eux
gcc \
  -L "${glibc_install}/lib" \
  -I "${glibc_install}/include" \
  -Wl,--rpath="${glibc_install}/lib" \
  -Wl,--dynamic-linker="${glibc_install}/lib/ld-linux-x86-64.so.2" \
  -std=c11 \
  -o test_glibc.out \
  -v \
  test_glibc.c \
  -pthread \
;
ldd ./test_glibc.out
./test_glibc.out

le programme produit les résultats escomptés:

gnu_get_libc_version() = 2.28
The atomic counter is 10000
The non-atomic counter is 8674

commande adaptée de https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_location mais --sysroot a échoué avec:

cannot find /home/ciro/glibc/build/install/lib/libc.so.6 inside /home/ciro/glibc/build/install

donc je l'ai enlevé.

ldd confirme que la sortie ldd et les bibliothèques que nous venons de construire sont effectivement utilisées comme prévu:

+ ldd test_glibc.out
        linux-vdso.so.1 (0x00007ffe4bfd3000)
        libpthread.so.0 => /home/ciro/glibc/build/install/lib/libpthread.so.0 (0x00007fc12ed92000)
        libc.so.6 => /home/ciro/glibc/build/install/lib/libc.so.6 (0x00007fc12e9dc000)
        /home/ciro/glibc/build/install/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007fc12f1b3000)

la sortie de débogage de la compilation gcc montre que les objets runtime de mon hôte ont été utilisés, ce qui est mauvais comme mentionné précédemment, mais je ne sais pas comment l'contourner, par exemple il contient:

COLLECT_GCC_OPTIONS=/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crt1.o

Setup 1: modifier glibc

modifions maintenant glibc avec:

diff --git a/nptl/thrd_create.c b/nptl/thrd_create.c
index 113ba0d93e..b00f088abb 100644
--- a/nptl/thrd_create.c
+++ b/nptl/thrd_create.c
@@ -16,11 +16,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */

+#include <stdio.h>
+
 #include "thrd_priv.h"

 int
 thrd_create (thrd_t *thr, thrd_start_t func, void *arg)
 {
+  puts("hacked");
   _Static_assert (sizeof (thr) == sizeof (pthread_t),
                   "sizeof (thr) != sizeof (pthread_t)");

puis recompiler et réinstaller glibc, et recompiler et relancer notre programme:

cd glibc/build
make -j `nproc`
make -j `nproc` install
./test_glibc.sh

et nous voyons hacked imprimé quelques fois comme prévu.

cela confirme une fois de plus que nous avons utilisé la glibc que nous avons compilée et non celle de l'hôte.

testé sur Ubuntu 18.04.

Setup 2: crosstool-NG setup vierge

c'est une alternative à la configuration 1, et c'est la configuration la plus correcte que j'ai réalisée jusqu'à présent: tout est correct autant que je peux l'observer, y compris les objets C runtime tels que crt1.o , crti.o , et crtn.o .

dans cette configuration, nous allons compiler une chaîne D'outils GCC dédiée qui utilise la glibc que nous voulons.

le seul inconvénient de cette méthode est que la construction prendra plus de temps. Mais je ne risquerais pas une production le programme d'installation avec rien de moins.

crosstool-NG est un ensemble de scripts qui télécharge et compile tout depuis la source pour nous, y compris GCC, glibc et binutils.

Oui le système de construction GCC est si mauvais que nous avons besoin d'un projet séparé pour cela.

cette configuration n'est pas parfaite car crosstool-NG ne supporte pas la construction des exécutables sans les drapeaux supplémentaires -Wl , ce qui est bizarre depuis que nous avons construit GCC lui-même. Mais tout semble fonctionner, si ce n'est qu'un inconvénient.

Obtenir crosstool-NG et le configurer:

git clone https://github.com/crosstool-ng/crosstool-ng
cd crosstool-ng
git checkout a6580b8e8b55345a5a342b5bd96e42c83e640ac5
export CT_PREFIX="$(pwd)/.build/install"
export PATH="/usr/lib/ccache:${PATH}"
./bootstrap
./configure --enable-local
make -j `nproc`
./ct-ng x86_64-unknown-linux-gnu
./ct-ng menuconfig

la seule option obligatoire que je puisse voir, est de faire correspondre la version du noyau hôte pour utiliser les en-têtes du noyau correct. Trouvez votre version du noyau hôte avec:

uname -a

qui me montre:

4.15.0-34-generic

donc dans menuconfig je fais:

  • Operating System
    • Version of linux

donc je sélectionne:

4.14.71

qui est la première version égale ou plus ancienne. Il doit être plus ancien car le noyau est rétrocompatible.

maintenant vous pouvez construire avec:

env -u LD_LIBRARY_PATH time ./ct-ng build CT_JOBS=`nproc`

et maintenant attendre une trentaine minutes à deux heures pour la compilation.

Setup 2: configuration optionnelle

le .config que nous avons généré avec ./ct-ng x86_64-unknown-linux-gnu a:

CT_GLIBC_V_2_27=y

pour changer que, dans menuconfig faire:

  • C-library
  • Version of glibc

enregistrer .config , et de continuer à la construire.

ou, si vous voulez utiliser votre propre source glibc, p.ex. pour utiliser glibc du dernier git, procéder comme ceci :

  • Paths and misc options
    • Try features marked as EXPERIMENTAL : mis à true
  • C-library
    • Source of glibc
      • Custom location : dire oui
      • Custom location
        • Custom source location : pointez vers un répertoire contenant votre source glibc

où glibc a été cloné:

git clone git://sourceware.org/git/glibc.git
cd glibc
git checkout glibc-2.28

Setup 2: tester

une fois que vous avez construit la chaîne d'outils que vous voulez, tester avec:

#!/usr/bin/env bash
set -eux
install_dir="${CT_PREFIX}/x86_64-unknown-linux-gnu"
PATH="${PATH}:${install_dir}/bin" \
  x86_64-unknown-linux-gnu-gcc \
  -Wl,--dynamic-linker="${install_dir}/x86_64-unknown-linux-gnu/sysroot/lib/ld-linux-x86-64.so.2" \
  -Wl,--rpath="${install_dir}/x86_64-unknown-linux-gnu/sysroot/lib" \
  -v \
  -o test_glibc.out \
  test_glibc.c \
  -pthread \
;
ldd test_glibc.out
./test_glibc.out

Tout semble fonctionner comme dans Setup 1, sauf que maintenant les bons objets runtime ont été utilisés:

COLLECT_GCC_OPTIONS=/home/ciro/crosstool-ng/.build/install/x86_64-unknown-linux-gnu/bin/../x86_64-unknown-linux-gnu/sysroot/usr/lib/../lib64/crt1.o

Setup 2: échec de la tentative de recompilation efficace de glibc

cela ne semble pas possible avec crosstool-NG, comme expliqué ci-dessous.

si vous venez de reconstruire;

env -u LD_LIBRARY_PATH time ./ct-ng build CT_JOBS=`nproc`

alors vos modifications à l'emplacement des sources glibc personnalisé sont pris en compte, mais il construit tout à partir de zéro, ce qui le rend inutilisable pour développement itératif.

Si nous n':

./ct-ng list-steps

il donne un bel aperçu des étapes de construction:

Available build steps, in order:
  - companion_tools_for_build
  - companion_libs_for_build
  - binutils_for_build
  - companion_tools_for_host
  - companion_libs_for_host
  - binutils_for_host
  - cc_core_pass_1
  - kernel_headers
  - libc_start_files
  - cc_core_pass_2
  - libc
  - cc_for_build
  - cc_for_host
  - libc_post_cc
  - companion_libs_for_target
  - binutils_for_target
  - debug
  - test_suite
  - finish
Use "<step>" as action to execute only that step.
Use "+<step>" as action to execute up to that step.
Use "<step>+" as action to execute from that step onward.

par conséquent, nous voyons qu'il ya des étapes glibc entrelacés avec plusieurs étapes GCC , notamment libc_start_files vient avant cc_core_pass_2 , qui est probablement la plus chère étape avec cc_core_pass_1 .

pour construire une seule étape, vous devez d'abord définir le " Save étapes intermédiaires" dans .config option pour la construction initiale:

  • Paths and misc options
    • Debug crosstool-NG
      • Save intermediate steps

et alors vous pouvez essayer:

env -u LD_LIBRARY_PATH time ./ct-ng libc+ -j`nproc`

mais malheureusement, le + requis comme mentionné à: https://github.com/crosstool-ng/crosstool-ng/issues/1033#issuecomment-424877536

noter cependant que redémarrer à une étape intermédiaire remet le répertoire d'installation dans l'état où il se trouvait pendant cette étape. C'est-à-dire: vous aurez une libc reconstruite-mais pas de compilateur final construit avec cette libc (et donc pas de librairies de compilateurs comme libstdc++ non plus).

et rend la reconstruction trop lente pour être réalisable pour le développement, et je ne vois pas comment surmonter cela sans Corriger crosstool-NG.

en outre, à partir de l'étape libc ne semble pas copier sur la source à partir de Custom source location , ce qui rend cette méthode inutilisable.

Bonus: stdlibc++

un bonus si vous êtes également intéressé par la bibliothèque standard C++: comment éditer et reconstruire la bibliothèque standard GCC libstdc++ C++ source?

1

quand j'ai voulu lancer un Chrome-browser sur Ubuntu precise( glibc-2.15), j'ai obtenu le message (typique) " ... libc.alors?6: version ' GLIBC_2.19 ' introuvable...". J'ai considéré le fait, que les fichiers ne sont pas nécessaires de façon permamently, mais seulement pour commencer. J'ai donc collecté les fichiers nécessaires pour le navigateur et sudo et créé un mini-glibc-2.19- environnement, a démarré le navigateur et a ensuite copié les fichiers originaux en arrière encore. Les fichiers nécessaires sont en RAM et la glibc originale est la même.

as root
the files (*-2.15.so) already exist 

mkdir - p / glibc-2.19 / i386-linux-gnu

/glibc-2.19/ld-linux.so.2 -> /glibc-2.19/i386-linux-gnu/ld-2.19.so
/glibc-2.19/i386-linux-gnu/libc.so.6 -> libc-2.19.so
/glibc-2.19/i386-linux-gnu/libdl.so.2 -> libdl-2.19.so
/glibc-2.19/i386-linux-gnu/libpthread.so.0 -> libpthread-2.19.so

mkdir - p / glibc-2.15 / i386-linux-gnu

/glibc-2.15/ld-linux.so.2 -> (/glibc-2.15/i386-linux-gnu/ld-2.15.so)
/glibc-2.15/i386-linux-gnu/libc.so.6 -> (libc-2.15.so)
/glibc-2.15/i386-linux-gnu/libdl.so.2 -> (libdl-2.15.so)
/glibc-2.15/i386-linux-gnu/libpthread.so.0 -> (libpthread-2.15.so)

le script pour lancer le navigateur:

#!/bin/sh
sudo cp -r /glibc-2.19/* /lib
/path/to/the/browser &
sleep 1
sudo cp -r /glibc-2.15/* /lib
sudo rm -r /lib/i386-linux-gnu/*-2.19.so
0
répondu dudu 2018-05-29 23:16:37