Rust: Lien avec LLD

Créé le 17 févr. 2017  ·  94Commentaires  ·  Source: rust-lang/rust

LLVM 4.0 est livré avec LLD activé, bien que AFAIK ne soit pas encore prêt pour la production sur toutes les plateformes. Je pense que nous avons une mise à niveau LLVM prévue bientôt pour résoudre les problèmes AVR/emscripten de toute façon, il est donc temps de commencer à déterminer ce que nous pourrions devoir faire pour le prendre en charge, comment cela affecte les performances du compilateur/taille binaire/performances d'exécution par rapport à notre les linkers habituels, et les plateformes sur lesquelles nous pourrions vouloir l'activer par défaut.

Statut actuel (2020-04-24) résumé sur https://github.com/rust-lang/rust/issues/39915#issuecomment -618726211

A-linkage C-feature-request I-compiletime T-compiler

Commentaire le plus utile

Ce bug est un peu le bordel, alors voici mon meilleur coup pour un bref résumé de la situation actuelle, pour les gens qui veulent faire avancer les choses.

Qu'est-ce que lld

Un éditeur de liens faisant partie du projet llvm, ce qui est souhaitable pour deux raisons :

  • c'est très convivial pour la compilation croisée (d'où son accent sur les cibles embarquées)
  • c'est très rapide (s'exécute souvent en deux fois moins de temps que Gold - la liaison peut prendre plusieurs minutes pour les gros projets (rustc, servo, etc.) et la liaison peut représenter un pourcentage énorme de la compilation avec des versions incrémentielles, donc diviser par deux Grosse affaire.)

Ce que Rust fait avec lld aujourd'hui

  • Rust envoie actuellement sa propre copie de lld sur la plupart des plates-formes en tant que binaire qu'il appelle rust-lld
  • rust-lld est utilisé par défaut sur de nombreuses cibles bare-metal
  • rust-lld est utilisé par défaut pour wasm
  • (?) vous pouvez explicitement demander à rouille-lld d'être utilisé en utilisant "-C linker-flavor" (flou sur ce que cela fait exactement sur les plates-formes non bare-metal, voir ci-dessous)

