Site icon Embarcadero RAD Studio, Delphi, & C++Builder Blogs

Problèmes de mélange des objets Classic et Clang: avertissements de l’éditeur de liens et amélioration de la stabilité de l’application

mixing classic and clang large size 2

L’éditeur de liens C ++ Builder vous avertit lorsque vous mélangez des fichiers objets liés à classique et clang ensemble, vous aidant ainsi à éviter les erreurs de l’éditeur de liens ou d’exécution.

Aujourd’hui, en 2020, nous vous recommandons d’utiliser les compilateurs Clang modernes, en particulier avec le travail que nous avons fait pour Win64 (par exemple, un tout nouveau débogueur) et les améliorations RTL pour faciliter la mise à niveau du classique. Cependant, de nombreux clients effectuent une mise à niveau par étapes: d’abord de Win32 classique vers Clang Win32, puis en ajoutant Win64 après. En fait, nous le recommandons souvent directement comme stratégie de mise à niveau, pour passer à Clang d’abord et Win64 ensuite, en deux étapes.

Cependant, il existe un problème courant lors du passage des compilateurs classiques aux compilateurs clang. Les fichiers objets (bibliothèques .obj et .lib) générés par les compilateurs classic et Clang Win32 ne sont pas compatibles binaires entre eux. (Les deux classiques et clang peuvent être liés à Delphi, mais classic et clang ne peuvent pas être liés l’un à l’autre.) Si vous essayez de créer une application dans laquelle certaines parties sont construites avec Clang et d’autres avec classic toutes mélangées, vous pouvez vous attendre à quelque chose des erreurs de l’éditeur de liens à l’instabilité d’exécution. Pourtant, c’est facile à faire accidentellement, à la fois lors de la mise à niveau ou même simplement lors de l’ajout d’une nouvelle bibliothèque ou d’un EXE à votre projet.

Dans la version 10.3.3, et cela a été documenté dans l’aide en ligne mais pas sur les blogs à l’époque, nous avons ajouté un nouvel avertissement de l’éditeur de liens pour vous aider à détecter ces situations.

Avant de montrer la solution, examinons rapidement ce qui peut se passer si vous rencontrez cette erreur dans vos builds.

Problèmes lors de la non-correspondance des compilateurs

Dans la version 10.3.3 et plus récente, vous recevrez un avertissement de l’éditeur de liens – voir ci-dessous – avant l’un des éléments suivants. Mais si vous utilisez une version plus ancienne, avant d’ajouter l’avertissement diagnostiquant le problème, vous ne verrez peut-être que les erreurs suivantes. Ceux-ci apparaissent lors de la liaison de l’application.

Erreurs de liaison

Lorsqu’une application créée avec la chaîne d’outils Clang est liée à une bibliothèque classique, vous pouvez voir les erreurs suivantes:

[crayon-676874c84d08e613793060/]

Lorsqu’une application créée avec la chaîne d’outils Classic est liée à une bibliothèque créée par Clang, vous pouvez voir les erreurs suivantes:

[crayon-676874c84d098561868280/]

Erreurs d’exécution

Dans certains cas, vous ne verrez peut-être aucune erreur de l’éditeur de liens et vous exécuterez votre application. Très probablement, à un moment donné, votre application plantera et il sera difficile de comprendre pourquoi, car le code semble correct. En réalité, cela sera dû à deux compilateurs différents faisant les choses de différentes manières – disposition de la mémoire, alignement, attentes de la bibliothèque d’exécution, gestion des exceptions, toutes sortes de différences possibles.

Ce n’est pas une bonne situation d’avoir des erreurs de l’éditeur de liens impairs ou un comportement d’exécution étrange. Nous avons donc ajouté un avertissement pour vérifier cette situation.

Diagnostiquer: un nouvel avertissement de l’éditeur de liens

RAD Studio / C ++ Builder 10.3.3 et plus récent vous avertit de mélanger clang et classique lors de la liaison. (Si des erreurs de l’éditeur de liens comme celles ci-dessus se produisent, cet avertissement est émis avant eux, vous verrez donc l’avertissement avant toute erreur due au problème.)

Le message dit « Avertissement: incompatibilité du compilateur ». puis vous dit ce qu’il attendait et ce qu’il a trouvé:

[crayon-676874c84d09a335404907/]

Alors, comment l’éditeur de liens vérifie-t-il les objets mixtes et comment sait-il à quoi s’attendre?

Dans l’erreur ci-dessus, j’ai une application VCL liée dans une bibliothèque statique. L’application VCL est construite avec Clang. La bibliothèque est construite avec classique. L’application clang est liée à la bibliothèque avec:

[crayon-676874c84d09b630178604/]

see documentation on linking with #pragma comment vs #link.

Il est assez facile de faire l’erreur de compilateurs incompatibles. Comme vous pouvez le voir dans la capture d’écran à droite, vous ne pouvez pas facilement dire quel compilateur Win32 est utilisé. C’est quelque chose que nous pourrions améliorer, mais pour le moment, il répertorie la plate-forme cible, pas le compilateur.

Notre compilateur émet maintenant dans chaque objet un enregistrement (un petit peu de données) indiquant avec quel compilateur il a été construit (par exemple, Clang Win32.) Lors de la liaison, l’éditeur de liens reçoit un ensemble de fichiers objets et de bibliothèques, dans l’ordre de la commande ligne. Il examine le premier objet avec lequel il est lié et indique qu’il s’attend à ce que tous les autres objets soient construits avec le même compilateur que le premier. Pour chaque objet dans lequel il est lié (et étant donné une bibliothèque, qui est juste un ensemble d’objets, pour chaque objet de la bibliothèque), il vérifie s’il a été construit avec le compilateur qu’il attend.

Sinon, il émet l’avertissement ci-dessus, que vous pouvez également voir dans l’image de droite. Vous pouvez voir qu’il répertorie l’objet erroné et avec quoi il a été construit, et cela explique également pourquoi il recherchait un compilateur différent. Ceci est destiné à vous aider à diagnostiquer la configuration de votre build.

TLDR

Résumé rapide: mélanger des fichiers objets construits avec deux compilateurs en un seul binaire est une mauvaise idée. L’éditeur de liens vous avertira si vous le faites et vous indiquera ce qui est construit avec quoi afin que vous puissiez le réparer. Cela corrige les problèmes de l’éditeur de liens et corrige les problèmes de stabilité des applications!

Lectures complémentaires

Composants ou bibliothèques d’empaquetage écrits dans les compilateurs Win32 Classic et Clang C ++
Cette nouvelle page docwiki traite de l’avertissement de l’éditeur de liens, mais contient également un peu plus d’informations. Il explique comment utiliser des binaires clang ou classiques si vous êtes un développeur d’applications et que vous créez des applications avec plusieurs parties (peut-être un lien avec une bibliothèque C ++ open source que vous créez également), et a également une autre section pour si vous êtes une bibliothèque développeur (par exemple, écrire des composants ou des bibliothèques et les distribuer à vos clients.)

 
Quitter la version mobile