J'ai des dépendances dans mon code qui nécessitent la libc. Lors de la construction (cargo build --release) sur Ubuntu 20.04 (glibc 2.31), l'exécutable résultant ne s'exécute pas sur CentOS 7 (glibc 2.17). Il renvoie une erreur indiquant qu'il nécessite GLIBC 2.18.

Lors de la construction du même code sur CentOS 7, l'exécutable résultant s'exécute sur CentOS 7 et Ubuntu 20.04.

Existe-t-il un moyen de contrôler quelle version de GLIBC est également requise pour construire cette version sur Ubuntu 20.04?

1
Michael 3 sept. 2020 à 16:16

2 réponses

Meilleure réponse

Si votre projet ne dépend d'aucune bibliothèque native, alors le moyen le plus simple serait probablement d'utiliser la cible x86_64-unknown-linux-musl.

Cette cible établit un lien statique avec MUSL Libc plutôt que de créer un lien dynamique avec la libc du système. En conséquence, il produit des binaires complètement statiques qui devraient fonctionner sur un large éventail de systèmes.

Pour installer cette cible:

rustup target add x86_64-unknown-linux-musl

Pour construire votre projet en utilisant cette cible:

cargo build --target x86_64-unknown-linux-musl

Voir le guide d'édition pour plus de détails.

Si vous utilisez des bibliothèques non-rust, cela devient plus difficile, car elles peuvent être liées dynamiquement et peuvent à leur tour dépendre de la libc système. Dans ce cas, vous devrez soit relier statiquement les bibliothèques externes (en supposant que cela soit même possible et que les bibliothèques que vous utilisez fonctionneront avec MUSL libc), soit créer différentes versions pour chaque plate-forme que vous souhaitez cibler.

Si vous finissez par devoir créer différentes versions pour chaque plate-forme, un conteneur Docker serait le moyen le plus simple d'y parvenir.

1
harmic 7 sept. 2020 à 05:15

En général, vous devez créer des binaires pour un système d'exploitation donné sur ce système d'exploitation, ou au moins construire sur le système d'exploitation le plus ancien que vous souhaitez prendre en charge.

La glibc utilise la gestion des versions de symboles pour préserver le comportement des programmes plus anciens tout en ajoutant la prise en charge de nouvelles fonctionnalités. Par exemple, une version plus récente de pthread_mutex_lock peut prendre en charge l'élision de verrouillage, contrairement à l'ancienne. Vous voyez cette erreur parce que lorsque vous créez un lien avec la libc, vous créez un lien avec la version par défaut du symbole si une version n'est pas explicitement spécifiée, et dans au moins un cas, la version à laquelle vous avez lié est de la glibc 2.18. Changer cela nécessiterait de recompiler libstd (et la libc crate, si vous l'utilisez) avec des modifications personnalisées pour choisir les anciens symboles versionnés, ce qui représente beaucoup de travail pour peu de gain.

Si votre seule dépendance est la glibc, il peut être suffisant de simplement compiler sur CentOS 7. Cependant, si vous dépendez d'autres bibliothèques, comme OpenSSL, alors celles-ci ne sont tout simplement pas compatibles entre les versions de système d'exploitation car leurs SONAME diffèrent, et il n'y a aucun moyen autour de ça. C'est pourquoi vous souhaitez généralement créer différents binaires par système d'exploitation.

1
bk2204 4 sept. 2020 à 01:44