Compile Java source to LLVM IR [duplicate] - llvm-ir

From what I've read, there is a llvm program that converts java bytecode to llvm's intermediate form called class2llvm. My question is, how do I access this. What front end do I have to install in order to access this.
VMkit is their implementation of a JVM, but I am looking for how to compile the java source code with llvm, not how to run it.

The Java frontend translates Java bytecode (.class files) into LLVM
bytecode. Take a look at this link:
https://llvm.org/svn/llvm-project/java/trunk/docs/java-frontend.txt

You may take a look at dragonegg, which enables llvm to use gcc's frontends. As gcc already has a frontend for java, called gcj, perhaps llvm can use it to compile java code. But I'm not sure how well llvm interfaces with the gcc frontend, so this may not work.

I have executed a java class using vmkit ( http://vmkit.llvm.org/ ) based on LLVM. It uses LLVM for compiling and optimizing high-level languages to machine code. J3 is an implementation of a JVM with VMKit.

[NOTE: From November 2015 it is no longer open source, so this hack is mostly useless.]
RoboVM might become the solution you're looking for. It's open source and compiles JVM bytecode (.class files) to machine code.
I assume they do it using something like class2llvm.
Unfortunately, it's still in alpha. I just tested it on HelloWorld.java. It gave 5x speed up of load time running on a single core. (Most of the run time is load time.)
echo Hello World! : <1 ms : 31K (/usr/bin/echo binary)
java HelloWorld : ~70 ms : 0.4K (HelloWorld.class JVM bytecode)
./HelloWorld : ~13 ms : 9.4MB (9.3MB binary + 57K robovm-rt.jar)
Note that java calls a 32MB $JAVA_HOME/lib/rt.jar file (and maybe more). Searching in such a large file must be part of the reason java is so slow to load. If RoboVM gets smarter, perhaps it can throw out most of the 9.3MB binary for an even faster load?
The website mentions iOS, but I think that's because they're selling their add-on UI libraries. RoboVM compiled fine for me on a flavor of Ubuntu. Just make sure to do
$ sudo apt-get install g++-multilib
first (and maybe install libpthread-stubs0-dev and libpthread-workqueue0...don't know if they mattered).

Related

Crystal-lang: why is the LLVM "hello.bc" not the same if generated by Crystal or by clang?

this is my first Stackoverflow question :-)
My background:
2 years Python experience
2 months crystal-lang experience ( websites running with Amber framework )
1 month into C, C++ , assembly
Facts:
- crystal-lang is compiling and running without any problem
- running on x86_64
Please be nice, as i don't have much low-level language knowledge yet.
From my understanding, when we compile and run a basic hello.c file using LLVM, it goes as follow:
hello.c :
#include
int main() {
printf("hello world\n");
return 0;
}
shell :
$ clang -O3 -emit-llvm hello.c -c -o hello.bc
$ llc hello.bc -o hello.s
$ gcc hello.s -o hello.native
$ ./hello.native
this comes from the LLVM examples )
My point is that we can produce a pretty short hello.bc file (128 lines) that can be run in a slower way using:
$ lli hello.bc
but when I tried to generate a similar hello.bc from a hello.cr file and run it like i did with the hello.c file:
hello.cr :
puts "hello world"
shell :
$ crystal build hello.cr --emit llvm-bc --release
$ llc hello.bc -o hello.s
what i noticed:
This hello.bc file is much much bigger than the one generating from the c file (43'624 lines)
This hello.bc can't be run using "lli" as it generates an:
"LLVM ERROR: Program used external function 'pcre_malloc' which could not be resolved!
I can't even compile from hello.s to hello.native
Same problem if i try to use generate and hello.ll file
As i understood, LLVM is portable , and that all front-end languages would produce an intermediate *.bc that can then be compiled to any architecture.
My questions are:
Why are the hello.bc not similar in both cases ?
Am I doing something wrong in the crystal procedure ?
Thank you!
Everything is just as it is supposed to be. Crystal has a runtime library that is always present even if you didn't include anything. This is required to run the Crystal program.
The C example pretty much doesn't contain anything else than a syscall to printf. That's why the compiled ASM is also really tiny.
Crystal's simple puts call has a much more behind it. It is based on libraries for handling asynchronous IO, concurrency, signal handling, garbage collection and more. Some of these libraries are completely implemented in the Crystal standard library, some use other libraries that are either directly embedded into the binary (libgc) or still require dynamic libraries from the system (libpcre, libpthread).
Any Crystal program comes with this runtime library by default. Even an empty program. This usually goes completely unnoticed because larger programs will eventually need those things anyway and the compiled binary size of the runtime library is less than 500 KB (in release mode).
Such a small program like yours doesn't really need all of this just to print a string. But these libraries are required for the Crystal runtime.
NOTE: You can compile a Crystal program without these default libraries. But this means you can't use anything from the Crystal stdlib and you have to essentially write C code with Crystal syntax (or implement your own stdlib):
require "lib_c"
require "c/stdio"
LibC.printf pointerof("hello world".#c)
This can be compiled with --prelude=empty option and it will generate a substantially smaller ASM, roughly similar to the C example.

Ada GPS IDE Compiler error Undefined symbols for architecture x86_64

Trying to get GtkAda to work. Didn't compile the lib myself, had a lot of problems and finally I found a precompiled library on the internet. Of course GPS didn't find it even after adding it to my path...
So I added it manually to my project and GPS began the compilation. It is just a simple example to see if everything works. Just beginning to learn programming.
WITH Gtk.Main ;
USE Gtk.Main ;
WITH Gtk.Window ;
USE Gtk.Window ;
WITH Gtk.Enums ;
USE Gtk.Enums ;
PROCEDURE MaFenetre IS
win : Gtk_window ;
BEGIN
Init ;
Gtk_New(win,Window_Popup) ;
win.show ;
Main ;
END MaFenetre ;
Which gave me this error:
gnatlink /Users/laurentlutgen/GPS/mafenetre.ali -o
/Users/laurentlutgen/GPS/mafenetre
Undefined symbols for architecture x86_64:
"_ada_c_enum_value_size", referenced from:
.
.
.
"_pango_tab_array_new", referenced from:
pango_tabs__pango_new in pango-tabs.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit
status gnatlink: error when calling /usr/local/gnat/bin/gcc
gnatmake: * link failed.
[2013-08-01 21:16:46] process exited with
status 4 (elapsed time: 09.38s)
The list of files the compiler complains about is quite long so.
Anyone an idea how to solve this.
I use the last version of gnat (2013) from AdaCore for MacOS X. I use MacOS 10.8.
The GtkAda library is xadalib 2012.
Thanks
Laurent
From what I see, gnatlink does not get passed the libraries needed to link against. You said that you added GtkAda to your project manually. By doing this, you probably missed all the linker options specified in the *.gpr file of GtkAda, so your binary does not get linked against the GTK+ library.
I suggest you try to get GPS to find the installed GtkAda project file. You can do this by setting ADA_PROJECT_PATH before launching GPS. If GtkAda is located in GNAT GPL's default path, it looks like this:
$ export ADA_PROJECT_PATH="/usr/local/gnat/lib/gnat"
$ gps
You said you're using a precompiled binary you found on the internet. Are you aware that GtkAda is bundled with the GNAT GPL compiler? You should use that, unless you want to use gtk-quartz as backend (which doesn't require X11). If that's the case, you may find the instructions I wrote for compiling GPS with gtk-quartz helpful (as Simon already noted).
If you want, you can try my GPS port to OSX. By default, it is able to load the *.gpr files bundled with GNAT GPL. On the Usage page, you find instructions of how to change the ADA_PROJECT_PATH if you installed your GNAT somewhere else.
For further help, you should post the *.gpr file of your project.
Edit:
I stand corrected: GtkAda is in fact not included in the GNAT GPL distribution for whatever reason. As XmlAda is included as project to link against, I was sure GtkAda was too, but it isn't; so using XAdaLib seems to be the easiest option. You have to point ADA_PROJECT_PATH to the installation directory of XAdaLib instead of the usual GNAT one to be able to use GtkAda.
As far as I know none of the GPL'ed GNATs from AdaCore for x86 have the capability to generate 64-bit code. I think I read something to that effect somewhere but cannot remember where.
The issue also came up in the Ada-port of Doom3, so if you can find him he might know for sure.

Compiling haskell module Network on win32/cygwin

I am trying to compile Network.HTTP (http://hackage.haskell.org/package/network) on win32/cygwin. However, it does fail with following message:
Setup.hs: Missing dependency on a foreign library:
* Missing (or bad) header file: HsNet.h
This problem can usually be solved by installing the system package that
provides this library (you may need the "-dev" version). If the library is
already installed but in a non-standard location then you can use the flags
--extra-include-dirs= and --extra-lib-dirs= to specify where it is.
If the header file does exist, it may contain errors that are caught by the C
compiler at the preprocessing stage. In this case you can re-run configure
with the verbosity flag -v3 to see the error messages.
Unfortuntely it does not give more clues. The HsNet.h includes sys/uio.h which, actually should not be included, and should be configurered correctly.
Don't use cygwin, instead follow Johan Tibells way
Installing MSYS
Install the latest Haskell Platform. Use the default settings.
Download version 1.0.11 of MSYS. You'll need the following files:
MSYS-1.0.11.exe
msysDTK-1.0.1.exe
msysCORE-1.0.11-bin.tar.gz
The files are all hosted on haskell.org as they're quite hard to find in the official MinGW/MSYS repo.
Run MSYS-1.0.11.exe followed by msysDTK-1.0.1.exe. The former asks you if you want to run a normalization step. You can skip that.
Unpack msysCORE-1.0.11-bin.tar.gz into C:\msys\1.0. Note that you can't do that using an MSYS shell, because you can't overwrite the files in use, so make a copy of C:\msys\1.0, unpack it there, and then rename the copy back to C:\msys\1.0.
Add C:\Program Files\Haskell Platform\VERSION\mingw\bin to your PATH. This is neccesary if you ever want to build packages that use a configure script, like network, as configure scripts need access to a C compiler.
These steps are what Tibell uses to compile the Network package for win and I have used this myself successfully several times on most of the haskell platform releases.
It is possible to build network on win32/cygwin. And the above steps, though useful (by Jonke) may not be necessary.
While doing the configuration step, specify
runghc Setup.hs configure --configure-option="--build=mingw32"
So that the library is configured for mingw32, else you will get link or "undefined references" if you try to link or use network library.
This combined with #Yogesh Sajanikar's answer made it work for me (on win64/cygwin):
Make sure the gcc on your path is NOT the Mingw/Cygwin one, but the
C:\ghc\ghc-6.12.1\mingw\bin\gcc.exe
(Run
export PATH="/cygdrive/.../ghc-7.8.2/mingw/bin:$PATH"
before running cabal install network in the Cygwin shell)

Qt Creator tag file

I use vim for C++ code editing. But its code completion isn't so good (although I have tried many plugins, such as OmniCppComplete). The Qt Creator code completion is awesome, and it also has vim style editing which functionality is full enough for me. Only thing that isn't so good for me is that I cannot use ctags functionality inside Qt Creator (although Qt Creator has functionality to go to class definition, but it takes a lot more time to parse the source code).
Is it possible to create the source code tag file and use it with in Qt Creator in fake vim mode?
Code completion for C++ in Vim is actually superior. I'll outline the steps you have to take in order to make it work. However, I won't go into much detail here (such as building huge open-source code base, cloning a repository, installing plugins for Vim, etc.) because otherwise it would be worth writing a large tutorial for novices. So, assuming that you are well-aware and well-prepared software developer, there you go a fluent guide:
Get and install clang_complete (plugin for Vim);
Get and install neocomplcache (plugin for Vim);
If you are on Unix, then you are lucky because you probably have LLVM and Clang either installed on your system already or you have to use package manager and install them with a single command. If so, then you can immediately jump to the last step (#7).
If you are on Windows, then you are less lucky, but that's actually better from the practical point of view - you'll have a great experience of building huge stuff on your own and getting things to work no matter what. :)
So, if you're on Windows (and using Qt Creator as I can see), then you might have MinGW already installed on your system. If that's not the case, then I strongly suggest that you to install a bleeding-edge MinGW-w64. Fortunately, you don't have to compile it yourself as rubenvb has kindly built MinGW-w64 toolchain in both variants: targeting 64-bit Windows (aka x64) and targeting 32-bit Windows (aka x86). Just download one depending on your OS. NOTE: These links are pointing to the latest (at the time of writing this answer) stable builds of MinGW-w64, i.e. based on GCC 4.7.2. IMPORTANT: Make sure that MinGW-w64 is in the %PATH% environment variable.
Another piece of software needed is CMake (a popular build system). Again, if you are on Unix it might be installed already. If you are on Windows, then just download and install it. IMPORTANT: Make sure that CMake is in the %PATH% environment variable.
The last thing we'll need is Python. Once again, if you are on Unix, then it is already installed on your system. Otherwise, you know what to do already. :) Officially, there are 2 versions of Python: 2.7.3 and 3.x.x - you should definitely download and install both. Python is an essential piece of software on any developer's machine. IMPORTANT: Make sure that Python 2.7.3 (not 3.x.x!) is in the %PATH% environment variable.
Now that we have MinGW-w64, CMake, Python installed, we are ready to build LLVM and Clang. To ease the pain go to my Out-of-Source Builders project and scroll down to Guide: Build 64-bit LLVM and Clang for Windows (64-bit) Using MinGW-w64. If you are on 32-bit Windows, don't pay attention to 64-bit (it does not matter) in the title, just follow the instructions there. Wait for about an hour until LLVM and Clang are built.
We are almost done, all that is left is to configure Vim properly. Here I'll simply provide my configuration which would most likely satisfy your needs.
Configure neocomplcache:
let g:neocomplcache_enable_at_startup = 1
let g:neocomplcache_enable_smart_case = 1
let g:neocomplcache_enable_camel_case_completion = 1
let g:neocomplcache_enable_underbar_completion = 1
let g:neocomplcache_min_syntax_length = 2
if !exists('g:neocomplcache_force_omni_patterns')
let g:neocomplcache_force_omni_patterns = {}
endif
let g:neocomplcache_force_overwrite_completefunc = 1
let g:neocomplcache_force_omni_patterns.c = '[^.[:digit:] *\t]\%(\.\|->\)'
let g:neocomplcache_force_omni_patterns.cpp = '[^.[:digit:] *\t]\%(\.\|->\)'
\ . '\|\h\w*::'
let g:neocomplcache_force_omni_patterns.objc = '[^.[:digit:] *\t]\%(\.\|->\)'
\ . '\|\h\w*::'
let g:neocomplcache_force_omni_patterns.objcpp = '[^.[:digit:] *\t]\%(\.\|->\)'
\ . '\|\h\w*::'
inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
Configure clang_complete:
let g:clang_use_library = 1
let g:clang_auto_select = 0
let g:clang_complete_auto = 0
let g:clang_complete_copen = 1
let g:clang_complete_macros = 1
let g:clang_complete_patters = 1
let g:clang_library_path = 'D:/Toolchains/x64/LLVM/3.3/bin'
let g:clang_auto_user_options = 'path, .clang_complete'
For more information on both of these plugins use Vim's help documentation: :h clang_complete and :h neocomplcache. There are lots of options to tweak, especially in neocomplcache. From my point of view both plugins are must have for any C++ developer who uses Vim.
NOTE: If you don't know how to complete some of the steps listed here, you would have to either ask additional questions here on StackOverflow or look elsewhere for the reason described in the beginning of this answer.
I hope this helps and you would favor Vim more for your development efforts from now. :)

Partial compilation of openwrt project

I would like to get an idea or reference to compile only subset on the openwrt project.
i am aware of the menuconfig utility but this is not enough for my goal.
i would like to compile only the tool-chain (binutils + gcc + glibc) for a specific target (ar71xx) and also the kernel.
now, after looking in the makefiles etc, i have noticed that most of the work in actually patching the toolchain and the kernel and then compile it. is there any option to stop build process after the patching so i can have only the source code patched and i can write my own make file to compile it?
To prepare (patch) toolchain independently:
make toolchain/{clean,prepare} V=99
To extract the kernel source and patch it:
make target/linux/{clean,prepare} V=99
The patched kernel source will be in build_dir/linux-$(target)/linux-$(version)

Resources