Sous Linux, la compilation croisée fait référence à la génération de code exécutable sur une plate-forme sur une autre plate-forme, c'est-à-dire que la plate-forme de compilation du code source et la plate-forme d'exécution du programme compilé du code source sont deux plates-formes différentes. Raisons d'utiliser la compilation croisée : 1. Le système cible n'a pas la capacité de compiler nativement dessus ; 2. La plate-forme capable de compiler le code source est différente de la plate-forme cible ;
L'environnement d'exploitation de ce tutoriel : système linux5.9.8, ordinateur Dell G3.
Compilation croisée
Ce qu'on appelle "Cross_Compile" signifie que la plateforme de compilation du code source et la plateforme d'exécution du programme compilé du code source sont deux plateformes différentes. Par exemple, sous la plateforme architecture Intel x86/Linux (Ubuntu), le fichier exécutable généré à l'aide de la chaîne d'outils de compilation croisée s'exécute sous l'architecture ARM/Linux.
En termes simples, il s'agit de générer du code exécutable sur une plateforme sur une autre plateforme. La même architecture peut exécuter différents systèmes d'exploitation ; de la même manière, le même système d'exploitation peut également fonctionner sur différentes architectures.
La compilation croisée est relativement compliquée et les problèmes suivants doivent être pris en compte :
Architecture CPU : telle que ARM, x86, MIPS, etc.
Ordre des octets : big-endian et Little-endian ;
Prise en charge des nombres à virgule flottante ;
Application Binary Interface (ABI)
Pourquoi utiliser la compilation croisée ? Il y a deux raisons principales :
Le système cible de la compilation croisée a généralement une petite mémoire, un équipement d'affichage médiocre, voire inexistant, et n'a pas la capacité de compiler localement dessus
Une plate-forme qui en a la capacité ; pour compiler le code source L'architecture du processeur ou du système d'exploitation est différente de la plate-forme cible ;
La chaîne d'outils de compilation croisée est un outil essentiel pour la compilation croisée et une compétence que les développeurs embarqués doivent maîtriser avec compétence.
Pourquoi la compilation croisée est-elle difficile ?
La compilation native portable est difficile.
La plupart des programmes sont développés sur du matériel x86 et compilés nativement. La compilation croisée peut rencontrer deux types de problèmes : des problèmes avec le programme lui-même et des problèmes avec le système de build.
La première catégorie de problèmes affecte toutes les cibles non x86, y compris les builds natifs et cross-build. La plupart des programmes font des hypothèses sur le type de machine sur laquelle ils s'exécutent, qui doivent correspondre à la plate-forme concernée, sinon le programme ne fonctionnera pas. Les hypothèses courantes incluent :
Taille du mot - copier des pointeurs vers int peut perdre des données sur les plates-formes 64 bits, déterminer la taille de malloc en multipliant par 4 au lieu de sizeof(long) est mauvais. Un dépassement d'entier entraîne une vulnérabilité de sécurité mineure, comme "if (x+y
Endianness - Différents systèmes stockent les données binaires en interne de différentes manières, et la lecture de données int ou float à partir d'un disque ou d'un réseau peut nécessiter une conversion.
Alignement - Certaines plates-formes (telles que arm) ne peuvent lire ou écrire que des entiers à partir d'adresses qui sont même des multiples de 4 octets, sinon une erreur de segmentation se produira. Le traitement des données alignées et non alignées est plus lent et le compilateur remplit généralement les variables d'alignement de la structure. Traiter les structures comme des blocs de données pouvant être envoyés sur disque ou sur le réseau nécessite un travail supplémentaire pour garantir une représentation cohérente.
Signature par défaut - Le type de données "char", qui est par défaut signé ou non signé, varie d'une plateforme à l'autre (d'un compilateur à l'autre), conduisant à des bugs très surprenants. La solution de contournement simple consiste à fournir un paramètre de compilateur tel que "-funsigned-char" qui force la valeur par défaut à une valeur connue.
NOMMU - Si la plateforme cible ne dispose pas d'unité de gestion de mémoire, quelques éléments sont à modifier. Nécessite vfork(), pas fork(), uniquement certains types de travail mmap() (partagé ou en lecture seule, mais pas de copie sur écriture), la pile ne se développe pas dynamiquement.
La plupart des packages visent à être portables lorsqu'ils sont compilés localement et accepteront au moins les correctifs résolvant l'un des problèmes ci-dessus (à l'exception des problèmes NOMMU) soumis à la liste de diffusion de développement appropriée.
Puis compilation croisée.
En plus des problèmes liés à la compilation native, la compilation croisée présente son propre ensemble de problèmes :
Problèmes de configuration - packages avec des étapes de configuration distinctes (section "./ configure" de l'installation standard ), teste généralement des éléments tels que l'ordre des octets ou la taille des pages, et est portable lorsqu'il est compilé de manière native. Lors de la compilation croisée, ces valeurs diffèrent entre le système hôte et le système cible, et l'exécution du test sur le système hôte donne des réponses incorrectes. Lorsque la cible ne dispose pas du progiciel ou que la version est incompatible, la configuration détecte s'il existe une prise en charge du progiciel sur l'hôte.
HOSTCC vs TARGETCC - Le processus de construction nécessite une compilation pour s'exécuter sur le système hôte, comme les tests configurés ci-dessus, ou un programme qui génère du code (comme un programme C qui crée un fichier .h, #inclus lors de la construction principale) . Remplacez le compilateur hôte par le compilateur cible, cassant ainsi la bibliothèque d'exécution pendant le processus de construction. Une telle bibliothèque nécessite un accès aux compilateurs hôte et cible et doit être spécifiée quand l'utiliser.
Fuite de la chaîne d'outils - Une chaîne d'outils de compilation croisée mal configurée fait fuir une partie du contenu du système hôte dans le programme compilé, provoquant des pannes souvent faciles à détecter, mais difficiles à diagnostiquer et à corriger. La chaîne d'outils peut inclure les mauvais fichiers d'en-tête ou rechercher les mauvais chemins de bibliothèque lors de la liaison. Les bibliothèques partagées dépendent souvent d'autres bibliothèques partagées, ce qui peut potentiellement introduire des références de temps de liaison inattendues au système hôte.
Bibliothèques - Les programmes liés dynamiquement doivent accéder aux bibliothèques partagées appropriées au moment de la compilation. La bibliothèque partagée du système cible doit être ajoutée à la chaîne d'outils de compilation croisée afin que le programme puisse s'y connecter.
Tests - Sur les versions natives, le système de développement fournit un environnement de test pratique. Lors d'une compilation croisée, confirmer que la construction "hello world" a réussi peut nécessiter la configuration (au moins) du chargeur de démarrage, du noyau, du système de fichiers racine et des bibliothèques partagées.
Note de bas de page 1 : La différence la plus significative entre les types d'ordinateurs est le processeur qui exécute le programme, d'autres différences incluent la bibliothèque ABI (telle que glibc vs uClibc), les machines avec endianité configurable (bras avec armeb), ou un mode de machine différent pouvant exécuter du code 32 bits et 64 bits (comme x86-64 sur x86).
Note 2 : Lors de la construction d'un compilateur, le troisième type est appelé « croix canadien », un compilateur croisé qui ne s'exécute pas sur le système hôte. Canadian Cross-Build est un compilateur qui s'exécute sur une plate-forme cible et génère du code sur une autre machine cible. Créez d’abord un compilateur croisé temporaire de l’hôte vers la première cible et, en tant que deuxième cible, créez un autre compilateur croisé pour créer un tel compilateur externe. La cible du premier compilateur croisé devient la machine hôte sur laquelle le nouveau compilateur s'exécutera, et la deuxième cible est la plate-forme sur laquelle le nouveau compilateur générera la sortie. Cette technique est souvent utilisée pour compiler de manière croisée un nouveau compilateur natif pour la plateforme cible.
Note 3 : Les systèmes de bureau modernes sont suffisamment rapides pour que l'émulation de cibles compilées nativement sous l'émulateur soit en fait une stratégie viable. Beaucoup plus lent que la compilation croisée, nécessite de trouver ou de générer un environnement de build natif pour la cible (un compilateur croisé doit de toute façon être configuré), peut planter en raison de différences entre l'émulateur et le matériel réel à déployer.
Note 4 : Les chaînes d'outils de compilation croisée ont tendance à préfixer les noms de leurs utilitaires, comme "armv5l-linux-gcc". S'ils sont simplement appelés "gcc", les compilateurs hôte et natif ne peuvent pas être dans $PATH en même temps.
Recommandations associées : "Tutoriel vidéo Linux"
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!