llvm-fs can be used to write your LLVM compiler in a .NET language. The code is all F# but an effort has been made to make the library easy to use from C#. See test/CSSimpleTest.cs for an example of how you can call the llvm-fs functions from C#. If you have questions or comments about llvm-fs you can use the project google group: http://groups.google.com/group/llvm-fs
NOTE: this has been tested on OS X 10.6 and on Windows 7 (using MinGW bash/gcc/g++ with python 2.7 installed)
Download a copy of the LLVM 3.3 source code. In order to use the LLVM native
libraries with llvm-fs they must be built with
Unfortunately the prebuilt LLVM binaries don't come with shared libraries so you
will have to build LLVM yourself. For windows you can do this by using a build
./configure --enable-shared --enable-jit && make && make install.
OS X 10.6 needs more convincing to build the 32-bit libraries as required to
work with mono. The following LLVM configuration works on 10.6:
CXX='g++ -m32' CC='gcc -m32' CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32 ./configure \ --disable-bindings --build=i686-apple-darwin --host=i686-apple-darwin \ --target=i686-apple-darwin --enable-targets=x86,x86_64 \ --enable-optimized --enable-shared --enable-jit
OS X/mono: On OS X run the
./build.bash script to generate the LLVMFsharp.dll
assembly. This should also work on Linux but is untested (Please let me know if
it works on Linux for you).
Windows 7: open the llvm-fs.fsproj project file and build the project. This will generate the LLVMFsharp.dll assembly for you.
In order to use llvm-fs you will want to consult the following:
- Example F# and C# code under the ./test directory. If you are using mono you
can see how these tests are built and run by un-commenting everything under
# uncomment the following to build and run the testsin the build.bash file.
- The LLVM C documentation. Almost all of the llvm-fs binding functions are auto-generated from the C header files so these docs are very useful.
- The LLVMFSharp.fsi file for all of the types and function signatures and of course the source code.
You can use F# Quotations to build LLVM functions. Using quotations is much more concise and simple than the API but there are caveats:
- The F# quotations are treated a way to represent LLVM IR more than F# code, so F# semantics are not 100% respected.
Many common F# language constructs are not supported for simplicity and so that the code in quotations will map fairly directly to LLVM IR code. Examples of this are that:
- quotations only allow you to use a part of the functionality that is available in the LLVM API
- the only supported types are:
double, tuples and arrays (using
LLVM.Quote.RawArraytype which does not have a length property)
- functions cannot be treated as first class values and partial application is not supported
- there are no exceptions and there is no garbage collection. Any items
allocated on the heap should be freed using the
LLVM.Quote.freefunction. Tuple construction is always done on the heap and arrays can be allocated on the heap using
LLVM.Quote.heapAllocRawArrayor on the stack using
- functions can only be top level definitions (closures are not supported)
- the list of top level function definitions in your quotation must end with
a single unit value
These limitations are not set in stone and new F# language features may be added in the future as long as doing so maintains the goal of having an almost direct mapping from F# code to LLVM code.
To get a better idea of how you can build functions with quotations take a look
at the examples in
test/quotetest.fs which generates all of the functions
Regenerating bindings should not be necessary unless you're building bindings to
a new version of LLVM. If you want to do this start with the
script and ask questions on the project list if you have problems.