Czy wykonalne jest utworzenie portu z aplikacji C ++ do Javy za pomocą LLVM

9

jak opłacalne jest przeniesienie aplikacji C ++ do kodu bajtowego Java za pomocą LLVM (chyba LLJVM)?

Chodzi o to, że obecnie mamy proces napisany w C ++, ale nowy klient wprowadził obowiązek uruchamiania programu w sposób wieloplatformowy, używając wirtualnej maszyny Java bez oczywistego kodu natywnego (bez JNI). Chodzi o to, aby móc wygenerować słoik i skopiować go do różnych systemów (Linux, Win, 32 bity - 64 bity) i powinien on po prostu działać.

Rozglądanie się wygląda na to, że można skompilować C ++ do kodu IR LLVM, a następnie ten kod do kodu bajtowego java. Wygenerowany kod nie musi być czytelny.

Testowałem trochę z podobnymi rzeczami przy użyciu emscripten, to pobiera kod C ++ i kompiluję go do JavaScript. Wynik jest prawidłowy JS, ale całkowicie nieczytelny (wygląda jak assambler).

  • Czy ktoś zrobił port aplikacji od C ++ do kodu bajtowego Java za pomocą tej techniki?
  • Z jakimi problemami możemy się zmierzyć?
  • Czy poprawne jest podejście do kodu produkcyjnego?

Aby wyjaśnić moją uwagę po kilku komentarzach, być może port nie jest dobrze używany, dlatego nie oczekuję czytelnego kodu źródłowego, po prostu kod bajtowy java, więc nie jest to „port”, który zostanie opracowany dla tego, tylko że docelowa platforma musi być maszyną Java JVM, a nie rodzimym narzędziem Assamblear.

Uwaga: Zdaję sobie sprawę, że obecnie mamy niektóre niestandardowe biblioteki C ++ i bliskie źródła, chcemy usunąć ten niestandardowy kod i wszystkie bliskie biblioteki źródłowe oraz użyć darmowego oprogramowania Open Source Libre, więc załóżmy, że cały kod jest standardowym kodem C ++ z cały kod dostępny w czasie kompilacji.

Uwaga 2: Nie jest możliwe napisanie przenośnego kodu C ++, a następnie skompilowanie go na pożądanej platformie docelowej, skompilowany program musi być wieloplatformowy, dlatego należy użyć JVM.

Uwaga 3: W tej chwili nie szukamy podobnych rozwiązań stosowanych w Pythonie lub innej bazie językowej, ale chciałbym również o tym usłyszeć. Rozumiem przez to, że naszym docelowym plikiem wykonywalnym musi być kod bajtowy Java, ale jeśli istnieją opcje kompilacji C ++ do poprawnego skompilowanego kodu python, chciałbym również o nich usłyszeć.

Javier Mr
źródło
nie jestem pewien, co masz na myśli w ostatnim zdaniu na temat Pythona, ale Jython jest dokładnie taki sam: użyj JVM zamiast maszyny wirtualnej Python i zastosowany dokładnie w tym scenariuszu: programiści chcą używać Python, wdrożenie musi odbywać się na JVM.
Javier
O ilu wierszach kodu mówimy? Może warto poświęcić czas na jego przepisanie, ale nie jest to prosta decyzja. Ponadto, jeśli twój kod wykonuje arytmetykę wskaźników, byłbym ciekawy, jak to się robi podczas pracy na JVM.
Levi Morrison
1
Debugowanie powinno być zabawne O_o
Daniel Gratzer
@LeviMorrison. Cóż, kod jest dość obszerny (różne zależności bibliotek do komunikacji, funkcje użyteczności), ale zakłada się, że cały kod jest dostępny w czasie kompilacji. A także, jeśli inny klient tego nie wymaga, nadal będziemy generować natywny plik binarny.
Javier,
@jozefg. O arytmetyce wskaźnika i celu debugowania Nie oczekuję, że będę debuggowany. Na przykład Emscripten robi to samo, ale językiem docelowym jest JavaScript. Kończymy tylko tablicą z dużymi bajtami jako operacją stosu i bitów dla licznika programów i po prostu z bajtami bez obiektów, ciągów znaków itp. Oczekuję, że wynik podobny do assamblear w kodzie bajtowym Java, można założyć, że nie jest on debuggowany.
Javier,

Odpowiedzi:

11

Naprawdę wątpię, żeby to zadziałało. Być może będziesz w stanie przetłumaczyć swój kod na bajtowy kod Java, ale nie spowoduje to magicznej translacji wywołań biblioteki na równoważne wywołania środowiska wykonawczego i bibliotek Java. Mogą nawet nie istnieć równoważne wywołania środowiska wykonawczego Java! Nawet jeśli wyeliminujesz wszystkie zastrzeżone biblioteki, nadal będziesz mieć standardową bibliotekę C ++.

Aby uczynić to konkretnym: twój program C ++ może zawierać wywołanie fprintf (). Ta funkcja jest zaimplementowana w standardowej bibliotece C i jest całkowicie uzasadniona, aby program C ++ mógł ją wywołać. Translator LLVM na LLJVM prawdopodobnie nie zamierza magicznie ustalić sekwencji wywołań środowiska wykonawczego Java, które dadzą wynik równoważny z funkcją fprintf () i zastąpi je w. Aby zapewnić tę funkcję, konieczne będzie zasadniczo ponowne wdrożenie środowisk wykonawczych C i C ++ w Javie kod bajtowy.

Istnieje kilka narzędzi, które wykonują tłumaczenie z C ++ na Java, ale konwertują tylko kilka prostszych wywołań biblioteki wykonawczej. Resztę pozostawiasz do rozgryzienia.

Charles E. Grant
źródło
Rozumiem twój punkt widzenia, ale o ile rozumiem emscripten robi coś podobnego z celem, jakim jest JavaScript, jeśli nie zrozumiałem źle, emscripten zapewnia niestandardową standardową bibliotekę, aby uniknąć tego, co wskazałeś (a nawet odwzorowań dla webGL przez bibliotekę SDL) ). Ale nie mogę znaleźć odpowiednika dla Javy (LLJVM wydaje się porzucony). Zastanawiam się nad zaproponowaniem kodu bajtowego llvm jako kompilacji niezależnej od platformy (oczywiście bez gałęzi kompilacji zależnych od platformy, według API lub danych; za pomocą aprlub podobnych)
Javier Mr
3
lljvm zapewnia bibliotekę wykonawczą C, częściowo jako C skompilowaną do kodu bajtowego JVM, a częściowo jako klasy Java. To całkiem kompletne libc. Musisz stworzyć odpowiednik dla libstdc ++. Poza tym backend lljvm nie obsługuje obecnie C ++. Próbowałem naprawić lljvm do pracy z nowszą wersją llvm. Powoli postępuje, ponieważ interfejsy API i narzędzia lvvm zmieniają się tak bardzo między wydaniami. Możesz śledzić tutaj, teraz jest prawie w użytecznej formie. github.com/hyc/lljvm/tree/llvm3.3
hyc