BCC64X

De RAD Studio
Aller à : navigation, rechercher

Remonter à Compilateurs C++ améliorés par Clang


BCC64X est un compilateur C++ de RAD Studio pour Windows 64 bits (Moderne).

BCC64X est basé sur Clang. Pour plus d'informations sur les fonctionnalités communes entre le compilateur BCC64X et les autres compilateurs C++ améliorés par Clang, voir Compilateurs C++ améliorés par Clang.

Remarques:
  • Le compilateur C++ BCC64X basé sur Clang 20 est maintenant la version C++23 par défaut. Si nécessaire, vous pouvez toujours cibler C++20 ou C++17.
  • Pour Windows 32 bits, utilisez BCC32C (compilateur amélioré par Clang) ou BCC32 (compilateur d'ancienne génération).
  • BCC64X est la chaîne d'outils/compilateur Win64 Moderne qui est recommandée pour toutes les applications. Cependant, l'ancien BCC64 existe toujours.

Informations générales

Champ Valeur
Version de Clang 20.0
Version de LLVM 20.0
Conventions d'appel Microsoft x64
Substantypage Itanium
Bibliothèque standard LLVM libc++
C++ Runtime Personnalisé, basé sur MinGW-LLVM
C Runtime UCRT

Fichiers de sortie

Type de fichier Extension de fichier Format de fichier
Exécutable .exe PE64 (PE32+)
Bibliothèque partagée .dll PE64 (PE32+)
Bibliothèque statique .lib et lib[name].a Bibliothèque de fichiers objet, voir Liaison automatique pour plus d'informations sur les extensions.
Objet compilé .o COFF64
Informations de débogage .pdb PDB
Remarque: Le nouveau Clang prend en charge la liaison dynamique et statique des packages. Vous pouvez lier ces fichiers à vos EXE ou DLL.
Remarque: Pour éviter les conflits à l'exécution lorsque plusieurs versions de RAD Studio sont installées, les bibliothèques d'exécution partagées (libc++.dll) ont maintenant en suffixe le numéro de version. BDS (libc++-370.dll).

Ecriture du code C++ pour BCC64X

Pour écrire du code C++ spécifiquement pour BCC64X, utilisez :

#if defined(__BORLANDC__) && defined(_WIN64) && defined(__MINGW64__)

Si vous visez une release spécifique, ajoutez une vérification en procédant comme suit :

#if __clang_major__ == 20
  #pragma message("Using version 20 of Clang")
#endif


Pour plus d'informations, voir Compilateurs C++ améliorés par Clang, Macros prédéfinies.

Chaîne d'outils

La chaîne d'outils C++ Windows 64 bits Moderne (bcc64x) est une implémentation des extensions Clang et des fonctionnalités C++Builder avec une technologie adaptée aux nouvelles plates-formes. Avec le lieur LLD, la nouvelle RTL, et d'autres fonctionnalités, la nouvelle chaîne d'outils Clang est la chaîne d'outils C++ que nous recommandons.

Elle utilise la STL LLVM libc++, une RTL C++ personnalisée, le UCRT Windows pour le runtime C, et génère des fichiers objet au format COFF64 avec des informations de débogage PDB.

Pour ajouter cette chaîne d'outils à votre projet C++ existant, procédez comme suit :

  1. Cliquez avec le bouton droit sur le noeud Plates-formes cible dans la vue arborescente Projets.
  2. Sélectionnez Ajouter une plate-forme.
  3. Choisissez Windows 64 bits (Moderne).
Remarque: Vous pouvez facilement permuter entre la nouvelle et l'ancienne plate-forme Win64 car les deux sont installées et peuvent être ajoutées à un projet, ce qui facilite la mise à niveau.
Attention: Les anciennes chaînes d'outils proposaient plusieurs versions du runtime pour gérer séparément les applications à thread unique et les applications multithreads. La chaîne d'outils moderne a un seul runtime multithread. Par conséquent, vous pouvez uniquement utiliser un runtime multithread. Si votre application utilise un thread unique, ce runtime convient quand même.
Remarque: _setmaxstdio et _getstdiomax sont des fonctionnalités runtime de Microsoft (UCRT). Ces fonctionnalités sont uniquement prises en charge sur Win64x.

Comment tester le nouveau compilateur BCC64X

Dans RAD Studio, nous recommandons aux développeurs d'utiliser le moyen suivant pour écrire du code qui détecte si la nouvelle chaîne d'outils est utilisée :

  • Méthode recommandée : utilisez un test de macro pour _CODEGEARC_ et _clang_major_ >= 20 pour cette version et les suivantes. RAD Studio recommande cette approche car la version de Clang changera au fil du temps, et ce code restera valide pour la version actuelle et les futures versions de cette chaîne d'outils. Nous recommandons d'effectuer cette vérification pour votre code.
  • Utilisez un test de macro _CODEGEARC_ et _clang_major_ == 20 pour cette version spécifique. Utilisez uniquement cette approche pour tester la version initiale de la chaîne d'outils. Ce test échouera à détecter les versions futures de la chaîne d'outils. C'est pourquoi il est préférable d'utiliser le test précédent.
Remarque: Découvrez comment détecter LLVM et sa version ici.
  • Utilisez les macros _has_feature et _has_builtin pour tester les fonctionnalités C++ ou compilateur/LLVM qui ne sont pas propres à C++Builder mais s'appliquent à plusieurs chaînes d'outils basées sur Clang. Pour en savoir plus sur les macros de vérification de fonctionnalité, consultez cette page.


L'exemple de code ci-dessous illustre le test recommandé précédemment pour la nouvelle chaîne d'outils. Utilisez ce code pour encapsuler du code spécifique à la chaîne d'outils, comme l'inclusion des en-têtes.

#include <iostream>
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv[])
{
      #if defined(__CODEGEARC__) && (__clang_major__ >= 20)
           std::cout << "C++Builder Modern Compiler, 12.1 or newer";
      #else
           std::cout << "A different compiler";
      #endif
}

