É viável criar uma porta de um aplicativo C ++ para Java através do LLVM

9

quão viável é portar um aplicativo C ++ para bytecode Java usando LLVM (eu acho que LLJVM)?

O fato é que atualmente temos um processo escrito em C ++, mas um novo cliente tornou obrigatório a capacidade de executar o programa de maneira multiplataforma, usando a Java Virtual Machine obviamente sem código nativo (sem JNI). A idéia é poder levar o jarro gerado e copiá-lo para diferentes sistemas (Linux, Win, 32 bits - 64 bits) e deve funcionar.

Olhando em volta, parece possível compilar o código IR de C ++ para LLVM e, em seguida, esse código para bytecode java. Não é necessário que o código gerado seja legível.

Eu testei um pouco com coisas semelhantes usando o emscripten, isso pega o código C ++ e o compila no JavaScript. O resultado é JS válido, mas totalmente ilegível (parece assambler).

  • Alguém fez uma porta de um aplicativo de C ++ para bytecode Java usando essa técnica?
  • Que problemas podemos enfrentar?
  • É uma abordagem válida para o código de produção?

Para esclarecer meu ponto de vista após alguns comentários, talvez a porta não seja bem usada, como resultado, não espero código fonte legível, apenas java bytecode, portanto, não é uma 'porta' que será desenvolvida para mais, apenas que o A plataforma de destino deve ser a JVM java, não a nativa assamblear.

Nota: Estou ciente de que atualmente temos algumas bibliotecas C ++ e de código-fonte não padrão, estamos procurando remover esse código não-padrão e todas as bibliotecas de código-fonte fechado e usar o Software Livre de Código Aberto Libre, então vamos supor que todo o código seja um código C ++ padrão com todo o código disponível em tempo de compilação.

Nota2: Não é uma opção para escrever código C ++ portátil e compilá-lo na plataforma de destino desejada; o programa compilado deve ser multiplataforma, portanto, o uso da JVM.

Nota 3: No momento, não estamos procurando soluções semelhantes aplicadas ao Python ou a outra base de linguagem, mas também gostaria de saber sobre isso. Com isso, quero dizer que nosso executável de destino deve ser java bytecode, mas se houver opções para compilar C ++ para código compilado python válido, também gostaria de saber sobre eles.

Javier Mr
fonte
não sei o que você quer dizer com a última frase sobre Python, mas o Jython é exatamente o mesmo: use a JVM em vez da VM do Python e usado exatamente nesse cenário: os programadores desejam usar o Python, a implantação deve estar na JVM.
Javier
De quantas linhas de código estamos falando? Pode valer a pena reescrevê-lo, mas essa não é uma decisão simples. Além disso, se o seu código fizer alguma aritmética de ponteiro, ficaria curioso para saber como isso é tratado ao trabalhar na JVM.
Levi Morrison
11
Depuração que deve ser divertido O_o
Daniel Gratzer
@LeviMorrison. Bem, o código é bastante extenso (várias dependências de bibliotecas para comunicações, funções de utilidade), mas presume-se que tenhamos disponível todo o código em tempo de compilação. E também se outro cliente não exigir, ainda geraremos o binário nativo.
Javier Mr
@jozefg. Sobre aritmética de ponteiro e depuração proposta, não espero que seja depurável. Emscripten, por exemplo, faz a mesma coisa, mas a linguagem de destino é Javascript; você termina apenas com uma grande matriz de bytes, como as operações heap e bit-wise para contador de programas e apenas operações com bytes sem objetos, seqüências de caracteres ou algo do tipo. Espero que o resultado semelhante ao assamblear no java bytecode, possa ser assumido como não debugável.
Javier Mr

Respostas:

11

Eu realmente duvido que isso funcione. Você poderá converter seu código em código de bytes Java, mas ele não traduzirá magicamente as chamadas da biblioteca em chamadas equivalentes para o tempo de execução e as bibliotecas Java. Pode até não haver chamadas de tempo de execução Java equivalentes! Mesmo se você eliminar todas as bibliotecas proprietárias, ainda ficará com a biblioteca padrão C ++.

Para tornar isso concreto: seu programa C ++ pode conter uma chamada para fprintf (). Essa função é implementada na biblioteca padrão C e é perfeitamente legítimo para um programa C ++ chamá-lo. O tradutor LLVM para LLJVM provavelmente não vai descobrir magicamente a sequência de chamadas em tempo de execução Java que produzirão o resultado equivalente a fprintf () e as substituirá. Para fornecer esse recurso, seria necessário reimplementar os tempos de execução C e C ++ em Java código de bytes.

Existem algumas ferramentas que executam a tradução de C ++ para Java, mas elas convertem apenas algumas das chamadas mais simples da biblioteca de tempo de execução. O resto é deixado para você descobrir.

Charles E. Grant
fonte
Entendo o seu ponto de vista, mas até onde eu entendo o emscripten faz algo semelhante com o destino sendo Javascript, se eu não entendi errado, o emscripten fornece uma biblioteca padrão personalizada para evitar o que você apontou (e até mesmo mapeamentos para o webGL através da biblioteca SDL ) Mas não consigo encontrar o equivalente para Java (o LLJVM parece abandonado). Estou pensando em propor llvm bytecode como uma compilação independente de plataforma (claro, sem ramos de compilação, dependendo da plataforma, pela API ou de dados, usando aprou similar)
Javier Mr
3
O lljvm fornece uma biblioteca de tempo de execução C, parcialmente como C compilado no bytecode da JVM e parcialmente como classes Java. É uma biblioteca bastante completa. Você precisaria criar o equivalente para libstdc ++. Além disso, o back-end lljvm realmente não suporta C ++ no momento. Eu tenho tentado corrigir o lljvm para trabalhar com uma versão mais recente do llvm. É lento, pois as APIs e ferramentas do llvm continuam mudando muito entre os lançamentos. Você pode acompanhar aqui, está quase em forma utilizável agora. github.com/hyc/lljvm/tree/llvm3.3
hyc