¿Es viable hacer un puerto desde una aplicación C ++ a Java a través de LLVM?

9

¿Qué tan viable es portar una aplicación C ++ a bytecode Java usando LLVM (supongo que LLJVM)?

La cuestión es que actualmente tenemos un proceso escrito en C ++, pero un nuevo cliente ha hecho obligatorio poder ejecutar el programa de una manera multiplataforma, utilizando la máquina virtual Java sin obviamente código nativo (sin JNI). La idea es poder tomar el jar generado y copiarlo a diferentes sistemas (Linux, Win, 32 bits - 64 bits) y debería funcionar.

Mirar alrededor parece que es posible compilar C ++ a LLVM IR code y luego ese código a java bytecode. No es necesario que el código generado sea legible.

He probado un poco con cosas similares usando emscripten, esto toma el código C ++ y lo compila en JavaScript. El resultado es JS válido pero totalmente ilegible (parece un asaltante).

  • ¿Alguien ha hecho un puerto de una aplicación de C ++ a Java bytecode utilizando esta técnica?
  • ¿Qué problemas podríamos enfrentar?
  • ¿Es un enfoque válido para el código de producción?

Para dejar más claro mi punto después de algunos comentarios, tal vez el puerto no se usa bien, no espero un código fuente legible como resultado, solo el bytecode de Java, por lo que no es un 'puerto' que se desarrollará para más, solo que el La plataforma objetivo debe ser la JVM de Java, no el asaltante nativo.

Nota: Soy consciente de que actualmente tenemos algunas bibliotecas de código cerrado y C ++ no estándar, estamos tratando de eliminar este código no estándar y todas las bibliotecas de código cerrado y usar el software libre de código abierto, así que supongamos que todo el código es código C ++ estándar con Todo el código disponible en tiempo de compilación.

Nota 2: No es una opción escribir código C ++ portátil y luego compilarlo en la plataforma de destino deseada, el programa compilado debe ser multiplataforma, por lo tanto, el uso de JVM.

Nota 3: En este momento no estamos buscando soluciones similares aplicadas a Python u otra base de lenguaje, pero también me gustaría escuchar sobre eso. Con esto quiero decir que nuestro ejecutable de destino debe ser un bytecode de Java, pero si hay opciones para compilar C ++ a un código compilado válido de Python, también me gustaría saber sobre ellos.

Javier Mr
fuente
No estoy seguro de lo que quiere decir en la última oración sobre Python, pero Jython es exactamente lo mismo: use JVM en lugar de Python VM, y se usa exactamente en ese escenario: los programadores quieren usar Python, la implementación debe estar en JVM.
Javier
¿De cuántas líneas de código estamos hablando? Puede valer la pena reescribirlo, pero esa no es una decisión simple. Además, si su código tiene alguna aritmética de puntero, me gustaría saber cómo se maneja eso cuando se trabaja en la JVM.
Levi Morrison
1
Depuración que debería ser divertida O_o
Daniel Gratzer
@LeviMorrison. Bueno, el código es bastante extenso (dependencias de varias bibliotecas para comunicaciones, funciones de utilidad) pero se supone que tenemos disponible todo el código en tiempo de compilación. Y también si otro cliente no lo requiere, seguiremos generando el binario nativo.
Javier Mr
@jozefg. Acerca de la aritmética del puntero y la depuración intencionada, no espero que sea depurable. Emscripten, por ejemplo, hace lo mismo, pero el idioma de destino es Javascript, termina con una gran matriz de bytes como las operaciones de montón y bit sabio para el contador del programa y solo operaciones con bytes sin objetos, cadenas o cosas por el estilo. Espero un resultado similar al ataque en código de bytes de Java, se podría suponer que no se puede depurar.
Javier Mr

Respuestas:

11

Realmente dudo que esto funcione. Es posible que pueda traducir su código al código de bytes de Java, pero no traducirá mágicamente las llamadas de la biblioteca en llamadas equivalentes a las bibliotecas y el tiempo de ejecución de Java. ¡Puede que ni siquiera haya llamadas de tiempo de ejecución Java equivalentes! Incluso si elimina todas las bibliotecas propietarias, todavía queda la biblioteca estándar de C ++.

Para hacer esto concreto: su programa C ++ puede contener una llamada a fprintf (). Esa función se implementa en la biblioteca estándar de C y es perfectamente legítimo para un programa de C ++ llamarla. El traductor de LLVM a LLJVM probablemente no va a descifrar mágicamente la secuencia de llamadas de tiempo de ejecución de Java que producirá el resultado equivalente a fprintf () y las sustituirá. Para proporcionar esa facilidad se requeriría esencialmente reimplementar los tiempos de ejecución de C y C ++ en Java código de byte

Hay algunas herramientas que realizan la traducción de C ++ a Java, pero solo convierten un puñado de las llamadas de biblioteca de tiempo de ejecución más simples. El resto te queda por resolver.

Charles E. Grant
fuente
Entiendo su punto de vista, pero por lo que entiendo, emscripten hace algo similar con el objetivo de ser Javascript, si no entendí mal, emscripten proporciona una biblioteca estándar personalizada para evitar lo que señaló (e incluso mapeos para webGL a través de la biblioteca SDL) ) Pero no puedo encontrar el equivalente para Java (LLJVM parece abandonado). Estoy pensando en proponer llvm bytecode como una compilación independiente de la plataforma (por supuesto, sin ramificaciones de compilación dependiendo de la plataforma, por API o datos; usando apro similar)
Javier Mr
3
lljvm proporciona una biblioteca de tiempo de ejecución de C, en parte como C compilada en código de bytes JVM, y en parte como clases de Java. Es una biblioteca bastante completa. Debería crear el equivalente para libstdc ++. Además, el backend lljvm no es compatible con C ++ en este momento de todos modos. He estado intentando arreglar lljvm para que funcione con una compilación llvm más reciente. Es lento ya que las API y herramientas de llvm siguen cambiando mucho entre versiones. Puedes seguirlo aquí, ahora está casi en forma utilizable. github.com/hyc/lljvm/tree/llvm3.3
hyc