Kakehashi est une couche de traduction en espace utilisateur qui charge des binaires macOS ARM64 et les exécute sur Linux aarch64, sans machine virtuelle, sans émulateur et sans compilation à la volée. Le projet est apparu sur Hacker News le 2 août et y a récolté 214 points et 55 commentaires, ce qui fait beaucoup d'attention pour quelque chose que son auteur qualifie d'expérimental. L'objectif est plus étroit et plus intéressant que le titre ne le laisse croire. Les tâches d'intégration continue qui ont besoin d'outils Darwin en ligne de commande doivent aujourd'hui tourner sur des runners macOS, rares et facturés environ douze fois le prix d'un runner Linux ARM64. Kakehashi cherche à les en sortir.
The short answer
Kakehashi est une couche de traduction macOS ARM64 vers Linux aarch64 en espace utilisateur, écrite en Rust et sous licence Apache 2.0. Elle charge des exécutables Mach-O, expose une libSystem autonome et traduit les appels système BSD, sans compilation à la volée ni machine virtuelle. Les invités vérifiés sont aujourd'hui 7-Zip, compression multi fils comprise, curl en HTTPS avec OpenSSL, et des fixtures de sonde clang. Manquent notamment l'ensemble des fonctions de curl, le Security.framework, la partie graphique, git et les Xcode Command Line Tools, ainsi que codesign et la notarisation. L'objectif affiché est d'exécuter l'outillage Darwin en ligne de commande sur des runners Linux aarch64 bon marché plutôt que sur une capacité macOS rare.
Le point pénible de toute chaîne d'intégration qui doit toucher du logiciel Apple, c'est la facture de runner. L'essentiel de la tâche est du travail ordinaire que n'importe quelle machine ferait, une étape a besoin d'un binaire Darwin, et cette seule étape traîne la tâche entière sur une capacité macOS chère et souvent saturée. Kakehashi, arrivé en une de Hacker News le 2 août avec 214 points, tente de briser cette dépendance au niveau du binaire.
Ce qu'il fait, et ce qu'il ne fait pas
Nommer le problème compte ici, car ce n'est pas celui que l'on suppose.
Les binaires Apple Silicon sont déjà en ARM64. En exécuter un sur une machine Linux ARM64 ne demande de traduire aucune instruction. Ce que cela demande, c'est de convaincre le binaire que le système sous lui est Darwin, un problème bien plus abordable que l'émulation et bien moins simple qu'il n'y paraît.
Kakehashi fait quatre choses pour y arriver. Il analyse et projette le Mach-O, le format exécutable qu'utilise macOS à la place d'ELF. Il fournit une libSystem autonome, la bibliothèque à laquelle tout binaire Darwin s'édite pour son exécution. Il traduit les appels système BSD vers leurs équivalents Linux. Et il fait le pont entre les chemins de fichiers, en exposant l'hôte via un chemin /Volumes/linux/ pour qu'un binaire Darwin atteigne des répertoires Linux.
Il n'y a ni compilation à la volée ni émulation d'instructions dans cette liste. C'est une couche de compatibilité au sens où WINE en est une, pointée dans une direction inhabituelle.
L'architecture
Le dépôt se découpe en quatre crates, et ce découpage vous dit où est le travail.
kakehashi est le binaire en ligne de commande installé par l'utilisateur. kh-loader gère l'analyse, la projection et l'exécution du Mach-O. kh-runtime possède la mémoire, les déroutements, les appels système BSD et la bibliothèque dynamique embarquée. kh-libsystem est la source de la dylib autonome, seule pièce construite pour aarch64-apple-darwin plutôt que pour Linux.
Ce dernier détail est élégant : la dylib invitée est compilée pour Darwin, puis intégrée au binaire d'exécution Linux via include_bytes, si bien que ce qui est livré est un exécutable Linux unique portant une bibliothèque Darwin en son sein.
Ce qui tourne, et ce qui ne tourne pas
La liste d'invités vérifiés est courte et le projet ne la survend pas.
7-Zip fonctionne. Créer des archives, les tester, les extraire, et la compression multi fils éprouvée avec 7zz et mmt=4, ce qui mérite d'être noté parce que les fils d'exécution sont l'endroit où une traduction d'appels système à moitié terminée s'effondre habituellement. curl fonctionne en HTTP et HTTPS avec OpenSSL et la gestion du paquet d'autorités. Des fixtures de sonde clang démontrent une compilation de base.
L'autre colonne maintenant. curl est partiel : corps POST, mandataires et HTTP/3 sont listés comme non fonctionnels. Le Security.framework est absent, donc tout ce qui vise le trousseau ou les interfaces de confiance d'Apple est hors jeu. Il n'y a pas de partie graphique, et le projet affiche clairement une priorité à la ligne de commande. git et les Xcode Command Line Tools ne s'exécutent pas, même si git est cité comme objectif via ces mêmes outils.
codesign et la notarisation ne sont pas non plus implémentés, et ce couple marque la limite honnête de la conception actuelle. Une chaîne de publication macOS se termine typiquement par la signature et la notarisation, deux étapes qui dialoguent avec des services Apple à travers des cadriciels Apple. Kakehashi peut plausiblement reprendre les étapes de construction et d'archivage bien avant de reprendre la dernière.
L'étape suivante annoncée est git, livré via un invité kh install xcode-tools. C'est la bonne cible, parce que git est l'outil Darwin en ligne de commande que presque toutes les chaînes touchent.
L'arithmétique qui le justifie
La performance d'abord, puisque c'est l'objection que tout le monde soulève. Sur Ubuntu aarch64 en machine nue sous UTM, une archive 7-Zip multi fichiers portant sur environ huit mille fichiers et 240 Mio a pris environ 22,5 secondes en natif et environ 118 secondes sous Kakehashi. C'est de là que vient le rapport de 5,2.
Le projet précise soigneusement d'où sort ce chiffre, et la nuance mérite d'être répétée. Sur des échantillons peu nombreux et lourds en compression, l'écart se resserre autour de 1,1 à 1,2 fois. Le grand écart multi fichiers est dominé par le parcours de chemins et la frontière par appel système, pas par la compression elle même. Autrement dit, la taxe suit le bavardage de l'invité et non la quantité de travail, ce qui est exactement ce qu'on attend d'une couche de traduction d'appels système et pas du tout ce qu'on attendrait d'un émulateur.
Puis les prix. Le projet cite les tarifs des runners hébergés GitHub Actions en dépassement sur dépôt privé : 0,005 dollar la minute pour un runner Linux arm64 à deux cœurs, contre 0,062 dollar la minute pour un runner macOS à trois ou quatre cœurs, les runners macOS plus gros se situant entre 0,077 et 0,102. Soit environ dix à douze fois la minute Linux arm64, avant même toute différence de temps réel.
Le calcul d'illustration proposé par le projet est le plus parlant. Cinq minutes de Linux arm64 à 0,005 font environ 0,025 dollar. Une minute de macOS à 0,062 fait 0,062. Une tâche cinq fois plus lente coûte encore moins de la moitié.
Accepter ce compromis dépend de ce que vous optimisez. Si un développeur attend le résultat, cinq fois plus lent fait mal. S'il s'agit d'une tâche nocturne, d'une matrice de construction, ou de tout ce où la facture et la file d'attente comptent plus que l'horloge, le calcul est favorable avant même de compter la rareté de la capacité macOS, qui est précisément ce qui fait attendre ces runners. Le projet dit aussi clairement quand les runners macOS restent gagnants : tout ce qui touche à l'interface graphique, à codesign ou à la notarisation, et les tests d'interface Xcode.
Où nous le situons aujourd'hui
Kakehashi est un projet Rust qui réclame une chaîne d'outils 1.88 ou plus récente, sous licence Apache 2.0, installé par cargo install kakehashi puis piloté par kh bottle ensure et kh install. Il tourne sur Linux aarch64, matériel nu ou virtualisé, avec des pages de 4 Kio ou 16 Kio.
Ce qu'il n'est pas encore, c'est quelque chose à placer devant une chaîne dont vous dépendez. L'écart entre exécuter 7zz et exécuter une vraie chaîne d'outils Darwin est large, et les pièces manquantes ne sont pas décoratives.
Ce qui le rend digne d'attention, c'est que l'approche est saine et le périmètre discipliné. Quelqu'un a regardé le problème des runners d'intégration, conclu que l'obstacle réel est l'interface du système et non le jeu d'instructions, et commencé à traduire l'interface. Si l'objectif git et Xcode Command Line Tools aboutit, l'ensemble des tâches qui exigent réellement du matériel Apple rétrécit, et c'est utile à quiconque a déjà regardé une file d'attente de runner macOS.
Sources et pour aller plus loin
Questions fréquentes
En quoi est ce différent d'une machine virtuelle ou de Rosetta ?
Rosetta traduit des instructions x86 pour qu'elles s'exécutent sur du matériel ARM, ce qui est un problème de jeu d'instructions. Kakehashi ne traduit aucune instruction. Les binaires sont déjà en ARM64, ils attendent simplement Darwin plutôt que Linux, donc ce qu'il faut traduire est l'interface du système d'exploitation : le format exécutable Mach-O, le comportement de l'éditeur de liens dynamique, la libSystem à laquelle le binaire s'édite, et les appels système BSD qu'il émet. C'est pourquoi il n'y a ni compilation à la volée ni couche d'émulation. Une machine virtuelle résout le même problème en exécutant un invité macOS complet, ce qui suppose une licence Apple, du matériel Apple et le démarrage d'un système entier. Kakehashi exécute le binaire comme un processus Linux.
Qu'est ce qui fonctionne aujourd'hui ?
L'ensemble vérifié est réduit et le projet ne le cache pas. 7-Zip fonctionne pour créer, tester et extraire des archives, y compris la compression multi fils testée avec l'option 7zz mmt=4, ce qui signifie que les fils d'exécution sont réellement fonctionnels et non bouchonnés. curl fonctionne pour des requêtes HTTP et HTTPS avec OpenSSL et la gestion du paquet d'autorités de certification. Des fixtures de sonde clang démontrent une compilation de base. L'accès au système de fichiers hôte passe par un chemin /Volumes/linux/ afin qu'un binaire Darwin atteigne des chemins Linux. C'est assez pour prouver l'approche, et très loin d'être assez pour exécuter une vraie construction macOS.
Qu'est ce qui ne fonctionne pas ?
La liste est plus longue que celle de ce qui marche, ce qui est le sens du mot expérimental. curl est partiel : pas de corps POST, pas de mandataires, pas de HTTP/3. Le Security.framework d'Apple est absent, ce qui exclut tout ce qui touche au trousseau ou aux interfaces de confiance du système. Il n'y a aucune prise en charge graphique, et le projet indique clairement viser la ligne de commande d'abord. git et les Xcode Command Line Tools ne s'exécutent pas encore, même si git est cité comme objectif. codesign et la notarisation ne sont pas implémentés, et cela compte parce que ce sont exactement les étapes qui terminent une chaîne de publication macOS réelle.
Quel est le compromis entre performance et coût ?
Le projet a mesuré une archive 7-Zip multi fichiers portant sur environ huit mille fichiers, sur Ubuntu aarch64 : environ 22,5 secondes en natif contre environ 118 secondes sous Kakehashi, soit un rapport de 5,2. Sur des échantillons peu nombreux et lourds en compression, l'écart se resserre autour de 1,1 à 1,2, parce que le coût vient de la frontière par appel système et du parcours de chemins plutôt que du travail de compression. Placez cela à côté des tarifs GitHub Actions que cite le projet : 0,005 dollar la minute pour un runner Linux arm64 à deux cœurs contre 0,062 pour un runner macOS à trois ou quatre cœurs. Cinq minutes de Linux arm64 font environ 0,025 dollar contre 0,062 pour une minute macOS, donc une tâche cinq fois plus lente coûte encore moins de la moitié.
Comment l'essayer, et que faut il ?
C'est écrit en Rust et il faut une chaîne d'outils 1.88 ou plus récente, l'installation se faisant depuis crates.io avec cargo install kakehashi. Ensuite, kh bottle ensure récupère les pièces d'exécution et kh install tire un invité, par exemple kh install 7zip ou kh install curl. L'hôte doit être un Linux aarch64, sur machine nue, en machine virtuelle, ou via Colima ou Docker, avec une taille de page de 4 Kio ou 16 Kio. La licence est Apache 2.0. Considérez le comme quelque chose à évaluer sur un runner de rechange plutôt qu'à placer devant une chaîne dont vous dépendez.