Pour migrer votre base de code existante, il est utile d'inclure le code spécifique à la nouvelle chaîne d'outils à l'intérieur d'une telle macro.

Remarque: Voir la liste complète des macros à la page Macros prédéfinies.

Ajustement des chemins

Pour garantir que le compilateur trouve les bons chemins, ajoutez la variable {Code|$(CC_SUFFIX)}} au chemin de bibliothèque.

Par exemple :

$(BDSLIB)\$(PLATFORM)$(CC_SUFFIX)\debug;..\..\..\..\..\Public\Documents\Embarcadero\Studio\15.0\Samples\CPP\Mobile Samples\User Interface\KeyboardToolbar\

La variable $CC_SUFFIX permet de gérer la différence entre les deux chaînes d'outils Win64. La nouvelle chaîne d'outils, bcc64x, comporte un X à la fin, ce qui signifie que l'emplacement correct des fichiers avec lesquels une liaison est établie est ‘win64x’. La variable $CC_SUFFIX prend la valeur X lorsque cette plate-forme est utilisée.

Tests pour Windows vs. Tests pour une chaîne d'outils spécifique

Lorsque vous utilisez du code source C++ tierce partie, vous pouvez avoir des en-têtes, des définitions de méthode, etc. propres à Windows mais incorrectement encapsulés dans une macro qui teste la chaîne d'outils (généralement MSVC). Pour régler cela, remplacez ces macros par un test de plate-forme plutôt qu'un test de chaîne d'outils.

Pour tester Windows, que vous utilisiez MSVC, C++Builder ou une autre chaîne d'outils, vérifiez si _WIN32 ou _WIN64 est défini. {CBuilder}} et MSVC définissent tous deux ces macros. Cette approche est recommandée lorsque le code est propre à Windows.

Les développeurs ont de moins en moins recours à des tests qui combinent plusieurs plates-formes (Windows) et des tests de chaînes d'outils. Cela est dû à l'utilisation croissante d'autres chaînes d'outils comme RAD Studio et mingw-llvm. Cependant, ce problème persiste lors de l'intégration de bibliothèques ou de code source C++ tierce partie.

Liaison de DLL

Construction d'une DLL et génération du fichier d'exportation .def