Problèmes d'utilisation de rust-lld dans plus d'endroits (c'est-à-dire de bureau linux/mac/windows)

  • Le backend macOS (Mach-O) pour lld est cassé et abandonné

    • une réécriture à partir de zéro a commencé, mais c'est le début

  • Sur les plateformes linux/unix, vous n'êtes pas censé invoquer directement ld/lld. Vous êtes censé invoquer l'éditeur de liens via votre compilateur système c (c'est-à-dire gcc), dont la responsabilité est de découvrir les symboles système comme crt1.o et de les fournir à ld. Cela signifie que nous ne pouvons pas « simplement » utiliser rust-lld ; nous devons l'alimenter dans gcc/clang/whatever. (nous ne voulons pas implémenter nous-mêmes cette logique de symbole système)

    • En général, vous ne pouvez pas fournir l'éditeur de liens comme chemin, vous devez l'injecter dans le chemin de recherche du compilateur C en tant que "ld"

    • Alternativement, vous pouvez faire la même chose mais l'injecter en tant que "ld.lld", et passer "-fuse-ld=lld"



      • Cela peut être important, apparemment, lld effectue une détection de nom binaire de style clang pour savoir s'il est exécuté en tant que "ld" ou "ld.lld" (nécessite une enquête)


      • Malheureusement, -fuse-ld=lld n'est qu'une partie de GCC 9, nous pouvons donc nécessiter une détection de fonctionnalité/version pour l'utiliser (clang l'a depuis longtemps)



  • windows-msvc est apparemment en bon état et semble avoir un support limité pour l'utilisation de rust-lld dans le backend, mais je ne sais pas ce qui doit être fait ici.
  • windows-mingw semble être à peu près au même endroit que linux/unix, sauf que vous êtes susceptible d'obtenir un ancien GCC, et les choses sont un peu bancales parce que pseudo-windows-linux n'est pas exactement une configuration bien testée ?

De plus, en général, lld est plus récent, ce n'est pas la valeur par défaut pour la plupart des systèmes d'exploitation, des bogues de compatibilité aléatoires vont presque certainement apparaître si nous commençons à l'utiliser dans plus d'endroits.

J'ai déposé deux métabugs pour des efforts concentrés sur l'utilisation de (rust-)lld par défaut sur deux plates-formes :

  • #71515 - x64 Ubuntu 20.04 LTS (et plus largement toutes les plateformes x64 ELF)
  • #71520 - Fenêtres msvc x64

Tous les 94 commentaires

Voir aussi un PoC au n°36120.

LLD peut être un très bon candidat pour les cibles MinGW, car nous regroupons actuellement un éditeur de liens avec eux de toute façon et l'éditeur de liens de MinGW a une variété de problèmes allant d'un manque d'ASLR à l'absence de support bigobj. Si nous pouvons d'une manière ou d'une autre apporter les bibliothèques mingw nécessaires lors de la compilation croisée et pas seulement le ciblage natif (auquel le package mingw de Rustup est actuellement limité), alors cela permettrait la compilation Rust Cross à partir de Linux, ce qui serait une énorme amélioration sur la situation existante où les gens obtiennent MinGW de leur distribution, puis rencontrent des problèmes car les distributions utilisent presque toujours un MinGW incompatible.

LLD n'est pas un bon candidat pour cibler nativement les cibles MSVC, pour plusieurs raisons, la principale raison étant le manque de prise en charge de debuginfo. La compilation croisée vers des cibles MSVC nécessite des bibliothèques qui ne peuvent pas être redistribuées, nous ne pouvons donc pas prendre en charge cela de toute façon.

Le problème de suivi pour la mise à niveau vers LLVM 4.0 est https://github.com/rust-lang/rust/issues/37609 .

Pour mémoire, lld n'est définitivement pas prêt pour les cibles Solaris. Mais sur Solaris, à ma connaissance, il n'y a aucune raison d'utiliser lld au lieu du ld natif. Nous avons déjà examiné ce qu'il faudrait pour que rust utilise Solaris ld sur Solaris au lieu d'utiliser gcc pour la liaison.

@binarycrusader Une des raisons d'utiliser lld est lors de la construction pour Solaris, pas sur Solaris.

PR rust-lang/rust#40018 ajoute un indicateur -Z linker-flavor à rustc pour permettre d'utiliser LLD comme éditeur de liens. Ce PR n'intègre pas LLD dans rustc mais permet de l'expérimenter en dehors de l'arbre.

@binarycrusader ^ cela peut vous aider dans votre expérience d'utilisation directe du ld de Solaris au lieu de gcc.

Nous semblons maintenant fonctionner sur LLVM 4.0. @japaric , cela signifie-t-il que l'indicateur de saveur de l'éditeur de liens peut désormais être facilement utilisé pour comparer et contraster LLD avec l'éditeur de liens système ?

@bstrie #40018 a débarqué il y a quelques semaines. Depuis ce débarquement, on a pu utiliser -Z linker-flavor=ld -C linker=ld.lld pour utiliser un binaire LLD externe comme éditeur de liens. Notez que, contrairement à gcc, LLD ne sait pas où se trouvent les bibliothèques système, vous devrez donc transmettre le chemin de recherche de la bibliothèque à l'éditeur de liens en utilisant -C link-args='-L ...' si vous vous connectez à une bibliothèque système.

Ce que LLVM 4.0 aide, c'est à fusionner LLD dans rustc. Avec ce changement, nous n'aurions pas besoin d'un éditeur de liens externe dans certains scénarios, comme la liaison de binaires MUSL ou de programmes bare metal. Je dis certains scénarios car la plupart des cibles nécessitent une liaison aux bibliothèques système où vous rencontrerez le problème de chemin de recherche de bibliothèque que j'ai mentionné ci-dessus. Pour ces cibles, LLD ne fonctionnera pas immédiatement. On ne sait pas comment et où résoudre ce problème et sans solution pour cela, nous ne pouvons pas passer à LLD pour les cibles les plus importantes (niveau 1), ce qui réduit l'attrait d'intégrer LLD dans rustc en premier lieu.

@japaric Quels sont les arguments contre l'intégration des chemins de recherche (bibliothèque relative à sysroot), ainsi que des choses comme -lc -lpthread crt0.o , directement dans rustc ? Après tout, certains composants de la chaîne d'outils doivent les intégrer car nous n'avons aucune norme à suivre pour les plates-formes, et binutils n'est pas une bonne source d'or de cette connaissance.

Le seul inconvénient auquel je peux penser est la situation où le même triple aurait des chemins de recherche différents sur différentes versions de systèmes (ce qui sera probablement exclusif aux triples Linux/glibc, et particulièrement mauvais sur les plates-formes avec multilib). Dans ce cas, je pense que clang fouine le nom du système d'exploitation et code en dur les conventions spécifiques au système d'exploitation, ce qui semble mauvais mais probablement inévitable si l'on veut distribuer un seul binaire qui s'exécute sur n'importe quel Linux (et n'a pas besoin de l'éditeur de liens système).

@ retep998 J'ai

J'espère que je me trompe.

Marquer cela comme un bogue de performances, car selon les benchmarks de LLD, il semble surpasser GNU ld d'un facteur dix, et les performances de liaison sont actuellement un élément important de la vitesse du compilateur.

Euh, j'ai oublié de lier les benchmarks : https://lld.llvm.org/#performance

(Pertinent aujourd'hui puisque LLVM 5.0 vient de sortir.)

La liaison avec LLD est beaucoup plus rapide que bfd ou gold, mais je doute que son utilisation améliore considérablement les performances globales. Pourtant, je pense que cette question est importante et devrait être une priorité.

@tpimh En fait, je ne suis pas tout à fait sûr que la balise I-slow soit censée représenter des bogues de performances d'exécution ou des bogues de performances de compilation, je l'entendais comme ce dernier. Et IME, quand je regarde le temps de liaison de sortie, se situe généralement dans les trois phases les plus longues, beaucoup plus longues que la plupart, donc même réduire de moitié le temps de liaison serait probablement une énorme victoire (en particulier pour les grandes choses comme Servo et rustc).

@bstrie I-slow est pour les mauvaises performances d'exécution, I-compiletime est pour les performances du compilateur la dernière fois que j'ai vérifié

Bonne nouvelle pour quiconque s'intéresse au sujet obscur de la réticulation de Linux à Windows. J'ai dit plus tôt que ce n'était pas possible avec lld, mais cela n'est vrai que pour la saveur ld de lld. C'est possible pour la saveur link.exe de lld (lld-link).

Spécifiquement pour Rust, nous pouvons le faire aujourd'hui avec quelques modifications de code.

  1. Nous devons compiler un très petit sous-ensemble du CRT de mingw-w64 dans des fichiers objet .o. À savoir certains threads init de stockage local. Nous avons également besoin de chkstk.

  2. lld n'aime pas les bibliothèques d'importation habituelles de MinGW. Au lieu de cela, nous devons créer nous-mêmes les fichiers .def dans les fichiers .lib, en utilisant lld-link ou llvm-dlltool

  3. Modifiez lld pour traiter IMPORT_NAME_NOPREFIX comme
    IMPORT_NAME_UNDECORATE, car même avec l'étape 2, les .libs ne sont pas parfaits

  4. Modifiez le seh.rs de Rust pour remplacer TYPE_INFO_VTABLE par ptr::null(). Obligatoire car le symbole ??_7type_info@@6B@ n'est pas défini dans MinGW. Ensuite, construisez et installez Rust.

  5. Utilisez .cargo/config pour spécifier un script wrapper personnalisé en tant qu'éditeur de liens.

  6. Notre script wrapper linker doit appeler lld-link principalement en utilisant les paramètres qui lui sont transmis. Cependant, nous devons faire quelques ajustements:

    a) Corrigez la casse du nom de fichier, par exemple, remplacez AdvAPI32.Lib par advapi32.lib

    b) Modifiez le fichier .def généré par Rust pour préfixer les symboles avec un trait de soulignement supplémentaire

    c) Ignorer le point d'entrée (/entry). Obligatoire probablement en raison d'un problème de nommage.

    d) Ajoutez les fichiers objet mingw-crt que vous avez compilés à l'étape 1

  7. Construisez votre projet Rust en utilisant xargo --target=i686-pc-windows-msvc

Faire les étapes ci-dessus me permet de croiser le code Rust. Je peux même paniquer et attraper des paniques en utilisant le déroulement basé sur SEH de Rust.

@iainnicol Vous mélangez la cible msvc avec des bits MinGW, c'est pourquoi vous devez faire toutes ces modifications étranges. Si vous copiez simplement les bibliothèques d'une installation VC++ existante, vous pouvez utiliser normalement lld-link sans toutes ces modifications ni aucun bit MinGW.

