2 votes

Bazel - comment gérer les dépendances transitives des bibliothèques .so externes ?

J'essaie de construire une application binaire avec Bazel. Ce binaire dépend d'une bibliothèque externe, précompilée, appelons-la liba.so . A son tour, liba.so dépend de libb.so (cette information, je l'obtiens via readelf -d liba.so | grep NEEDED .

Pour construire cela, j'ai la configuration suivante dans Bazel :

cc_import(
    name = "liba",
    shared_library = "liba.so",
    deps = [":libb"],
)

cc_import(
    name = "libb",
    shared_library = "libb.so",  
)

cc_binary(
    name = "my_app",
    srcs = ["main.cpp"],
    deps = [":liba"],
)

La construction fonctionne bien, mais lors de l'exécution (soit par l'intermédiaire de bazel run ou directement) ldd ne trouve pas libb.so .

J'ai lu des articles à ce sujet et la raison en est que Bazel ajoute au RUNPATH du binaire que son dépendances directes . Desde libb.so est une dépendance transitive, le binaire ne peut pas la trouver.

Pour résoudre ce problème, je peux penser aux astuces suivantes :

  • Ajoutez des drapeaux de liaison vilains pour dire à Bazel d'ajouter à la page RPATH au lieu de RUNPATH . Il s'agit toutefois d'une mauvaise idée, car RPATH est en train d'être déprécié et ne permet pas d'être surchargé par l'intermédiaire de LD_LIBRARY_PATH .

  • Patch le fichier .so de la tierce partie à ajouter à leur RUNPATH . Cela fonctionne mais il n'est pas agréable de patcher des bibliothèques que je ne possède pas.

  • Faire des dépendances transitives des dépendances directes du binaire. Ce n'est pas bon, chaque bibliothèque devrait être responsable de ses dépendances. Le binaire n'a pas besoin de savoir ce que les liba.so dépend.

Existe-t-il de meilleurs moyens d'y parvenir ? D'autres choses que j'ai essayées sans succès :

  • Utilisez cc_library au lieu de cc_import
  • Utilisez data au lieu de deps .

Merci !

0voto

Konstantin Erman Points 476

J'ai été confronté à ce problème pendant longtemps. La première chose que je vous recommande d'essayer est d'activer la fonction

Copier les bibliothèques dynamiques en binaire

fonctionnalité de la chaîne d'outils. Je pense qu'elle a été principalement conçue pour Windows, mais elle devrait également fonctionner pour Linux.

Pour nos besoins, j'ai dû adopter une approche plus complexe, mais finalement plus fiable : J'ai implémenté l'aspect qui, pour chaque binaire, traverse le graphe des dépendances, collecte tout ce qui appartient au dossier de sortie du binaire et génère des actions de copie de fichiers pour y placer les fichiers nécessaires lorsque le binaire est construit. Cela inclut les dépendances transitives, mais est suffisamment flexible pour copier d'autres fichiers dont nous avons besoin dans le dossier de sortie - runtimes C++, fichiers de données, etc. Si vous êtes intéressé, je peux découper et partager des extraits de code pertinents.

Konstantin

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