Calling a simple function written in Rust from Idris
bvssvni opened this issue · 0 comments
To call Rust from Idris, you need to generate IR code to make it freestanding (not depending on runtime).
IR code is an intermediate language for LLVM which can then be compiled to a ".o" file.
In addition you need to write a C header file manually so Idris can link to a ".o" and a ".h" file.
Idris does not know it is calling Rust, so the type system is limited to C.
Here is the Idris code, in a file Main.idr
.
module Main
%include C "idrisfs.h"
%link C "idrisfs.o"
getSizeInt : IO Int
getSizeInt = mkForeign (FFun "sizeof_int" [] FInt)
main : IO ()
main = do
x <- getSizeInt
putStrLn (show x)
Here is the Rust code, in a file lib.rs
:
#![crate_id = "idrisfs"]
#![deny(missing_doc)]
//! Documentation goes here.
/// Returns the number of bytes in an int.
#[no_mangle]
pub extern "C" fn sizeof_int() -> int {
std::mem::size_of::<int>() as int
}
Here is the C header in a file idrisfs.h
:
#ifndef IDRISFS
#define IDRISFS
int sizeof_int(void);
#endif
Command for generating IR:
rustc lib.rs -o idrisfs.ll --crate-type=lib --emit=ir
In order to use llc
you need to add it to the PATH variable.
On OSX this is done to the .bash_profile
file in the ~
directory.
On my system this becomes:
export PATH="/usr/local/Cellar/llvm/3.4/bin/":$PATH
Then you can execute the last command:
llc idrisfs.ll -o idrisfs.o -filetype=obj
To run, you can do idris Main.idr
and then :exec
.
It should print 8
.