Жизнеспособно ли сделать порт из приложения C ++ в Java через LLVM

9

Насколько жизнеспособно портировать приложение C ++ на байт-код Java, используя LLVM (я думаю, LLJVM)?

Дело в том, что в настоящее время у нас есть процесс, написанный на C ++, но новый клиент сделал обязательным, чтобы иметь возможность запускать программу многоплатформенным способом, используя виртуальную машину Java без явно собственного кода (без JNI). Идея состоит в том, чтобы иметь возможность взять сгенерированный jar и затем скопировать его в разные системы (Linux, Win, 32 бит - 64 бит), и он должен просто работать.

Осмотр выглядит так, как будто можно скомпилировать C ++ в код LLVM IR, а затем этот код в байт-код Java. Сгенерированный код не нужен для чтения.

Я немного протестировал подобные вещи, используя emscripten, он берет код C ++ и компилирует его в JavaScript. Результат действительный JS, но совершенно нечитаемый (выглядит как ассамблер).

  • Кто-нибудь сделал порт приложения из C ++ в Java байт-код, используя эту технику?
  • С какими проблемами мы можем столкнуться?
  • Является ли действительный подход для производственного кода?

Чтобы прояснить мою точку зрения после некоторых комментариев, возможно, порт используется недостаточно хорошо, я не ожидаю читабельный исходный код в результате, просто байт-код Java, так что это не «порт», который будет разрабатываться больше, просто целевой платформой должна быть Java JVM, а не нативная ассамбляр.

Примечание. Мне известно, что в настоящее время у нас есть несколько нестандартных библиотек C ++ и закрытых исходных кодов, мы собираемся удалить этот нестандартный код и все библиотеки закрытых исходных кодов и использовать бесплатное программное обеспечение с открытым исходным кодом Libre, поэтому предположим, что весь код является стандартным кодом C ++ весь код доступен во время компиляции.

Примечание 2: Это не вариант написания переносимого кода на C ++, а затем компиляции его на нужную целевую платформу, скомпилированная программа должна быть многоплатформенной, поэтому используется JVM.

Примечание 3: В настоящее время мы не рассматриваем похожие решения, применяемые к Python или другой языковой базе, но я также хотел бы услышать об этом. Под этим я подразумеваю, что нашим целевым исполняемым файлом должен быть байт-код java, но если есть варианты для компиляции C ++ в допустимый скомпилированный код на python, я также хотел бы услышать о них.

Хавьер Мистер
источник
Не знаю, что вы имеете в виду в последнем предложении о Python, но Jython точно такой же: используйте JVM вместо Python VM и используйте именно в этом сценарии: программисты хотят использовать Python, развертывание должно быть на JVM.
Хавьер
Сколько строк кода мы говорим? Возможно, стоит переписать его, но это не простое решение. Кроме того, если ваш код выполняет какую-либо арифметику указателей, мне было бы интересно узнать, как это обрабатывается при работе с JVM.
Леви Моррисон
1
Отладка, которая должна быть веселой О_о
Даниэль Гратцер
@LeviMorrison. Ну, код довольно обширный (различные зависимости библиотек для связи, функции utlity), но предполагается, что у нас есть весь код во время компиляции. А также, если другой клиент не требует этого, мы все равно будем генерировать собственный двоичный файл.
Хавьер Мистер
@jozefg. Об арифметике и отладке указателей я не ожидаю отладки. Emscripten, например, делает то же самое, но целевым языком является Javascript, в результате вы заканчиваете просто большим байтовым массивом в качестве кучи и побитовых операций для счетчика программ и просто операций с байтами, без объектов, строк или тому подобного. Я ожидаю, что результат, аналогичный assamblear в байт-коде Java, можно предположить, что он не подлежит отладке.
Хавьер Мистер

Ответы:

11

Я действительно сомневаюсь, что это сработает. Возможно, вы сможете преобразовать свой код в байт-код Java, но он не будет магическим образом переводить вызовы библиотеки в эквивалентные вызовы среды выполнения Java и библиотек. Может даже не быть эквивалентных вызовов времени выполнения Java! Даже если вы удалите все проприетарные библиотеки, вы все равно останетесь со стандартной библиотекой C ++.

Чтобы сделать это более конкретным: ваша C ++ программа может содержать вызов fprintf (). Эта функция реализована в стандартной библиотеке C, и она вполне допустима для программы на C ++. Переводчик LLVM в LLJVM, вероятно, не собирается волшебным образом выяснять последовательность вызовов времени выполнения Java, которые приведут к эквивалентному результату для fprintf (), и подставлять их в. Чтобы обеспечить, что средство потребует существенного переопределения времени выполнения C и C ++ в Java байт код

Есть некоторые инструменты, которые выполняют перевод C ++ в Java, но они конвертируют лишь несколько простых вызовов библиотеки времени выполнения. Остальные оставлены для вас, чтобы выяснить.

Чарльз Э. Грант
источник
Я понимаю вашу точку зрения, но, насколько я понимаю, emscripten делает нечто похожее с целью, являющейся Javascript, если я не понял неправильно, emscripten предоставляет настраиваемую стандартную библиотеку, чтобы избежать того, на что вы указали (и даже отображения для webGL через библиотеку SDL ). Но я не могу найти эквивалент для Java (LLJVM кажется заброшенным). Я думаю о предложении llvm байт-кода в качестве независимой от платформы сборки (конечно, без веток компиляции в зависимости от платформы, по API или данным; использование aprили подобное)
Хавьер Мр
3
lljvm предоставляет библиотеку времени выполнения C, частично в виде C, скомпилированного в байт-код JVM, а частично в виде классов Java. Это довольно полный libc. Вам необходимо создать эквивалент для libstdc ++. Кроме того, бэкэнд lljvm на самом деле пока не поддерживает C ++. Я пытался исправить lljvm для работы с более свежей сборкой llvm. Это происходит медленно, так как API и инструменты llvm постоянно меняются между релизами. Вы можете следовать здесь, это почти в удобной форме сейчас. github.com/hyc/lljvm/tree/llvm3.3
Hyc