Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

JavaWorld Daily Brew

Building LLVM on Windows using MinGW32

 

As I've mentioned in passing, one of the things I'm playing with in my spare time
(or will play with, now that I've got everything working, I think) is the LLVM
toolchain
. In essence, it looks to be a parallel to Microsoft's Phoenix, except
that it's out, it's been in use in production environments (Apple is a major contributor
to the project and uses it pretty extensively, it seems), and it supports not only
C/C++ and Objective-C, but also Ada and Fortran. It's also a useful back-end for people
writing languages, hence my interest.

One of the things that appeals about LLVM is that it uses an "intermediate representation"
that in many ways reminds me of Phoenix's Low IR, though I'm sure there are significant
differences that I'm not well-practiced enough to spot. Consider this bit of Fibonacci
code, for example:

 1: define
i32 @fib(i32 %AnArg) {
 2: EntryBlock:
 3: %cond
= icmp sle i32 %AnArg, 2 ; <i1> [#uses=1]
 4: br
i1 %cond, label %return, label %recurse
 5:  
 6: return:
; preds = %EntryBlock
 7: ret
i32 1
 8:  
 9: recurse:
; preds = %EntryBlock
 10: %arg
= sub i32 %AnArg, 1 ; <i32> [#uses=1]
 11: %fibx1
= tail call i32 @fib( i32 %arg ) ; <i32> [#uses=1]
 12: %arg1
= sub i32 %AnArg, 2 ; <i32> [#uses=1]
 13: %fibx2
= tail call i32 @fib( i32 %arg1 ) ; <i32> [#uses=1]
 14: %addresult
= add i32 %fibx1, %fibx2 ; <i32> [#uses=1]
 15: ret
i32 %addresult
 16: }
 17:  
 18: declare void @abort()

It's rather interesting to imagine this as a direct by-product of that first pass
off of the hypothetical Universal AST....

Getting this thing to build has been an exercise of patience, however.

The documentation on the website, while extensive, isn't very Windows-friendly. For
example, there's a page that describes how to build it with Visual Studio, but it's
a touch out-of-date. On top of that, it turns out that the VS/LLVM tools can't compile to
LLVM bitcode, only execute it once it's in that format; you need "llvm-gcc" to compile
to bitcode, which means you're left with a two-machine solution: a *nix box using
llvm-gcc to compile the code, and then your Windows box to run it. Ugh.

Fortunately, Windows users have two choices for dealing with *nix solutions: Cygwin
and MinGW32. The first tries to lay down a *nix-like layer on top of the Win32 APIs
(meaning everything depends on cygwin1.dll once built), the second tries to provide
an adapter layer such that when a *nix tool is done building, it has no dependencies
beyond what you'd see from any other Win32 app. Debates rage about the validity of
each, and rather than seem like I'm coming down in favor of one or the other, I'll
simply note that I have both installed in my Languages VMWare image now, and leave
it at that.

Building LLVM with MinGW was a bit more painful than I expected, however, so for a
long time I just didn't bother. Last night that changed, thanks to Anton Korobeynikov,
who spent the better part of three or four hours in back-and-forth email conversation
with me, walking me patiently through the step-by-step of getting MinGW and msys up
and running on my machine long enough to build the LLVM 2.2+ (meaning the tip beyond
the current 2.2 release) code base. I can't thank him enough--both for the direct
help in getting the MinGW bits up and in the right places as well as for the casual
conversation about MinGW along the way--so I thought I'd replicate what we did on
my box to the 'Net in an attempt to spare others the effort.

First, there's a pile of tarballs from the MinGW download page that require downloading and
extracting:

  • gcc-g++-3.4.5-20060117-1.tar.gz
  • binutils-2.18.50-20080109.tar.gz
  • mingw-runtime-3.14.tar.gz
  • gcc-core-3.4.5-20060117-1.tar.gz
  • w32api-3.11.tar.gz

Note that I also pulled down the other gcc- tarballs (gcj, objc and so on), just because
I wanted to play with the MinGW versions of these tools. Extract all of these into
a directory; on my system, that's C:/Prg/MinGW.

(There is a .exe installer on the Sourceforge page that supposedly manages all
this for you, but it installed the binutils-2.17 package instead of 2.18, and I couldn't
figure out how to get it to grab 2.18. All it does is download these packages and
extract them, so going without it isn't a huge ordeal.)

By the way, if you're curious about experimenting with gcj as well (hey, it's a Java
compiler that compiles to native code--that's interesting in its own right, if you
ask me), take careful note that as it stands right now in the installation process,
you can run gcj but can't compile Hello.java with it--it complains about a missing
library, "iconv". This is a known
bug
, it seems, and the solution is to install libiconv from
the GnuWin32 project--just extract
the "bin" and "lib" packages into C:/Prg/MinGW.

At this point, you're done with C:/Prg/MinGW32.

Next, there's a couple of installers and additional tarballs that need downloading
and extracting:

  • MSYS-1.0.10.exe
  • msysDTK-1.0.1.exe
  • bash-3.1-MSYS-1.0.11-1.tar.bz2
  • bison-2.3-MSYS-1.0.11.tar.bz2
  • flex-2.5.33-MSYS-1.0.11.tar.bz2
  • regex-0.12-MSYS-1.0.11.tar.bz2 (required by flex)

The first two just execute and install; on my system, that is C:/Prg/msys/1.0. The
next one just extracts into the C:/Prg/msys/1.0 directory. The last three are a tad
tricky, however--apparently they assume that everything should be installed into a
top-level "usr" directory, and that's not quite where we want them; we want
them. Apparently, we want them installed directly (so that "/usr/bin" from bison goes
into "/bin" inside of "C:/Prg/msys/1.0"), so extract these to a temporary directory,
then xcopy everything inside the temp/usr directory over to C:/Prg/msys/1.0.
(That is, "cd temp", then "cd usr", then "xcopy /s/e * C:/Prg/msys/1.0".)

At this point, we're done with the setup--create a directory into which you want LLVM
built (on my system, that's C:/Prg/LLVM/msys-build, where the source from SVN is held
in C:/Prg/LLVM/llvm-svn), and execute the "configure" script in this directory (that
is, "cd C:/Prg/LLVM/msys-build" and "../llvm-svn/configure"). The script will deposit
a bunch of makefiles and directories into the build directory, after which a simple
"make" suffices to build everything (in Debug; if you want Release, do "make ENABLE_OPTIMIZED=1",
as per the LLVM documentation).

Thanks again, Anton! Now can you help me get llvm-gcc working? :-)





Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. Contact
me for details
.