Mais je ne veux pas utiliser une installation VC++ existante. Il n'y a même aucun moyen d'en obtenir un sans passer quelque chose comme huit heures à télécharger et à installer des fichiers indésirables, encore moins à redistribuer.

Les outils de construction autonomes sont beaucoup plus légers, à moins que ce ne soit déjà ce à quoi vous faites référence, auquel cas nous devrions peut-être travailler pour améliorer ou recréer ce que MinGW a fait afin qu'il soit réellement compatible avec MSVC.

Les outils de construction autonomes sont beaucoup plus légers

Je n'ai pas réalisé que Microsoft les distribue. Pourriez-vous créer un lien vers eux ? Existe-t-il un moyen raisonnable d'extraire l'archive d'installation sans l'exécuter, c'est-à-dire est-ce un msi ou quelque chose de similaire?

Les voici : http://landinghub.visualstudio.com/visual-cpp-build-tools

Les versions 2015 et 2017 sont des exe, mais vous pourrez peut-être convaincre l'exe 2017 de vous donner ce que vous voulez via ceci : https://docs.microsoft.com/en-us/visualstudio/install/install-vs- réseau-qualité-incohérent

Si nous voulons vraiment faire cela correctement pour Windows, nous aurions tout d'abord besoin de https://github.com/rust-lang/rust/issues/30027 pour éliminer le besoin du SDK Windows ou des bibliothèques d'importation de MinGW. Ensuite, il ne nous resterait plus qu'à remplacer les bits CRT par nos propres versions pures de Rust (fonctions mathématiques/mémoire, point d'entrée, quelques autres bits d'exécution dont Rust a besoin) et nous aurions une chaîne d'outils Rust entièrement autonome qui peut créez des binaires Windows ! L'inconvénient de ceci est que vous ne seriez pas en mesure de lier statiquement du code C/C++ car cela dépend très fortement de la liaison dans le CRT approprié à partir de MinGW ou de VC++. Bien sûr, tout l'intérêt de Rust est de tout réécrire dans Rust, donc ce n'est pas vraiment un problème.

Bonne nouvelle pour quiconque s'intéresse au sujet obscur de la réticulation de Linux à Windows. J'ai dit plus tôt que ce n'était pas possible avec lld, mais cela n'est vrai que pour la saveur ld de lld. C'est possible pour la saveur link.exe de lld (lld-link).

On dirait que cela devrait maintenant être possible avec la saveur ld : https://reviews.llvm.org/rL312926

Le nouveau pilote compatible MinGW de lld est un wrapper de l'éditeur de liens lld-link. Il traduit en interne les options Unix en options Windows, puis appelle le point d'entrée de lld-link. Je ne sais pas si vous voulez l'utiliser car (sauf que le pilote wrapper est incomplet et n'est pas prêt à l'emploi), cela ne semble pas faciliter les choses à moins que vous n'ayez déjà Makefiles pour MinGW.

J'ai une question (probablement idiote) à vous poser à propos de la compilation croisée. Sous Windows, tous les symboles importés par dll ont des noms de DLL à partir desquels ils sont importés. Si vous n'avez pas de fichiers de bibliothèque MSVC, comment savoir à partir de quels fichiers les symboles importés sont importés ?

J'ai une question (probablement idiote) à vous poser à propos de la compilation croisée. Sous Windows, tous les symboles importés par dll ont des noms de DLL à partir desquels ils sont importés. Si vous n'avez pas de fichiers de bibliothèque MSVC, comment savoir à partir de quels fichiers les symboles importés sont importés ?

Si vous n'avez pas de bibliothèques d'importation, vous devez soit créer des bibliothèques d'importation, soit implémenter https://github.com/rust-lang/rust/issues/30027 afin que winapi puisse faire tout le dur travail de spécification de la DLL d'où provient chaque symbole, ainsi que la folie comme les ordinaux. Quelque chose doit spécifier le mappage des symboles au moment de la liaison avec les symboles/ordinaux dans les DLL, qu'il s'agisse de bibliothèques d'importation ou d'annotations dans votre code.

Après avoir extrait https://reviews.llvm.org/rL311734, je suis presque capable d'amorcer rustc à l'aide de lld sur macOS. Il semble y avoir un problème avec les métadonnées dylib, que je dois encore enquêter.

J'ai une branche qui ressuscite https://github.com/rust-lang/rust/pull/36120; puisque nous avons besoin de ce correctif (très récent) lld, celui-ci est bloqué sur https://github.com/rust-lang/rust/issues/43370.

@tamird : #43370 a été fermé.

LLD a été ajouté dans https://github.com/rust-lang/rust/pull/48125 et est désormais livré avec les plates-formes de niveau 1 (mac, linux, windows). Vous pouvez le tester avec -Z linker-flavor pour chaque plate-forme, bien qu'il soit peu probable qu'il fonctionne pour la plupart des plates-formes par défaut. Cela fonctionne, cependant, par défaut sur MSVC. Par exemple:

$ RUSTFLAGS='-Z linker-flavor=lld-link' cargo build

réduit le temps de liaison de Cargo de 2,5 s à 1,5 s, une belle amélioration !

