Prerequisites:
cabal update && cabal install cabal-install
git clone git@github.com:ghc-ios/ghc-ios-scripts.git ~/bin/ghc-ios-scripts
echo -e "\nPATH=~/bin/ghc-ios-scripts:"'$PATH' >> ~/.profile
PATH=~/bin/ghc-ios-scripts:$PATH
Run the installer script. GHC iOS will politely live alongside your existing native GHC installation.
installGHCiOS.sh
Create or open an Xcode project (the Single View Application template is simple for testing)
Use this repository's HaskelliOS.xcconfig
Compile your Haskell code with ghc-ios. For example, if you had a file named Counter.hs:
{-# LANGUAGE ForeignFunctionInterface #-}
module Counter where
import Control.Concurrent
import Control.Monad
foreign export ccall startCounter :: Int -> IO ()
startCounter :: Int -> IO ()
startCounter = void . forkIO . void . loop
where loop i = do
putStrLn (replicate i 'o')
threadDelay (10^6)
loop (i + 1)
Compile this like so to get Counter.a and Counter_stub.h:
ghc-ios Counter.hs
(Counter.a will be a fat binary that works with both devices and the simulator.)
Drag Counter.a and Counter_stub.h to the project's sidebar. Make sure "Add to Targets:" has a check next to your app.
In main.m #import "HsFFI.h"
and add hs_init(NULL, NULL);
to the top of main()
In your app's AppDelegate.m:
#import "Counter_stub.h"
and at the top of application:didFinishLaunchingWithOptions:, add:
startCounter(3);
Run your app! You should see a growing triangle of 'o's.
To automatically rebuild your Haskell file each time you rebuild your project:
source ~/.profile # or ~/.bash_profile, whichever you use
ghc-ios Counter
Xcode will now run these commands each time it builds your project.
cabal install cabal-install
cabal-ios install random
If you run into Illegal instruction: 4
while running make install
, please see this discussion https://github.com/ghc-ios/ghc-ios-scripts/issues/4 — we're not sure what causes it yet but the thread contains a working solution.
Some packages need a flag to make them use integer-simple rather than trying to use integer-gmp, for example
cabal-ios install -finteger-simple text
and
cabal-ios install -f-integer-gmp hashable
Similarly, some packages need to have Template Haskell disabled, such as
cabal-ios install -f-templateHaskell QuickCheck
and
cabal-ios install distributed-process --flags=-th
You can check the .cabal file to find the appropriate option.
cabal get
and manually comment out the executables section in the .cabal file, then cabal install
'ing the edited copy. You can use this strategy to get rid of Template Haskell in packages that don't provide a flag to do so, such as aeson. But consider submitting a patch to the developers : )