RAD Studio fournit llvm-dlltool.exe car il fait partie du llvm-project à partir duquel notre compilateur amélioré par Clang bcc64x.exe est construit. Pour générer un fichier .def, il est recommandé d'utiliser l'outil tdump.exe.

Liaison directe avec une DLL

La nouvelle chaîne d'outils permet de lier directement un fichier .dll. Vous pouvez utiliser la fonction -lmydll ou, si une copie du fichier .dll est présente dans le chemin LIBRARY, utiliser #pragma comment(lib, "mydll") sans qu'il soit nécessaire d'avoir une bibliothèque d’importation.

Pour plus d'informations, voir la documentation Liaison automatique.

Le lieur peut être invoqué manuellement via le compilateur si le chemin suivant est ajouté au lieur :

libclang_rt.builtins-x86_64.a

Création de bibliothèques d’importation DLL

RAD Studio permet maintenant de lier une .dll directement, sans avoir à passer par une bibliothèque d’importation. Cette nouvelle implémentation ne concerne que les plates-formes Win64x.

Cependant, la bibliothèque d’importation est généralement utilisée pour importer un fichier .dll car le lieur recherchera d'abord les bibliothèques, et en dernier les fichiers .dll.

La chaîne d'outils prend en charge toute bibliothèque COFF. Vous pouvez toutefois créer la vôtre.

Pour créer votre propre bibliothèque d’importation (.lib), procédez comme suit :

  1. Obtenez le fichier de définition (.def) de la DLL.
    Remarque: Le fichier .def peut être généré depuis un fichier .dll en utilisant notre outil tdump.
  2. Depuis l'outil tdump, exécutez la commande suivante pour créer le fichier .def :
    tdump -def mydll.dll mydll.def
    
    Remarque: Un fichier .def est du texte brut. Ouvrez le fichier et assurez-vous qu'il contient LIBRARY <dllname>.dll avec le nom de <dllname> correct.
  3. Utilisez le nouveau lieur Lieur LLD pour générer une bibliothèque d’importation en exécutant la commande suivante dans l'invite de commande de RAD Studio :
    ld.lld.exe -m i386pep --out-implib file.lib file.def
    

L'EDI crée automatiquement votre bibliothèque d’importation DLL à la construction. Vous pouvez aussi le faire manuellement en exécutant le code suivant au niveau de la ligne de commande :

bcc64x -tD -Xlinker --out-implib=dll.lib dll.cpp

ou

bcc64x -tD dll.cpp -Wl,--out-implib,dll.lib

Compilation parallèle

Les projets C++Builder utilisant la nouvelle chaîne d'outils Win64 peuvent être compilés en parallèle par défaut. La compilation s'effectue plus rapidement avec bcc64x qu'avec :

  • --jobs, en utilisant l'ancien bcc64 (ancienne chaîne d'outils Win64).
  • CMake & Ninja, en utilisant l'ancien et le nouveau bcc64/x.
  • Visual C++, avec CMake et Ninja et le commutateur de ligne de commande /MP.

Ce paramètre est activé par défaut pour les projets utilisant cette plate-forme. Consultez la documentation suivante pour configurer les paramètres ou comprendre le fonctionnement.

Comprendre le fonctionnement

La compilation parallèle des projets C++Builder combine deux fonctionnalités : batch compilation, où le compilateur reçoit plusieurs fichiers C++ à la fois plutôt que d'invoquer la compilation pour un seul fichier à la fois, et --jobs, où il traite les fichiers reçus en parallèle.

Ainsi, le compilateur reçoit beaucoup de fichiers à compiler (la compilation en lots ou compilation groupée) et doit les compiler en parallèle (--jobs).

Pourquoi activer les deux ? Si vous effectuez uniquement une compilation par lots (compilation groupée), le compilateur compilera tous les fichiers par une seule invocation du fichier EXE, mais il devra les traiter les uns après les autres en série. Si vous utilisez uniquement --jobs, la compilation s'effectue en parallèle, mais sur un seul fichier, ce qui n'a pas d'intérêt. Il est donc nécessaire d'activer les deux paramètres : (a) la compilation simultanée de plusieurs fichiers et (b) l'exécution en parallèle.