@alexcrichton , quelles sont les prochaines étapes ? Idéalement, nous aurions LLD fonctionnant par défaut sur toutes les plates-formes (je n'ai aucune idée de la quantité de travail que cela prendra), puis j'aimerais exécuter des benchmarks de compilation/d'exécution pour voir s'il est logique de faire de LLD la valeur par défaut sur toutes les plateformes. Surtout avec la compilation incrémentielle, les performances de liaison vont être plus importantes que jamais.

Surtout avec la compilation incrémentielle, les performances de liaison vont être plus importantes que jamais.

C'est dommage que les performances de liaison ne soient toujours pas assez importantes pour que nous puissions faire des choses comme activer la liaison incrémentielle sur les plates-formes qui la prennent en charge. https://github.com/rust-lang/rust/issues/37543

@bstrie Je suppose que ce sont les prochaines étapes, le faire fonctionner sur d'autres plates-formes :)

Quant à ce que cela implique, je ne suis pas sûr, mais cela fonctionne déjà sur MSVC, je pense que c'est loin de fonctionner sur MinGW/Linux, et nous sommes assez proches sur OSX. En ce qui concerne la prise en charge de l'architecture croisée, je ne suis pas sûr non plus. Je ne m'attends pas à ce que nous le "stabilisions" pour autre chose que la plate-forme wasm dans un proche avenir.

@alexcrichton Puis-je vous demander comment spécifieriez-vous « stabiliser » ? Pourquoi ne serait-il pas possible de « stabiliser » la liaison avec lld pour les autres principales plates-formes supportant la rouille ? (par exemple, la compilation croisée d'un exécutable à partir de Linux pour macOS).

À l'heure actuelle, la compilation croisée est tellement pénible, par exemple le travail nécessaire pour compiler un exécutable pour macOS (x86_64-apple-darwin) à partir de Linux nécessite des étapes non triviales comme l'acquisition du SDK xcode et la construction de l'ensemble de la chaîne d'outils.

@cynecx une bonne question ! Un auquel je n'ai pas beaucoup pensé. Je pense, cependant, que nous ne voulons pas stabiliser de facto LLD simplement parce que nous l'avons ajouté pour une autre plate-forme, il faudra du temps et du travail pour bien faire les choses et bien les exposer.

par exemple, le travail nécessaire à la compilation croisée d'un exécutable pour macOS (x86_64-apple-darwin) à partir de Linux nécessite des étapes non triviales telles que l'acquisition du SDK xcode et la création de l'ensemble de la chaîne d'outils.

LLD n'aiderait pas vraiment ici, vous avez toujours besoin du SDK Xcode car il a des en-têtes que vous ne pouvez pas redistribuer (et selon ce que vous construisez, vous aurez également besoin d'autres outils SDK).

Ce qui est vraiment bien dans le fait que LLD soit désormais intégré tous les soirs, c'est que vous pouvez facilement compiler de manière croisée des projets Rust purs de Windows à Linux avec RUSTFLAGS='-Z linker-flavor=ld.lld' cargo build --target x86_64-unknown-linux-musl . Idéal pour écrire de petits outils pour les machines Linux sur lesquelles vous ne pouvez pas simplement installer Rust.

Je ne m'attends pas à ce que nous le "stabilisions" pour autre chose que la plate-forme wasm dans un proche avenir.

Comme l'a dit @rkarp , un cas d'utilisation très courant consiste à cibler x86_64-unknown-linux-musl (et éventuellement steed) pour prendre en charge les charges de travail Linux conteneurisées. C'est l'une de ces choses que Go fait très bien et où nous semblons être très proches de Rust pouvant faire de même. En termes d'utilisation réelle, je parie que LLD pour x86_64-unknown-linux-musl serait en fait utilisé beaucoup plus largement que wasm.

Plus généralement, lorsqu'il s'agit de cross-building, je ne pense pas qu'une approche « ça doit fonctionner pour tous les hôtes et/ou toutes les cibles » ait du sens. Je pense qu'il est logique de stabiliser cela cible par cible à mesure que les cibles commencent à fonctionner.

En particulier, j'aimerais contribuer à l'effort pour obtenir LLD pour la cible x86_64-unknown-linux-musl stabilisé dès que possible.

Mon projet a 37 caisses, et le build lie environ 70 binaires (beaucoup de tests). De manière non scientifique (en regardant top ) au moins la moitié du temps de construction, nous n'exécutons que ld. Je m'attends à ce que l'utilisation de lld accélère considérablement nos constructions. Nous sommes sur Rust stable et je n'ai pas encore réussi à faire fonctionner lld 6.0.

@briansmith avez-vous testé LLD pour musl et votre cas d'utilisation ? En théorie, tout ce que vous auriez besoin de faire pour le tester est de passer -Z linker-flavor=ld.lld , et si cela fonctionne semble plausible, nous pourrions changer les valeurs par défaut !

@rocallahan juste pour confirmer, vous utilisez tous l'éditeur de liens en or actuellement, n'est-ce pas ? (comme je le dis, c'est plus rapide que l'éditeur de liens binutils standard). Si -Z linker-flavor=ld.lld fonctionne (et est plus rapide), alors nous pourrions peut-être chercher à le stabiliser ! C'était sur quelle plateforme ?

De manière non scientifique (en haut), au moins la moitié du temps de construction, nous n'exécutons que ld.

C'est pour une version de débogage BTW.

vous utilisez tous l'éditeur de liens en or actuellement, n'est-ce pas ? (comme je le dis, c'est plus rapide que l'éditeur de liens binutils standard)

Non, c'est l'éditeur de liens système Fedora, l'éditeur de liens GNU standard.

C'était sur quelle plateforme ?

Fedora 27, ordinateur portable Skylake quadricœur avec SSD. Je vais obtenir des chiffres de performance.

Ah ok bon à savoir ! Les versions de débogage tireront probablement le meilleur parti du temps de liaison du nain divisé (https://github.com/rust-lang/rust/issues/34651) plutôt que des améliorations de l'éditeur de liens.

Pour plus d'informations sur le timing, @rocallahan si vous en avez l'occasion, testez avec ld.gold et ld.lld ?

Sûr. Je dois également rappeler que le problème #48762 est très simple pour accélérer les temps de liaison de débogage Linux. (Nous utilisons déjà un script d'éditeur de liens piraté qui supprime .debug_pubnames / .debug_pubtypes de l'exécutable.)

Split DWARF peut être une bonne chose, mais cela peut aussi causer des problèmes aux utilisateurs. Je ferai un commentaire dans ce numéro.

@briansmith avez-vous testé LLD pour musl et votre cas d'utilisation ? En théorie, tout ce que vous auriez besoin de faire pour le tester est de passer -Z linker-flavor=ld.lld, et si cela fonctionne semble plausible, nous pourrions changer les valeurs par défaut !

OK, je vais tester les choses. Peut-être qu'au départ, il devrait y avoir un juste milieu entre "par défaut" et "uniquement tous les soirs", un moyen d'opter pour l'utilisation de LLD comme nous le pouvons avec -Z , mais sans utiliser -Z pour que cela fonctionne dans les constructions stables.

mais sans utiliser -Z pour que cela fonctionne dans les versions stables.

Vous pouvez essayer RUSTC_BOOTSTRAP=1 RUSTFLAGS="-Z linker-flavor=foo" cargo build

S'il vous plaît, ne recommandons pas le drapeau bootstrap ? Je crains que si suffisamment de projets en dépendent, les choses deviendront de facto stables, vainquant ainsi tout le mécanisme de stabilité.

Désolé =/

En tant que point de données, la liaison de la caisse rustc_trans dans le référentiel Rust lui-même est passée d'un temps de liaison de 78 s à un temps de liaison de 1 s sur ma machine locale.

Ma performance résulte de la modification d'un espace blanc dans une caisse près du bas de notre hiérarchie de caisses. Ordinateur portable Skylake quadricœur, 16 Go de RAM, rouille 1.24.0, LLD 7.0.0, GNU ld 2.29-13. Nous utilisons un script d'éditeur de liens personnalisé qui supprime .debug_pubnames et .debug_pubtypes ; LLD utilise des chemins de code assez différents lorsqu'un script d'éditeur de liens est présent, ce qui peut affecter les choses.

ld GNU :

real    2m39.138s
user    8m18.992s
sys 1m37.513s

LLD :

real    2m19.164s
user    6m4.477s
sys 0m56.858s

L'or n'a pas fonctionné, il a vomi sur notre script d'éditeur de liens. Les résultats sont assez stables. LLD n'affecte pas beaucoup le temps de bout en bout, mais réduit considérablement l'utilisation du processeur ; Je suppose que cela signifie que notre version ne passe pas beaucoup de temps à attendre la fin de lds, mais elle passe beaucoup de temps CPU à les exécuter.

Voir #50584 pour un exemple du monde réel où le passage de GNU ld à lld fait qu'une charge de travail commune de "modification et reconstruction mineure" s'exécute plus de 2,5 fois plus rapidement.

Er https://github.com/rust-lang/rust/issues/50584#issuecomment-400918647 est plus approprié ici :


La prochaine étape pour stabiliser LLD serait d'obtenir un indicateur, comme -Z linker-flavor=lld, fonctionnant pour toutes les cibles (Windows + Mac + Linux). Il ferait tout ce qu'il faut pour fonctionner sur les différentes plates-formes.

Une fois cela fait, nous pouvons l'annoncer à la communauté, en demandant des commentaires. Ici, nous pouvons obtenir à la fois des informations de synchronisation ainsi que des rapports de bogues à envoyer à LLD. Si tout se passe bien (ce qui est un peu douteux avec un tout nouveau linker, mais bon on ne sait jamais !) on peut l'activer par défaut, sinon on peut travailler pour stabiliser la sélection de LLD puis ajouter une option à Cargo. toml afin que les projets puissent au moins s'y inscrire.

Nous sommes passés à lld pour certaines cibles : https://rust-embedded.github.io/blog/2018-08-2x-psa-cortex-m-breakage/

Je crois que pour wasm aussi?

Ce problème couvre-t-il à la fois la liaison avec un binaire lld externe et la liaison avec la prise en charge interne de lld intégrée à rustc lui-même ? Ou seulement le premier ?

Ce problème couvre-t-il à la fois la liaison avec un binaire lld externe et la liaison avec la prise en charge interne de lld intégrée à rustc lui-même ? Ou seulement le premier ?

Juste le binaire lld externe, IIUC.

@nnethercote Existe-t-il un autre problème pour le suivi de l'utilisation d'un éditeur de liens interne, ou dois-je déposer un problème distinct pour cela ?

Je n'ai jamais entendu parler de l'idée de l'éditeur de liens interne auparavant. Je ne suis pas au courant d'un PR pour cela.

https://github.com/rust-lang/rust/pull/57514 a préparé le terrain pour utiliser LLD pour lier LLVM.

Peut-être qu'au départ, il devrait y avoir un juste milieu entre "par défaut" et "uniquement la nuit", un moyen d'opter pour l'utilisation de LLD comme nous le pouvons avec -Z, mais sans utiliser -Z pour que cela fonctionne dans des versions stables.

https://github.com/rust-lang/rust/pull/56351 a ajouté -C linker-flavor .

Il n'est pas clair ce que ce problème est destiné à suivre. Il semble qu'il serait préférable de fermer cela en faveur d'avoir des problèmes spécifiques, par exemple "Lien avec LLD pour les cibles -msvc lorsque la chaîne d'outils de Microsoft n'est pas disponible".

Pour moi, ce problème concerne l'activation de LLD comme éditeur de liens par défaut pour toutes les cibles. J'aimerais cela parce que LLD est extrêmement rapide, et le temps de liaison est souvent une composante importante du temps de compilation, et la vitesse de compilation est un problème permanent.

FWIW J'ai déposé un bogue pour la prise en charge de LLD sur macOS par rapport à BMO. Apparemment, c'est WONTFIX. D'après les commentaires, il semble que ce n'est pas aussi simple que "LLD est extrêmement rapide", car les LLD sur différentes plates-formes sont des programmes différents, et celui sur macOS est interrompu avec un développement au point mort.

D'accord avec @briansmith qu'il serait bon d'avoir des problèmes dédiés pour suivre l'état de cela pour différentes cibles, bien qu'au lieu de fermer cela, nous pourrions ensuite transformer cela en un métabug. S'il y a quelqu'un qui en sait plus sur les cibles pour lesquelles il vaut la peine d'ouvrir des problèmes, n'hésitez pas, car je ne suis pas au courant du statut de support LLD.

Le lien avec LLD est-il documenté quelque part ? J'ai (sous Linux) rustc -C linker-flavor=ld.lld hello.rs , mais je n'ai pas de chance. Je pensais que LLD était distribué avec notre copie de LLVM, je me trompe ? J'ai également essayé d'installer LLD via apt, mais rustc est toujours mystifié. Quelles sont les étapes à suivre pour essayer LLD avec le code Rust aujourd'hui ?

@bstrie Vous devez en plus passer l'argument -C linker=rust-lld .

C'est censé fonctionner avec du fret ? J'obtiens actuellement les erreurs suivantes lorsque j'essaie de créer un projet vierge sur la dernière génération nocturne de rouille et de cargaison.

$ RUSTFLAGS='-C linker=rust-lld' cargo build
   Compiling rust3 v0.1.0 (/home/carado/tmp/rust3)
error: linking with `rust-lld` failed: exit code: 1
  |
  = note: "rust-lld" "-flavor" "gnu" "-L" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.2ualxzb8lqn4ho3y.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.32vfyq64cfbzv618.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.4rbt3m5y8o8cl09t.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.ben0932xzwyt64v.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.fzsdnygvstiwzxo.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.x0rq6ifodcf11zi.rcgu.o" "-o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.1m259ox4uzrzk583.rcgu.o" "--gc-sections" "-pie" "-zrelro" "-znow" "-L" "/home/carado/tmp/rust3/target/debug/deps" "-L" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--start-group" "-Bstatic" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-44988553032616b2.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-607feef6be9150b2.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace-a8dbf6d92401e34a.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace_sys-9a4716f5e8a3e722.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-988a64d96b043c6d.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-cadd6177b8c6d586.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-8f1d8efc92b45369.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-1e76014677816767.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-cc28bce38cb195d9.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-4123e9e89add689a.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-4d259c17788c1fb5.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-9495dbda85bb8f16.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-793d0026c575805f.rlib" "--end-group" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-33c3162edae6574e.rlib" "-Bdynamic" "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-lutil"
  = note: rust-lld: error: unable to find library -ldl
          rust-lld: error: unable to find library -lrt
          rust-lld: error: unable to find library -lpthread
          rust-lld: error: unable to find library -lgcc_s
          rust-lld: error: unable to find library -lc
          rust-lld: error: unable to find library -lm
          rust-lld: error: unable to find library -lrt
          rust-lld: error: unable to find library -lpthread
          rust-lld: error: unable to find library -lutil
          rust-lld: error: unable to find library -lutil


error: aborting due to previous error

error: Could not compile `rust3`.

To learn more, run the command again with --verbose.

J'obtiens les mêmes erreurs que carado. J'ai réussi à "shoehorn" -L /usr/lib dans l'invocation de l'éditeur de liens, mais cela ne fait que raccourcir la liste des bibliothèques manquées à -lgcc qui n'existe nulle part dans le système en tant que libgcc (il y a un libgcc_s.a ) Je soupçonne que c'est le résultat d'un peu de gnu-isme mais je ne sais pas comment le réparer.

@almindor essayez RUSTFLAGS='-C linker=rust-lld -L /usr/lib -L /usr/lib/gcc/x86_64-pc-linux-gnu/9.1.0' ou quelque chose de similaire. Le chemin dépendra de votre distribution et de la version du compilateur.

Mon commentaire ci-dessus est-il la bonne façon d'utiliser LLD ? Je n'arrive pas à le faire fonctionner, car chaque programme plante avec SIGSEGV :

Reading symbols from target/debug/hello...
(gdb) show directories
Source directories searched: ~/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/etc:$cdir:$cwd
(gdb) r
Starting program: target/debug/hello 

Program received signal SIGSEGV, Segmentation fault.
core::ops::function::FnOnce::call_once{{vtable-shim}} () at /rustc/a7f28678bbf4e16893bb6a718e427504167a9494/src/libcore/ops/function.rs:231
(gdb) l
226     #[stable(feature = "fn_once_output", since = "1.12.0")]
227     type Output;
228 
229     /// Performs the call operation.
230     #[unstable(feature = "fn_traits", issue = "29625")]
231     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
232 }
233 
234 mod impls {
235     #[stable(feature = "rust1", since = "1.0.0")] 
(gdb) info reg
rax            0x0                 0
rbx            0x0                 0
rcx            0x0                 0
rdx            0x0                 0
rsi            0x0                 0
rdi            0x0                 0
rbp            0x0                 0x0
rsp            0x7fffffffddb0      0x7fffffffddb0
r8             0x0                 0
r9             0x0                 0
r10            0x0                 0
r11            0x0                 0
r12            0x0                 0
r13            0x0                 0
r14            0x0                 0
r15            0x0                 0
rip            0x7ffff7ffc000      0x7ffff7ffc000 <core::ops::function::FnOnce::call_once{{vtable-shim}}>
eflags         0x10202             [ IF RF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0
(gdb) disassemble 
Dump of assembler code for function core::ops::function::FnOnce::call_once{{vtable-shim}}:
=> 0x00007ffff7ffc000 <+0>: mov    (%rdi),%rax
   0x00007ffff7ffc003 <+3>: mov    (%rax),%rdi
   0x00007ffff7ffc006 <+6>: jmpq   *0x11d4(%rip)        # 0x7ffff7ffd1e0
End of assembler dump.

Pour tous ceux qui se retrouvent ici, l'incantation magique est RUSTFLAGS="-C link-arg=-fuse-ld=lld" cargo build si vous avez GCC 9 ou Clang comme compilateur. Alternativement, -C linker=clang devrait fonctionner quelle que soit la version de GCC, il peut donc être préférable.

Pour rendre cela permanent, vous pouvez l'ajouter à ~/.cargo/config ou .cargo/config dans un projet spécifique :

[build]
rustflags = ["-C", "linker=clang"]
# rustflags = ["-C", "link-arg=-fuse-ld=lld"]

@lnicola note que cela ne fonctionne que lorsque vous utilisez GCC 9 ou Clang en tant que CC.

@bstrie savez-vous quel en est l'état actuel ? Quels sont les obstacles pour aller de l'avant ?

@ mati865 connaissez -vous une invocation alternative pour les personnes ayant un GCC plus ancien ?

@lnicola toutes mes plates-formes ont Clang + GCC 9 et je n'ai pas étudié comment l'utiliser avec des compilateurs incompatibles.

@jonhoo Je ne suis au courant d'aucun travail dans ce domaine, je suppose que vous voudriez demander à l'équipe du compilateur.

Je ne pense pas pouvoir taguer des équipes, et je ne veux pas non plus leur faire de bruit excessif. Quelle est la meilleure façon d'amener quelqu'un de là-bas à jeter un coup d'œil, selon vous ?

Triage; @rust-lang/compiler est-ce que quelqu'un sait quel est l'état actuel de ce problème ?

Pour toute personne ici qui parvient à faire fonctionner LLD avec Rust, pouvez-vous également inclure les détails de votre plate-forme et les versions spécifiques de tous les compilateurs utilisés ? Je vois toujours des gens dans la nature avoir du mal à le faire fonctionner, même avec les conseils énumérés ici.

La commande que j'ai postée ci-dessus fonctionne sous Linux avec GCC 9.2.0 et LLD 9.0.0. Je pense que cela fonctionne parfois aussi sous Windows, mais j'ai vu quelqu'un avec un GCC 9 pour Windows qui ne prenait pas en charge -fuse=lld. Sur MacOS, cela ne vaut pas la peine d'essayer, selon certains liens publiés ici.

Pour toute personne ici qui parvient à faire fonctionner LLD avec Rust, pouvez-vous également inclure les détails de votre plate-forme et les versions spécifiques de tous les compilateurs utilisés ? Je vois toujours des gens dans la nature avoir du mal à le faire fonctionner, même avec les conseils énumérés ici.

cat /etc/version-système
Fedora version 30 (Trente)

cc --version
cc (CCG) 9.2.1 20190827 (Red Hat 9.2.1-1)

ld.lld --version
LLD 8.0.0 (compatible avec les linkers GNU)

Espérons que cela aide

mais j'ai vu quelqu'un avec un GCC 9 pour Windows qui ne supportait pas -fuse=lld

@lnicola
Les versions de Windows GCC 9 prennent en charge -fuse-ld=lld (à moins qu'elles ne soient corrigées pour ne pas la prendre en charge, mais pourquoi quelqu'un le ferait-il ?).
Je suppose que le composant rust-mingw été installé et que l'éditeur de liens n'a pas été remplacé dans .cargo/config . De cette façon, Rustc a choisi GCC 6 qu'il expédie au lieu de celui du système.

Un autre problème sur Windows est l'indicateur de lien codé en dur --enable-long-section-names que LLD 9 et les versions antérieures ne prennent pas en charge (il est prévu de le prendre en charge à l'avenir). Pour contourner cela, vous pouvez :

  • créer un wrapper qui supprime ce drapeau
  • patch LLD pour accepter ce drapeau comme no-op
  • utiliser des builds Rust patchés locaux qui n'utilisent pas ce drapeau

Un autre problème sous Windows est l'indicateur d'éditeur de liens codé en dur --enable-long-section-names que LLD 9 et les versions antérieures ne prennent pas en charge (il est prévu de le prendre en charge à l'avenir).

Cette partie est corrigée par : https://github.com/rust-lang/rust/pull/66257
Les utilisateurs de Windows-gnu doivent toujours effectuer un travail manuel pour utiliser le compilateur C qui prend en charge -fuse-ld=lld .

@bstrie : Cela fonctionne avec Stable et Nightly sur Windows-MSVC, détails dans le premier post de ce numéro de gamedev-wg : https://github.com/rust-gamedev/wg/issues/50

Un autre point de données : en utilisant RUSTFLAGS="-C link-arg=-fuse-ld=lld" lors de la construction de rustc lui-même, le temps de liaison passe de 93 s à 41 s sur ma machine Linux rapide à 14 cœurs.

@nnethercote : Est-ce différent de définir linker=lld dans (par exemple) la section [target.x86_64-unknown-linux-gnu] du config.toml ?

@Aaron1011 : Je suppose que les deux approches ont le même effet, mais je ne l'ai pas vérifié moi-même.

@Aaron1011 cela devrait être clang, voir https://github.com/rust-lang/rust/issues/39915#issuecomment -538049306.

@mati865
Avez-vous essayé de construire rustc sur x86_64-pc-windows-gnu avec LLD comme éditeur de liens ?

Je l'ai essayé aujourd'hui et LLD se bloque au milieu de la construction et arrête de travailler, ou se plaint de unknown argument: --version-script=... .
Le blocage se produit également si LLD est utilisé pour lier LLVM uniquement, avec

[llvm]
use-linker = "lld"

Versions d'outils :

$ ld.lld --version
LLD 9.0.1 (https://github.com/msys2/MINGW-packages.git 5e3b8820ed9f04221affee4197e458aca2612e87) (compatible with GNU linkers)

$ gcc --version
gcc.exe (Rev2, Built by MSYS2 project) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

@petrochenkov oui je pourrais le construire avec quelques hacks :

J'écris ici quelques possibilités futures. Bien que certains efforts de mise en œuvre soient nécessaires, je pense que ceux-ci aideront à résoudre certains problèmes de longue date dans le développement de Rust :

  • Au lieu d'utiliser lld externe fourni, construisez-le et utilisez-le en tant que bibliothèques statiques dans rustc. Cela permet une intégration plus étroite pour se rouiller, améliore l'expérience prête à l'emploi et ouvre des possibilités futures.
  • Au lieu de passer beaucoup de noms de chemin à lld en tant que commande d'éditeur de liens, utilisez un système de fichiers virtuel et transmettez ces données de mémoire à mémoire au lieu d'utiliser les E/S de disque chaque fois qu'il y a suffisamment d'espace mémoire pour le faire. Pour les projets plus importants, cela peut économiser des centaines, voire des milliers de mégaoctets d'E/S disque, et ainsi améliorer le temps de compilation.

Au lieu de passer beaucoup de noms de chemin à lld en tant que commande d'éditeur de liens, utilisez un système de fichiers virtuel et transmettez ces données de mémoire à mémoire au lieu d'utiliser les E/S de disque chaque fois qu'il y a suffisamment d'espace mémoire pour le faire. Pour les projets plus importants, cela peut économiser des centaines, voire des milliers de mégaoctets d'E/S disque, et ainsi améliorer le temps de compilation.

Ce n'est pas seulement une question de bande passante IO. Sur des plates-formes comme Windows, en particulier lorsque Windows Defender est activé, chaque fichier avec lequel vous souhaitez travailler ajoute une pénalité de temps assez importante, et le modèle d'unité de codegen de Rust signifie que les caisses sont divisées en des centaines de minuscules fichiers objets qui peuvent rapidement accumuler beaucoup de compilation temps.

Ce bug est un peu le bordel, alors voici mon meilleur coup pour un bref résumé de la situation actuelle, pour les gens qui veulent faire avancer les choses.

Qu'est-ce que lld

Un éditeur de liens faisant partie du projet llvm, ce qui est souhaitable pour deux raisons :

  • c'est très convivial pour la compilation croisée (d'où son accent sur les cibles embarquées)
  • c'est très rapide (s'exécute souvent en deux fois moins de temps que Gold - la liaison peut prendre plusieurs minutes pour les gros projets (rustc, servo, etc.) et la liaison peut représenter un pourcentage énorme de la compilation avec des versions incrémentielles, donc diviser par deux Grosse affaire.)

Ce que Rust fait avec lld aujourd'hui

  • Rust envoie actuellement sa propre copie de lld sur la plupart des plates-formes en tant que binaire qu'il appelle rust-lld
  • rust-lld est utilisé par défaut sur de nombreuses cibles bare-metal
  • rust-lld est utilisé par défaut pour wasm
  • (?) vous pouvez explicitement demander à rouille-lld d'être utilisé en utilisant "-C linker-flavor" (flou sur ce que cela fait exactement sur les plates-formes non bare-metal, voir ci-dessous)

Problèmes d'utilisation de rust-lld dans plus d'endroits (c'est-à-dire de bureau linux/mac/windows)

  • Le backend macOS (Mach-O) pour lld est cassé et abandonné

    • une réécriture à partir de zéro a commencé, mais c'est le début

  • Sur les plateformes linux/unix, vous n'êtes pas censé invoquer directement ld/lld. Vous êtes censé invoquer l'éditeur de liens via votre compilateur système c (c'est-à-dire gcc), dont la responsabilité est de découvrir les symboles système comme crt1.o et de les fournir à ld. Cela signifie que nous ne pouvons pas « simplement » utiliser rust-lld ; nous devons l'alimenter dans gcc/clang/whatever. (nous ne voulons pas implémenter nous-mêmes cette logique de symbole système)

    • En général, vous ne pouvez pas fournir l'éditeur de liens comme chemin, vous devez l'injecter dans le chemin de recherche du compilateur C en tant que "ld"

    • Alternativement, vous pouvez faire la même chose mais l'injecter en tant que "ld.lld", et passer "-fuse-ld=lld"



      • Cela peut être important, apparemment, lld effectue une détection de nom binaire de style clang pour savoir s'il est exécuté en tant que "ld" ou "ld.lld" (nécessite une enquête)


      • Malheureusement, -fuse-ld=lld n'est qu'une partie de GCC 9, nous pouvons donc nécessiter une détection de fonctionnalité/version pour l'utiliser (clang l'a depuis longtemps)



  • windows-msvc est apparemment en bon état et semble avoir un support limité pour l'utilisation de rust-lld dans le backend, mais je ne sais pas ce qui doit être fait ici.
  • windows-mingw semble être à peu près au même endroit que linux/unix, sauf que vous êtes susceptible d'obtenir un ancien GCC, et les choses sont un peu bancales parce que pseudo-windows-linux n'est pas exactement une configuration bien testée ?

De plus, en général, lld est plus récent, ce n'est pas la valeur par défaut pour la plupart des systèmes d'exploitation, des bogues de compatibilité aléatoires vont presque certainement apparaître si nous commençons à l'utiliser dans plus d'endroits.

J'ai déposé deux métabugs pour des efforts concentrés sur l'utilisation de (rust-)lld par défaut sur deux plates-formes :

  • #71515 - x64 Ubuntu 20.04 LTS (et plus largement toutes les plateformes x64 ELF)
  • #71520 - Fenêtres msvc x64

windows-msvc est apparemment en bon état et semble avoir un support limité pour l'utilisation de rust-lld dans le backend, mais je ne sais pas ce qui doit être fait ici.

LLD + windows-msvc est en assez bon état, j'utilise actuellement cette configuration pour le développement de rustc .

Tout le support nécessaire pour lld-link est en place dans le backend rustc , mais il y a des bogues comme https://github.com/rust-lang/rust/issues/68647.

  • Cela peut être important, apparemment, lld effectue une détection de nom binaire de style clang pour savoir s'il est exécuté en tant que "ld" ou "ld.lld" (nécessite une enquête)

c'est le cas, mais ld et ld.lld sont le même mode : https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-02-05/lld/tools/lld/lld. cpp (idem depuis 8.0-2019-01-16)

  • Malheureusement, -fuse-ld=lld n'est qu'une partie de GCC 9, nous pouvons donc nécessiter une détection de fonctionnalité/version pour l'utiliser (clang l'a depuis longtemps)

puisque ld.lld est identique à ld, et selon https://patches-gcc.linaro.org/patch/11148/ le seul changement avec -fuse-ld=lld est d'exécuter ld.lld au lieu de ld, si nous utilisons l'injection PATH, ça devrait aller. Je pense cependant que verrouiller cela sur gcc 9+ n'est pas bon : debian stable n'a que 8.3, et bullseye ne sera probablement pas publié avant 2021.

  • windows-mingw semble être à peu près au même endroit que linux/unix, sauf que vous êtes susceptible d'obtenir un ancien GCC, et les choses sont un peu bancales parce que pseudo-windows-linux n'est pas exactement une configuration bien testée ?

mingw-w64 6.0.0, publié le 16/09/2018, a gcc 8.3.0, qui n'a pas -fuse-ld=lld, mais est encore raisonnablement nouveau. mingw-w64 7.0.0, publié le 11-11-2019, a gcc 9.3.0, qui a -fuse-ld=lld. Debian buster (stable) a 6.0.0, bullseye (test) a 7.0.0. Debian stretch (oldstable) n'a que 5.0.1 avec gcc 6.3.0, mais je pense qu'il serait raisonnable d'exiger la dernière version de Debian stable pour la prise en charge de lld s'il y a des problèmes importants avec gcc 6.3.

J'ai déposé deux métabugs pour des efforts concentrés sur l'utilisation de (rust-)lld par défaut sur deux plates-formes :

  • #71515 - x64 Ubuntu 20.04 LTS (et plus largement toutes les plateformes x64 ELF)
  • #71520 - Fenêtres msvc x64

À propos du port macOS (Mach-O) de lld : il semble fonctionner, ou à tout le moins, être en bien meilleure forme depuis https://github.com/rust-lang/rust/issues/39915#issuecomment -618726211 était écrit!

En utilisant ce commit LLVM , j'ai construit lld et l'ai défini comme un éditeur de liens spécifique au projet pour tokio-rs/tracing . J'ai ensuite construit le traçage sur nightly-x86_64-apple-darwin et exécuté tous les tests avec succès. Je suis particulièrement content des temps de compilation (debug) :

  • Avec ld , un cargo build propre a pris 35 secondes.
  • Avec lld , un cargo build propre a pris 20 secondes.

Noter que:

  • ces chiffres de performances proviennent d'un MacBook Pro récent avec 32 Go de RAM et un i9 à 8 cœurs, et
  • il y a quelques problèmes en suspens pour lld et Mach-O.

@davidbarsky Cool ! Par curiosité, comment cette performance se compare-t-elle à zld ? (https://github.com/michaeleisel/zld)

Aussi, avez-vous pris en compte les thermiques ? Les MBP passent très rapidement en régulation thermique, en particulier avec le profil de vitesse de ventilateur par défaut. Attendre que le bas de la machine près de la charnière soit froid au toucher avant de faire une course devrait aider à la cohérence.

Je viens d'un tel bug, sur Ubuntu 16 i686

Cette page vous a été utile?
0 / 5 - 0 notes