Skip to content

Instantly share code, notes, and snippets.

@seanjensengrey
Last active July 16, 2016 23:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seanjensengrey/c423a5ab0276758030e74f501a63994f to your computer and use it in GitHub Desktop.
Save seanjensengrey/c423a5ab0276758030e74f501a63994f to your computer and use it in GitHub Desktop.

Setting up Haskell to Build corrode

Corrode is a Haskell program that translates C programs into Rust programs.

As of Jul 16, 2016 it compiles with GHC The Glorious Glasgow Haskell Compilation System, version 7.10.3, 8.0.1 the current homebrew version, will exit with dependency failures in base-4.8.0.0.

To install the needed tooling to compile corrode on OSX do the following

Install GHC 7.10 and cabal

Hombrew currently has GHC 8.0.1 as the latest compiler. We will need to temporarily revert to an older commit hash to install GHC 7.10

pushd $(brew --prefix)
cd Library/Formula
git checkout baf2e43358530cc07f2ee7ae771417046c11e1bd ghc.rb
brew install ghc cabal
git checkout -- ghc.rb
popd

Update cabal's package repo

cabal update

checkout corrode

git clone https://github.com/jameysharp/corrode
cd corrode

Create a cabal sandbox, add sandbox to path

cabal sandbox init
PATH=$(pwd)/.cabal-sandbox/bin:$PATH

Install build tool dependencies for language-c

cabal install happy
cabal install alex

Build corrode

cabal build
cabal install

Test Corrode

In a file ten.c

int main(int argc, char** argv) {
    int j = 4;
    int k = 0;
    for(int i=0; i<10; i++) {
        k = j * i;
    }
    return k;
}

corrode ten.c

Will emit something like

fn main() {
    use std::os::unix::ffi::OsStringExt;
    let mut argv_storage
        = std::env::args_os().map(
              |str| ({
                         let mut vec = str.into_vec();
                         vec.push(b'\0');
                         vec
                     })
          ).collect::<Vec<_>>(
          );
    let mut argv
        = argv_storage.iter_mut().map(|vec| vec.as_mut_ptr()).chain(
              Some(std::ptr::null_mut())
          ).collect::<Vec<_>>(
          );
    let ret
        = unsafe {
              _c_main(argv_storage.len() as (i32),argv.as_mut_ptr())
          };
    std::process::exit(ret);
}

#[no_mangle]
pub unsafe fn _c_main(mut argc : i32, mut argv : *mut *mut u8) -> i32 {
    let mut j : i32 = 4i32;
    let mut k : i32 = 0i32;
    {
        let mut i : i32 = 0i32;
        while i < 10i32 {
            {
                k = j * i;
            }
            i = i + 1;
        }
    }
    k
}

If you are seeing errors like

Resolving dependencies...
cabal: Could not resolve dependencies:
trying: corrode-0.1.0.0 (user goal)
next goal: base (dependency of corrode-0.1.0.0)
rejecting: base-4.9.0.0/installed-4.9... (conflict: corrode => base>=4.8 &&
<4.9)
rejecting: base-4.9.0.0, base-4.8.2.0, base-4.8.1.0, base-4.8.0.0,
base-4.7.0.2, base-4.7.0.1, base-4.7.0.0, base-4.6.0.1, base-4.6.0.0,
base-4.5.1.0, base-4.5.0.0, base-4.4.1.0, base-4.4.0.0, base-4.3.1.0,
base-4.3.0.0, base-4.2.0.2, base-4.2.0.1, base-4.2.0.0, base-4.1.0.0,
base-4.0.0.0, base-3.0.3.2, base-3.0.3.1 (constraint from non-upgradeable
package requires installed instance)
Dependency tree exhaustively searched.

Note: when using a sandbox, all packages are required to have consistent
dependencies. Try reinstalling/unregistering the offending packages or
recreating the sandbox.

It most likely means you are on GHC 8 and above, you will need to run GHC 7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment