deb-src-symbols - Fichier de modèle des bibliothèques
partagées étendues de Debian
debian/paquet.symbols.arch,
debian/symbols.arch,
debian/paquet.symbols,
debian/symbols
Les modèles de fichiers de symboles sont fournis dans les paquets source
de Debian et leur format est un sous-ensemble des fichiers de symboles fournis
dans les paquets binaires, voir
deb-symbols(5).
Les commentaires sont gérés dans les fichiers de symbole
modèles. Toute ligne commençant par
« # » est un commentaire sauf si elle commence par
« #include » (voir la section
utilisation des
inclusions). Les lignes commençant par
« #MISSING: » sont des commentaires
spéciaux qui indiquent les symboles qui peuvent avoir disparu.
Dans de rares cas, le nom de la bibliothèque dépend de
l'architecture. Afin d'éviter de coder le nom du paquet en dur dans le
fichier de symboles, il est possible d'utiliser le marqueur
#PACKAGE#.
Il sera remplacé par le vrai nom du paquet lors de l'installation des
fichiers de symboles. À la différence du marqueur
#MINVER#,
#PACKAGE# n'apparaîtra jamais dans le fichier
de symboles d'un paquet binaire.
L'étiquetage des symboles (« symbol
tagging ») est utile pour marquer des symboles qui sont
particuliers d'une manière ou d'une autre. Tout symbole peut avoir un
nombre quelconque d'étiquettes associées. Bien que toutes les
étiquettes soient analysées et conservées, seules
certaines d'entre elles sont comprises par
dpkg-gensymbols et
déclenchent un traitement spécifique des symboles. Veuillez
consulter la sous-section
Étiquettes standard de symbole pour
une référence complète à propos de ces
étiquettes.
L'indication de l'étiquette vient juste avant le nom du symbole (sans
espace). Elle commence toujours par une parenthèse ouvrante
(,
se termine avec une parenthèse fermante
) et doit contenir au
moins une étiquette. Les étiquettes multiples doivent
être séparées par le caractère
|. Chaque
étiquette peut comporter optionnellement une valeur,
séparée du nom de l'étiquette par le caractère
=. Les noms et valeurs des étiquettes sont des chaînes
quelconques qui ne doivent pas comporter les caractères
)
| et
=. Les noms de symbole qui suivent une étiquette
peuvent optionnellement être mis entre guillemets avec les
caractères
' ou
" afin d'y autoriser la
présence d'espaces. Cependant, si aucune étiquette n'est
utilisée, les guillemets sont alors traités comme une partie du
nom du symbole, qui s'arrête alors au premier espace.
(étiq1=je suis marqué|étiquette avec espace)"symbole comportant des
espaces"@Base 1.0 (optional) symbole_non_protégé@Base 1.0 1
symbole_non_étiqueté@Base 1.0
Le premier symbole de cet exemple est appelé
symbole comportant des
espaces et utilise deux étiquettes :
étiq1
avec la valeur
je suis marqué et
étiquette avec
espace sans valeur. Le deuxième symbole, appelé
symbole_non_protégé ne comporte que l'étiquette
optional. Le dernier symbole est un exemple de symbole normal sans
étiquette.
Comme les étiquettes de symbole sont une extension du format de
deb-symbols(5), elles ne peuvent apparaître que
dans les fichiers de symboles des paquets source (ces fichiers peuvent ensuite
être vus comme des modèles permettant de construire les fichiers
de symboles inclus dans les paquets binaires). Lorsque
dpkg-gensymbols
est lancé sans l'option
-t, il affiche les fichiers de symboles
compatibles avec le format
deb-symbols(5) : il
traite entièrement les symboles d'après les exigences des
étiquettes standard et supprime les étiquettes dans sa sortie.
Au contraire, dans le mode modèle
(« template », option
-t), tous les
symboles et leurs étiquettes (standard et inconnues) sont
conservés dans la sortie et écrits dans leur forme d'origine.
- optional
- Un symbole marqué comme optionnel peut
disparaître de la bibliothèque à tout moment et ne
provoquera pas l'échec de dpkg-gensymbols. Cependant, les
symboles optionnels disparus apparaîtront en permanence comme
manquants dans le fichier de différences, à chaque nouvelle
version du paquet. Ce comportement sert de rappel au responsable qu'un tel
symbole doit être supprimé du fichier de symboles ou bien
rajouté à la bibliothèque. Un tel symbole optionnel,
précédemment déclaré comme manquant
(« MISSING »), peut réapparaître
soudainement dans la version suivante en étant remis à
l'état existant (« existing »), sans
modification de sa version minimale.
Cette étiquette est utile pour les symboles qui sont privés,
car leur disparition ne provoque pas de changement d'interface applicative
(ABI). Par exemple, la plupart des modèles d'instanciation C++ sont
dans cette catégorie. Comme toute autre étiquette, celle-ci
peut comporter une valeur arbitraire qui peut servir à indiquer
pour quelle raison le symbole est optionnel.
-
arch=liste-d'architectures
-
arch-bits=octets-architecture
-
arch-endian=boutisme-d'architecture
- Ces étiquettes permettent de restreindre la liste
des architectures avec lesquelles le symbole est censé exister. Les
étiquettes arch-bits et arch-endian sont prises en
charge depuis dpkg 1.18.0. Lorsque la liste des symboles est mise
à jour avec ceux découverts dans la bibliothèque,
tous les symboles spécifiques d'architectures qui ne concernent pas
l'architecture en cours sont ignorés. Si un symbole propre à
l'architecture en cours n'existe pas dans la bibliothèque, les
processus normaux pour des symboles manquants s'appliquent jusqu'à
éventuellement provoquer l'échec de dpkg-gensymbols.
D'un autre côté, si le symbole propre à une
architecture est trouvé alors qu'il n'est pas censé exister
(parce que l'architecture courante n'est pas mentionnée dans
l'étiquette ou ne correspond pas au boutisme et aux octets), il est
rendu indépendant de l'architecture (c'est-à-dire que les
étiquettes d'architecture, d'octets de l'architecture et de
boutisme d'architecture sont abandonnées et le symbole
apparaît dans le fichier de différences) mais non
considéré comme nouveau. (NdT : une aspirine peut
être nécessaire après la lecture de ce paragraphe)
Dans le mode de fonctionnement par défaut (pas en mode
« modèle »), seuls les symboles
spécifiques de certaines architectures qui correspondent à
l'architecture courante sont écrits dans le fichier de symboles. Au
contraire, tous les symboles spécifiques d'architectures (y compris
ceux des architectures différentes) seront écrits dans le
fichier de symboles, dans le mode
« modèle ».
Le format de liste-d'architectures est le même que le format
utilisé dans les champs Build-Depends des fichiers
debian/control (à l'exception des crochets d'inclusion []).
Par exemple, le premier symbole de la liste qui suit sera pris en compte
sur les architectures alpha, n'importe quelle amd64 et ia64, le second
uniquement sur les architectures linux et le troisième partout sauf
sur armel.
(arch=alpha any-amd64 ia64)un_symbole_spécifique_64bit@Base 1.0
(arch=linux-any)un_symbole_spécifique_linux@Base 1.0
(arch=!armel)un_symbole_inexistant_sur_armel@Base 1.0
Les octets-architecture sont soit 32 soit 64.
(arch-bits=32)32bit_specific_symbol@Base 1.0
(arch-bits=64)64bit_specific_symbol@Base 1.0
Le boutisme-d'architecture est soit little soit big.
(arch-endian=little)little_endian_specific_symbol@Base 1.0
(arch-endian=big)big_endian_specific_symbol@Base 1.0
Plusieurs restrictions peuvent être chaînées.
(arch-bits=32|arch-endian=little)32bit_le_symbol@Base 1.0
- allow-internal
-
dpkg-gensymbols comporte une liste de symboles
internes qui ne devraient pas apparaître dans les fichiers de
symboles, car ils sont en général uniquement des effets de
bord de détails de mise en œuvre de la chaîne
d'outils de construction (depuis dpkg 1.20.1). Si, pour une raison
précise, vous voulez vraiment inclure un de ces symboles dans le
fichier, vous pouvez imposer qu'il soit ignoré, avec
allow-internal. Cela peut être utile pour certaines
bibliothèques de bas niveau telles que libgcc.
- ignore-blacklist
- Un alias obsolète pour allow-internal (depuis
dpkg 1.20.1, pris en charge depuis dpkg 1.15.3).
- c++
- Indique un motif de symbole c++. Voir la
sous-section Utilisation de motifs de symbole plus loin.
- symver
- Indique un motif de symbole symver (version de
symbole). Voir la sous-section Utilisation des motifs de symbole
plus loin.
- regex
- Indique un motif de symbole basé sur une
expression-rationnelle. Voir la sous-section Utilisation des
motifs de symbole plus loin.
Au contraire d'une indication normale de symbole, un motif permet de couvrir des
symboles multiples de la bibliothèque.
dpkg-gensymbols essaie de
faire correspondre chaque motif à chaque symbole qui n'est pas
explicitement défini dans le fichier de symboles. Dès qu'un
motif est trouvé qui correspond au symbole, l'ensemble de ses
étiquettes et propriétés sont utilisées comme
spécification de base du symbole. Si aucun des motifs ne correspond, le
symbole sera considéré comme nouveau.
Un motif est considéré comme perdu si aucun symbole ne lui
correspond dans la bibliothèque. Par défaut, cela provoquera un
échec de
dpkg-gensymbols s'il est utilisé avec l'option
-c1 (ou une valeur plus élevée). Cependant, si
l'échec n'est pas souhaité, le motif peut être
marqué comme optionnel avec l'étiquette
optional. Dans ce
cas, si le motif ne correspond à rien, il sera simplement
mentionné dans le fichier de différences comme
MISSING
(manquant). De plus, comme pour tout autre symbole, le motif peut être
limité à des architectures données avec
l'étiquette
arch. Veuillez consulter la sous-section
Étiquettes standard de symbole pour plus d'informations.
Les motifs sont une extension du format de
deb-symbols(5) en ce sens
qu'ils ne sont valables que dans les modèles de fichiers de symboles.
Cependant, la partie comportant le nom de symbole est utilisée comme
une expression à faire correspondre à
name@version du
symbole réel. Afin de faire la distinction entre les différents
types de motifs, un motif sera usuellement marqué avec une
étiquette spéciale.
Actuellement,
dpkg-gensymbols gère trois types de base de
motifs :
- c++
- Ce motif est repéré par l'étiquette
c++. Il ne sera comparé qu'aux symboles C++ avec leur nom de
symbole rétabli (demangled) tel qu'affiché avec l'utilitaire
c++filt(1). Ce motif est très pratique pour faire
correspondre les symboles dont les noms décorés (mangled)
peuvent différer selon les architectures bien que leurs noms
d'origine restent les mêmes. Un tel groupe de symboles sont les
non-virtual thunks pour lesquels les décalages (offsets)
spécifiques d'architectures sont inclus dans leur nom
décoré. Une manifestation usuelle de ce cas est le
destructeur virtuel qui, dans le contexte d'un
« problème du diamant », a besoin d'un
symbole de transition spécial (ou
« thunk ») non virtuel. Par exemple,
même si _ZThn8_N3NSB6ClassDD1Ev@Base sur une architecture 32 bits
est identique à _ZThn16_N3NSB6ClassDD1Ev@Base sur une architecture
64 bits, les deux peuvent être indiqués avec le même
motif c++ :
libdummy.so.1 libdummy1 #MINVER#
[...]
(c++)"non-virtual thunk to NSB::ClassD::~ClassD()@Base" 1.0
[...]
Le nom non décoré ci-dessus peut être obtenu avec la
commande suivante :
$ echo '_ZThn8_N3NSB6ClassDD1Ev@Base' | c++filt
Veuillez noter que, bien que le nom décoré soit unique dans la
bibliothèque par définition, cela n'est pas forcément
vrai pour le nom non décoré. Deux symboles réels
différents peuvent avoir le même nom non
décoré. C'est par exemple le cas avec les symboles
« thunk » non virtuels dans des configurations
d'héritage complexes ou avec la plupart des constructeurs et
destructeurs (puisque g++ crée usuellement deux symboles
réels pour eux). Cependant, comme ces collisions se produisent au
niveau de l'interface applicative binaire (ABI), elles ne devraient pas
dégrader la qualité du fichier de symboles.
- symver
- Ce motif est indiqué par l'étiquette
symver. Les bibliothèques bien gérées
utilisent des symboles versionnés où chaque version
correspond à la version amont à laquelle le symbole a
été ajouté. Si c'est le cas, il est possible
d'utiliser un motif symver pour faire correspondre chaque symbole
associé à la version spécifique. Par exemple :
libc.so.6 libc6 #MINVER#
(symver)GLIBC_2.0 2.0
[...]
(symver)GLIBC_2.7 2.7
access@GLIBC_2.0 2.2
Tous les symboles associés avec les versions GLIBC_2.0 et GLIBC_2.7
conduiront respectivement à des versions minimales de 2.0 et 2.7,
à l'exception du symbole access@GLIBC_2.0. Ce dernier amène
à une dépendance minimale sur la version 2.2 de libc6
bien qu'il soit dans le scope de
« (symvar)GLIBC_2.0 ». Cela est dû au
fait que les symboles spécifiques prennent le pas sur les motifs.
Veuillez noter que les anciens motifs avec caractères
génériques (indiqués sous la forme
« *@version ») dans le champ de nom de symbole
sont toujours gérés. La nouvelle syntaxe
« (symver|optional)version » doit toutefois
leur être préférée. Par exemple,
« *@GLIBC_2.0 2.0 » devrait être
écrit sous la forme « (symver|optional)GLIBC_2.0
2.0 » si un comportement analogue est recherché.
- regex
- Les motifs d'expressions rationnelles sont indiqués
par l'étiquette expression-rationnelle. La correspondance se
fait avec une expression rationnelle Perl sur le champ de nom de symbole.
La correspondance est faite telle quelle et il ne faut donc pas oublier le
caractère ^, sinon la correspondance est faite sur n'importe
quelle partie du symbole réel name@version. Par
exemple :
libdummy.so.1 libdummy1 #MINVER#
(regex)"^mystack_.*@Base$" 1.0
(regex|optional)"private" 1.0
Les symboles tels que « mystack_new@Base »,
« mystack_push@Base »,
« mystack_pop@Base », etc., seront en
correspondance avec le premier motif alors que
« ng_mystack_new@Base » ne le sera pas. Le
deuxième motif correspondra pour tous les symboles qui comportent
la chaîne « private » dans leur nom et
les correspondances hériteront de l'étiquette
optional depuis le motif.
Les motifs de base indiqués précédemment peuvent
être combinés au besoin. Dans ce cas, ils sont traités
dans l'ordre où les étiquettes sont indiquées. Par
exemple, les deux motifs :
(c++|regex)"^NSA::ClassA::Private::privmethod\d\(int\)@Base" 1.0
(regex|c++)N3NSA6ClassA7Private11privmethod\dEi@Base 1.0
seront en correspondance avec les symboles
« _ZN3NSA6ClassA7Private11privmethod1Ei@Base" »
et « _ZN3NSA6ClassA7Private11privmethod2Ei@Base ».
Lors de la correspondance avec le premier motif, le symbole brut est d'abord
rétabli d’origine en tant que symbole C++, puis comparé
à l'expression rationnelle. D'un autre côté, lors de la
correspondance avec le deuxième motif, l'expression rationnelle est
comparée au nom de symbole brut, puis le symbole est testé en
tant que symbole C++ en tentant de le rétablir d’origine.
L'échec de n'importe quel motif basique provoquera l'échec de
l'ensemble du motif. Ainsi, par exemple,
« __N3NSA6ClassA7Private11privmethod\dEi@Base » ne
correspondra à aucun des motifs, car ce n'est pas un symbole C++
valable (NdT : j'ai l'impression de traduire du Klingon !).
En général, les motifs sont divisés en deux
groupes : les alias (
c++ et
symver basique) et les
motifs génériques (
expression-rationnelle et toutes les
combinaisons de motifs basiques multiples). La correspondance de motifs
basés sur des alias est rapide (
O(1)) alors que les motifs
génériques sont O(N) (N étant le nombre de motifs
génériques) pour chaque symbole. En conséquence, il est
déconseillé d'abuser des motifs génériques.
Lorsque plusieurs motifs correspondent pour le même symbole réel,
les alias (d'abord
c++, puis
symver) sont
privilégiés par rapport aux motifs génériques.
Ceux-ci sont essayés dans l'ordre où ils apparaissent dans le
modèle de fichier de symboles, en s'arrêtant à la
première correspondance. Veuillez noter, cependant, que la modification
manuelle de l'ordre des entrées de fichiers n'est pas
recommandée, car
dpkg-gensymbols crée des fichiers de
différences d'après l'ordre alphanumérique de leur nom.
Lorsqu'un jeu de symboles exportés varie selon les architectures, il est
souvent peu efficace d'utiliser un seul fichier de symboles. Pour couvrir ces
cas, une directive d'inclusion peut devenir utile dans certains cas :
- •
- Il est possible de factoriser la partie commune dans un
fichier externe donné et l'inclure dans le fichier
paquet.symbols. arch avec une directive
« include » utilisée de la
manière suivante :
#include "I<paquets>.symbols.common"
=item *
La directive d'inclusion peut également être
étiquetée comme tout autre symbole :
(étiquette|...|étiquetteN)#include "fichier_à_inclure"
Le résultat sera que tous les symboles inclus depuis I<fichier_à_inclure> seront considérés comme étiquetés par défaut avec I<etiq> ... I<etiqN>. Cela permet de créer un fichier I<paquet>.symbols commun qui inclut les fichiers de symboles spécifiques des S<architectures :>
symbole_commun1@Base 1.0
(arch=amd64 ia64 alpha)#include "package.symbols.64bit"
(arch=!amd64 !ia64 !alpha)#include "package.symbols.32bit"
symbole_commun2@Base 1.0
Les fichiers de symboles sont lus ligne par ligne et les directives d'inclusion
sont traitées dès qu'elles sont trouvées. En
conséquence, le contenu du fichier d'inclusion peut remplacer une
définition qui précède l'inclusion et ce qui suit
l'inclusion peut remplacer une définition qu'elle ajoutait. Tout
symbole (ou même une autre directive d'inclusion) dans le fichier
inclus peut définir des étiquettes supplémentaires ou
remplacer les valeurs d'étiquettes héritées, dans sa
définition d'étiquettes. Cependant, pour un symbole
donné, il n'existe pas de méthode permettant de remplacer une de
ses étiquettes héritées.
Un fichier inclus peut reprendre la ligne d'en-tête qui contient le
« SONAME » de la bibliothèque. Dans ce cas,
cela remplace toute ligne d'en-tête précédente. Il est
cependant déconseillé de dupliquer les lignes d'en-tête.
Une façon de le faire est la méthode suivante :
#include "libmachin1.symbols.common"
symboles_specifique_architecture@Base 1.0
deb-symbols(5),
dpkg-shlibdeps(1),
dpkg-gensymbols(1).
Ariel VARDI <
[email protected]>, 2002. Philippe Batailler, 2006.
Nicolas François, 2006. Veuillez signaler toute erreur à
<
[email protected]>.