Comprendre le fonctionnement de la compilation parallèle ainsi que l'utilisation de la CPU

Les informations ci-dessous vous aideront à comprendre comment la compilation par lots avec --jobs fonctionne et comment optimiser vos environnements de construction pour accélérer et améliorer la compilation tout en utilisant vos ressources au mieux.

Sortie du compilateur

Les messages du compilateur ne concernent qu'un fichier à la fois. Même si la compilation s'exécute en parallèle, les messages relatifs à chaque fichier sont générés à la fin de l'opération.

En cas d'erreur de compilation, le processus s'arrête. Après l'erreur, des messages de compilation réussie peuvent s'afficher, car le processus continue pour les autres fichiers compilés en parallèle.

Systèmes de compilation

Le système de compilation en parallèle '--jobs' peut être utilisé depuis l'EDI et la ligne de commande MSBuild ainsi que directement via la ligne de commande ‘bcc64x’.

Sachez que vous pouvez tout à fait utiliser cette commande pour l'intégration continue (CI), les serveurs de build, etc. lorsque vous effectuez la compilation via une commande MSBuild en ligne de commande. Vous avez d'autres possibilités que l'appel direct du compilateur ; le système de compilation par défaut peut effectuer des compilations parallèles depuis la ligne de commande.

Les constructions ou les compilations s'effectuent normalement  ; la compilation parallèle est utilisée par défaut. Si vous ouvrez le Gestionnaire de tâches, vous pouvez voir un processus bcc64x unique qui utilise plusieurs threads, et approche les 100 % d'utilisation de la CPU.

C++ parallel building (batch and jobs) options.png

Pour vérifier si votre projet utilise la compilation en parallèle, ouvrez la fenêtre Options de projet :

  1. Assurez-vous que la plate-forme Windows 64 bits Moderne est sélectionnée et activée dans votre projet.
  2. Accédez à Options de projet. Vérifiez que "Toutes les configurations" est bien sélectionné dans la liste déroulante.
  3. Construction > Compilateur C++ > Activer la compilation groupée doit être défini sur true. Vérifiez qu'aucune autre configuration cible ne remplace ce choix ; ce paramètre doit être la valeur par défaut à un niveau hérité élevé.
  4. L'option Propriétés de projet > Général > Nombre de sous-processus doit être définie sur 0. Tous les coeurs de CPU dont vous disposez sont alors utilisés.

Invoquez msbuild pour votre projet. Dans la mesure où les paramètres ci-dessus sont définis dans les options de projet de l'EDI, la compilation peut s'effectuer en parallèle.

> msbuild MyProject.cbproj

Voir Construction d'un projet à l'aide d'une commande MSBuild pour une liste complète des paramètres. N'oubliez pas de vérifier dans l'EDI que la compilation en parallèle est configurée pour votre projet. Ces paramètres seront toujours utilisés par défaut lorsque msbuild sera utilisé depuis la ligne de commande avec ce projet.

Pour une exécution directe via la ligne de commande, utilisez la commande suivante :

> bcc64x a.cpp b.cpp c.cpp --jobs=0 ...other parameters

Cette commande envoie ce lot de fichiers en une seule fois et indique au compilateur d'effectuer une compilation en parallèle en utilisant tous les coeurs disponibles ('0' indiquant tous les coeurs.)

Saturation CPU

Dans l'onglet Options de projet > Propriétés de projet > Général, recherchez le paramètre Nombre de sous-processus ; sa valeur par défaut est ‘0’. Cela signifie que tous les coeurs de CPU sont disponibles. Cela permet d'exécuter deux fois plus de threads qu'il n'y a de coeurs.

Si vous souhaitez que le système de compilation utilise presque toutes les ressources disponibles sans les monopoliser complètement, définissez la valeur sur -1. Un coeur de moins que la valeur par défaut ‘0’ sera utilisé. Ce paramètre ne doit être utilisé que si vous voulez faire autre chose pendant la compilation et constatez que les autres processus ralentissent.

