Est-il viable de créer un port à partir d'une application C ++ vers Java via LLVM

9

dans quelle mesure est-il viable de porter une application C ++ sur le bytecode Java en utilisant LLVM (je suppose LLJVM)?

Le fait est que nous avons actuellement un processus écrit en C ++ mais un nouveau client a rendu obligatoire de pouvoir exécuter le programme de manière multiplateforme, en utilisant la machine virtuelle Java sans évidemment aucun code natif (pas de JNI). L'idée est de pouvoir prendre le pot généré et le copier ensuite sur différents systèmes (Linux, Win, 32 bits - 64 bits) et cela devrait simplement fonctionner.

En regardant autour, il est possible de compiler C ++ en code IR LLVM puis ce code en bytecode java. Il n'est pas nécessaire que le code généré soit lisible.

J'ai testé un peu avec des choses similaires en utilisant emscripten, cela prend du code C ++ et le compile en JavaScript. Le résultat est un JS valide mais totalement illisible (ressemble à un assembleur).

  • Quelqu'un a-t-il fait le portage d'une application de C ++ vers le bytecode Java en utilisant cette technique?
  • Quels problèmes pourrions-nous rencontrer?
  • Une approche valide pour le code de production?

Pour clarifier mon point de vue après quelques commentaires, peut-être que le port n'est pas bien utilisé, je ne m'attends donc pas à du code source lisible, juste du bytecode java, donc ce n'est pas un 'port' qui sera développé pour plus, juste que le la plate-forme cible doit être la JVM java et non l'assamblear natif.

Remarque: Je sais que nous avons actuellement des bibliothèques C ++ non standard et des bibliothèques source proches, nous cherchons à supprimer ce code non standard et toutes les bibliothèques source proches et à utiliser le logiciel libre et gratuit Open Source, donc supposons que tout le code soit du code C ++ standard avec tout le code est disponible au moment de la compilation.

Remarque 2: Il n'est pas possible d'écrire du code C ++ portable puis de le compiler sur la plate-forme cible souhaitée, le programme compilé doit être multiplateforme, d'où l'utilisation de JVM.

Note3: Pour l'instant, nous ne recherchons pas de solutions similaires appliquées à Python ou à une autre base de langage, mais j'aimerais également en entendre parler. Avec cela, je veux dire que notre exécutable cible doit être du bytecode java mais s'il y a des options pour compiler C ++ en code compilé python valide, j'aimerais aussi en entendre parler.

Javier Mr
la source
Je ne sais pas ce que vous voulez dire sur la dernière phrase à propos de Python, mais Jython est exactement le même: utilisez JVM au lieu de la machine virtuelle Python, et utilisé exactement dans ce scénario: les programmeurs veulent utiliser Python, le déploiement doit être sur JVM.
Javier
De combien de lignes de code parlons-nous? Cela vaut peut-être la peine de le réécrire, mais ce n'est pas une décision simple. De plus, si votre code fait de l'arithmétique de pointeur, je serais curieux de savoir comment cela est géré lorsque vous travaillez sur la JVM.
Levi Morrison
1
Débogage qui devrait être amusant O_o
Daniel Gratzer
@LeviMorrison. Eh bien, le code est assez étendu (diverses dépendances des bibliothèques pour les communications, fonctions utilitaires) mais on suppose que nous avons disponible tout le code au moment de la compilation. Et aussi si un autre client n'en a pas besoin, nous générerons toujours le binaire natif.
Javier Mr
@jozefg. À propos des pointeurs aritmetics et du débogage, je ne m'attends pas à être déboguable. Emscripten par exemple fait la même chose mais la langue cible est Javascript, vous vous terminez juste avec un grand tableau d'octets en tant qu'opérations en tas et en bits pour le compteur de programme et juste des opérations avec octets sans objets, chaînes ou quelque chose comme ça. Je m'attends à un résultat similaire à assamblear dans le bytecode java, il pourrait être supposé ne pas être déboguable.
Javier Mr

Réponses:

11

Je doute vraiment que cela fonctionne. Vous pourrez peut-être traduire votre code en code d'octet Java, mais cela ne traduira pas comme par magie les appels de bibliothèque en appels équivalents au runtime Java et aux bibliothèques. Il n'y a peut-être même pas d'appels d'exécution Java équivalents! Même si vous éliminez toutes les bibliothèques propriétaires, il vous reste la bibliothèque standard C ++.

Pour rendre cela concret: votre programme C ++ peut contenir un appel à fprintf (). Cette fonction est implémentée dans la bibliothèque standard C et il est parfaitement légitime qu'un programme C ++ l'appelle. Le traducteur LLVM vers LLJVM ne va probablement pas magiquement comprendre la séquence d'appels d'exécution Java qui produira le résultat équivalent à fprintf () et les remplacer par. Pour fournir cette fonctionnalité, il faudrait essentiellement réimplémenter les temps d'exécution C et C ++ en Java code d'octet.

Il existe certains outils qui effectuent la traduction C ++ en Java, mais ils ne convertissent qu'une poignée d'appels de bibliothèque d'exécution plus simples. Le reste est à vous de comprendre.

Charles E. Grant
la source
Je vois votre point de vue, mais pour autant que je comprends, emscripten fait quelque chose de similaire avec la cible étant Javascript, si je n'ai pas mal compris, emscripten fournit une bibliothèque standard personnalisée afin d'éviter ce que vous avez souligné (et même des mappages pour webGL via la bibliothèque SDL ). Mais je ne trouve pas l'équivalent pour Java (LLJVM semble abandonné). Je pense à proposer llvm bytecode comme une construction indépendante de la plate-forme (bien sûr, sans branches de compilation en fonction de la plate-forme, par API ou par données; en utilisant aprou similaire)
Javier Mr
3
lljvm fournit une bibliothèque d'exécution C, en partie sous forme de C compilé en bytecode JVM et en partie sous forme de classes Java. C'est une libc assez complète. Vous devez créer l'équivalent pour libstdc ++. De plus, le backend lljvm ne prend pas en charge C ++ pour le moment. J'ai essayé de corriger lljvm pour qu'il fonctionne avec une version plus récente de llvm. C'est lent car les API et les outils llvm changent tellement entre les versions. Vous pouvez suivre ici, c'est presque en forme utilisable maintenant. github.com/hyc/lljvm/tree/llvm3.3
hyc