Vous pouvez aussi définir ce paramètre sur une valeur entière positive. Selon le nombre de coeurs disponibles, le système utilisera jusqu'au nombre spécifié. Si le nombre de coeurs spécifié dépasse le nombre de coeurs dont vous disposez, il utilisera simplement le maximum de coeurs possibles.

La même valeur peut être définie en invoquant directement le compilateur avec le paramètre de ligne de commande {{{1}}}.

Nous vous recommandons d'utiliser la valeur 0 (la valeur par défaut). Elle permet de saturer la CPU et d'obtenir une vitesse de compilation maximale.

Prise en charge C++23

A partir de RAD Studio Florence 13.0, le compilateur C++Builder amélioré par Clang-20 intègre la prise en charge de C++23.

Le nouveau compilateur amélioré par Clang propose une prise en charge robuste du langage C++23, alors que libc++ fournit un grand nombre de fonctionnalités C++23. Avec la plate-forme Win64 Moderne, les nouveaux projets C++ sont par défaut en C++23. Si vous recherchez des fonctionnalités qui ne sont plus disponibles dans C++23, vous pouvez permuter vers une version plus ancienne dans les paramètres de compilation C++ situés dans Projet > Options > Construction > Compilateur C++

Pour de plus amples informations sur clang et la prise en charge de libc++ pour les fonctionnalités C++23, consultez les liens suivants :

Différences entre les différentes versions du compilateur

A partir de RAD Studio 13 Florence, la chaîne d'outils C++ Win64 Moderne utilise Clang version 20.

Cette section décrit les différences entre les versions 15 et 20 du compilateur.

Remarque: RAD Studio Athens 12 est fourni avec la version 15 de Clang.

La version 20 du compilateur BCC64X moderne applique strictement les règles de compilation C99 lorsqu'elle compile du code C, ce qui provoque des erreurs au lieu des avertissements.

Fonctions implicites

L'appel d'une fonction définie implicitement sans prototype provoque un message d'erreur.

Exemple:

int test2()
{
 return implicit_function();
}

L'exemple de code ci-dessus produit deux résultats distincts.

Compilateur Version 15 :

Warning W4856 stricter_c.c 10(10): call to undeclared function 'implicit_function'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]

Compilateur Version 20 :

Error E5430 stricter_c.c 10(10): call to undeclared function 'implicit_function'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration].

int implicite

L'appel d'un int implicite provoque un message d'erreur.

Exemple:

test1()
{
 return 42;
}

L'exemple de code ci-dessus produit deux résultats distincts.

Compilateur Version 15 :

Warning W4884 stricter_c.c 1(1): type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int [-Wimplicit-int].

Compilateur Version 20 :

Error E5464 stricter_c.c 1(1): type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int [-Wimplicit-int].

Pointeurs de fonction incompatibles

Voici un exemple de code qui combine des pointeurs de fonction incompatibles.

Exemple:

int callback(int a, int b) {
 return a+b;
}

int call_callback(int (*callback)(int)) {
 return callback(5);
}

int test3() {
 return call_callback(callback);
}

L'exemple de code ci-dessus a généré un avertissement avec l'ancien compilateur. Avec le compilateur moderne, c'est un message d'erreur qui est généré.

Compilateur Version 15 :

Warning W4971 stricter_c.c 23(24): incompatible function pointer types passing 'int (int, int)' to parameter of type 'int (*)(int)' [-Wincompatible-function-pointer-types]

Compilateur Version 20 :

Error E5558 stricter_c.c 23(24): incompatible function pointer types passing 'int (int, int)' to parameter of type 'int (*)(int)' [-Wincompatible-function-pointer-types]

Problèmes connus

Les composants provenant de packages créés pour WIN64X à l'aide de projets Delphi doivent être d'abord activés pour cette plate-forme. Pour activer les composants pour la plate-forme Windows 64 bits (Moderne), reportez-vous aux instructions sur Construction de packages Delphi pour C++.

Remarque: Le problème ne se produit que pour les projets existants. Les projets nouvellement créés ne sont pas concernés.

Pour plus d'informations, voir http://delphi.org/2013/09/debugging-against-a-remote-android-emulator/.

Voir aussi