Skip to content

Commit

Permalink
Some notes about building ghc cross compiler for android
Browse files Browse the repository at this point in the history
  • Loading branch information
RudolfVonKrugstein committed Jan 13, 2013
1 parent b110629 commit 7b2dea2
Show file tree
Hide file tree
Showing 5 changed files with 317 additions and 0 deletions.
105 changes: 105 additions & 0 deletions android_ghc/android_ghc.md
@@ -0,0 +1,105 @@
Install android ndk!
If I do

arm-linux-androideabi-gcc -print-sysroot

it outputs

/tmp/ndk-andrewhsieh/build/toolchain/prefix/sysroot

so I do (I am sure there are other ways, but this works):

alias ndk_setup=" mkdir -p /tmp/ndk-andrewhsieh/build/toolchain/prefix && ln -s $ANDROID_NDK/platforms/android-9/arch-arm /tmp/ndk-andrewhsieh/build/toolchain/prefix/sysroot"

Install iconv-android (static!): https://github.com/ironsteel/iconv-android
and ncurses: http://credentiality2.blogspot.de/2010/08/compile-ncurses-for-android.html
for the android ndk

checkout ghc:

git clone http://darcs.haskell.org/ghc.git/
./sync-all --no-dph get

apply patch 2 and 3 from http://web.archiveorange.com/archive/v/j7U5dAvNego9GwzeIPFn (0001-Set-up-for-QNXNTO-OS.patch not needed).
These are needed for a cross compile.

Some more patches are needed!
To inform llvm of the target architecture, apply mtriple.patch.
I wonder if one should also add a data layout here???

In the ndk headers, winsize is defined in terminfo.h.
in libraries/haskeline: add-terminfo.patch

For some reason in the android ndk build system when including termios.h, the offsetof macro is set to something, that can not be used as a constant expression (see http://stackoverflow.com/questions/14233983/storage-size-not-constant-when-using-offsetof-and-including-termios-h-with-andro)
in utils/hsc2hs: offset.patch

There seem to be some more differences in the posix headers in the android ndk.
Some pw_gecos field of passwd struct is missing. We replace it with pw_name. Also telldir and seekdir are missing. We just remove those from the ffi.
In libraries/unix apply unix-posix.patch

Some ubuntu package one needs (hopefully complete list):

sudo apt-get install autoconf libtool autotools-dev happy alex

Create a build.mk with

INTEGER_LIBRARY = integer-simple

I also used

BuildFlavour = quick

We need config.sub and config.guess, that accept accept out target:

cp -av /usr/share/misc/config.sub ./
cp -av /usr/share/misc/config.guess ./

Configure ghc (for now unregistered, if we do not do this the compiled haskell programs will segfault):

perl boot
./configure --target=arm-linux-androideabi --enable-unregisterised

and compile:

make

This will fail with:

configure: error: /bin/bash ./config.sub arm-unknown-linux-android failed

so go do

cd libraries/unix
cp -av /usr/share/misc/config.sub ./
cp -av /usr/share/misc/config.guess ./

again, this will fail with

expectJust initTcInteractive

there is an easy fix. Type make again (it is a known problem)!
But this will fail again with something like this:

Not in scope: type constructor or class `HTYPE_FLOAT'

So do

<edit> ./libraries/base/include/HsBaseConfig.h

now replace

/* Define to Haskell type for double */
/* #undef HTYPE_DOUBLE */

/* Define to Haskell type for float */
/* #undef HTYPE_FLOAT */

with

/* Define to Haskell type for double */
#define HTYPE_DOUBLE Double

/* Define to Haskell type for float */
#define HTYPE_FLOAT Float

and do make again.
24 changes: 24 additions & 0 deletions android_ghc/patches/add-terminfo.patch
@@ -0,0 +1,24 @@
From c075607aa2e0905c48dcb90b87b6a88adaa67bde Mon Sep 17 00:00:00 2001
From: Nathan <nathan.huesken@posteo.de>
Date: Sun, 13 Jan 2013 14:57:09 +0100
Subject: [PATCH] add terminfo

---
haskeline.cabal | 1 +
1 file changed, 1 insertion(+)

diff --git a/haskeline.cabal b/haskeline.cabal
index 2665ae8..7f049a5 100644
--- a/haskeline.cabal
+++ b/haskeline.cabal
@@ -114,6 +114,7 @@ Library
Build-depends: unix>=2.0 && < 2.7
-- unix-2.3 doesn't build on ghc-6.8.1 or earlier
-- Use manual encoding/decoding on ghc<7.4
+ cpp-options: -DUSE_TERMIOS_H
if flag (legacy-encoding) || impl(ghc<7.4) {
c-sources: cbits/h_iconv.c
includes: h_iconv.h
--
1.7.10.4

25 changes: 25 additions & 0 deletions android_ghc/patches/mtriple.patch
@@ -0,0 +1,25 @@
From 1cf3e56529f638c03c7ef3671dd85e030ad87c87 Mon Sep 17 00:00:00 2001
From: Nathan <nathan.huesken@posteo.de>
Date: Sun, 13 Jan 2013 15:43:13 +0100
Subject: [PATCH] llvm mtriple for android

---
compiler/llvmGen/LlvmCodeGen/Ppr.hs | 2 ++
1 file changed, 2 insertions(+)

diff --git a/compiler/llvmGen/LlvmCodeGen/Ppr.hs b/compiler/llvmGen/LlvmCodeGen/Ppr.hs
index 218870a..31b75ae 100644
--- a/compiler/llvmGen/LlvmCodeGen/Ppr.hs
+++ b/compiler/llvmGen/LlvmCodeGen/Ppr.hs
@@ -58,6 +58,8 @@ moduleLayout = sdocWithPlatform $ \platform ->
Platform { platformArch = ArchARM {}, platformOS = OSLinux } ->
text "target datalayout = \"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:64-n32\""
$+$ text "target triple = \"arm-unknown-linux-gnueabi\""
+ Platform { platformArch = ArchARM {}, platformOS = OSAndroid } ->
+ text "target triple = \"arm-unknown-linux-androideabi\""
_ ->
-- FIX: Other targets
empty
--
1.7.10.4

51 changes: 51 additions & 0 deletions android_ghc/patches/offset.patch
@@ -0,0 +1,51 @@
From a6c750e564d0365f84df2caa657cbb1673339d8e Mon Sep 17 00:00:00 2001
From: Nathan <nathan.huesken@posteo.de>
Date: Sun, 13 Jan 2013 13:31:54 +0100
Subject: [PATCH] on android offsetof cannot be used as constant (when
termios.h is included)

---
CrossCodegen.hs | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/CrossCodegen.hs b/CrossCodegen.hs
index 7fbd20a..af44e64 100644
--- a/CrossCodegen.hs
+++ b/CrossCodegen.hs
@@ -208,13 +208,13 @@ outputSpecial :: (String -> TestMonad ()) -> ZCursor Token -> TestMonad ()
outputSpecial output (z@ZCursor {zCursor=Special pos@(SourcePos file line) key value}) =
case key of
"const" -> outputConst value show
- "offset" -> outputConst ("offsetof(" ++ value ++ ")") (\i -> "(" ++ show i ++ ")")
+ "offset" -> outputConst ("__builtin_offsetof(" ++ value ++ ")") (\i -> "(" ++ show i ++ ")")
"size" -> outputConst ("sizeof(" ++ value ++ ")") (\i -> "(" ++ show i ++ ")")
- "peek" -> outputConst ("offsetof(" ++ value ++ ")")
+ "peek" -> outputConst ("__builtin_offsetof(" ++ value ++ ")")
(\i -> "(\\hsc_ptr -> peekByteOff hsc_ptr " ++ show i ++ ")")
- "poke" -> outputConst ("offsetof(" ++ value ++ ")")
+ "poke" -> outputConst ("__builtin_offsetof(" ++ value ++ ")")
(\i -> "(\\hsc_ptr -> pokeByteOff hsc_ptr " ++ show i ++ ")")
- "ptr" -> outputConst ("offsetof(" ++ value ++ ")")
+ "ptr" -> outputConst ("__builtin_offsetof(" ++ value ++ ")")
(\i -> "(\\hsc_ptr -> hsc_ptr `plusPtr` " ++ show i ++ ")")
"type" -> computeType z >>= output
"enum" -> computeEnum z >>= output
@@ -272,11 +272,11 @@ outValidityCheck :: Token -> Int -> String
outValidityCheck s@(Special pos key value) uniq =
case key of
"const" -> checkValidConst value
- "offset" -> checkValidConst ("offsetof(" ++ value ++ ")")
+ "offset" -> checkValidConst ("__builtin_offsetof(" ++ value ++ ")")
"size" -> checkValidConst ("sizeof(" ++ value ++ ")")
- "peek" -> checkValidConst ("offsetof(" ++ value ++ ")")
- "poke" -> checkValidConst ("offsetof(" ++ value ++ ")")
- "ptr" -> checkValidConst ("offsetof(" ++ value ++ ")")
+ "peek" -> checkValidConst ("__builtin_offsetof(" ++ value ++ ")")
+ "poke" -> checkValidConst ("__builtin_offsetof(" ++ value ++ ")")
+ "ptr" -> checkValidConst ("__builtin_offsetof(" ++ value ++ ")")
"type" -> checkValidType
"enum" -> checkValidEnum
_ -> outHeaderCProg' s
--
1.7.10.4

112 changes: 112 additions & 0 deletions android_ghc/patches/unix-posix.patch
@@ -0,0 +1,112 @@
From b1d4a299ec9aa6f42f0df740f2fd41107d935934 Mon Sep 17 00:00:00 2001
From: Nathan <nathan.huesken@posteo.de>
Date: Sun, 13 Jan 2013 15:49:30 +0100
Subject: [PATCH] Changes in unix because of difference in android ndk headers

---
System/Posix/Directory.hsc | 2 --
System/Posix/Directory/ByteString.hsc | 2 --
System/Posix/Directory/Common.hsc | 17 -----------------
System/Posix/Terminal/Common.hsc | 4 ++--
System/Posix/User.hsc | 2 +-
5 files changed, 3 insertions(+), 24 deletions(-)

diff --git a/System/Posix/Directory.hsc b/System/Posix/Directory.hsc
index 71a70ce..814b987 100644
--- a/System/Posix/Directory.hsc
+++ b/System/Posix/Directory.hsc
@@ -29,8 +29,6 @@ module System.Posix.Directory (
rewindDirStream,
closeDirStream,
DirStreamOffset,
- tellDirStream,
- seekDirStream,

-- * The working dirctory
getWorkingDirectory,
diff --git a/System/Posix/Directory/ByteString.hsc b/System/Posix/Directory/ByteString.hsc
index 3ac642b..96f0620 100644
--- a/System/Posix/Directory/ByteString.hsc
+++ b/System/Posix/Directory/ByteString.hsc
@@ -29,8 +29,6 @@ module System.Posix.Directory.ByteString (
rewindDirStream,
closeDirStream,
DirStreamOffset,
- tellDirStream,
- seekDirStream,

-- * The working dirctory
getWorkingDirectory,
diff --git a/System/Posix/Directory/Common.hsc b/System/Posix/Directory/Common.hsc
index a608be3..2de0b21 100644
--- a/System/Posix/Directory/Common.hsc
+++ b/System/Posix/Directory/Common.hsc
@@ -22,8 +22,6 @@ module System.Posix.Directory.Common (
DirStream(..), CDir, CDirent, DirStreamOffset(..),
rewindDirStream,
closeDirStream,
- seekDirStream,
- tellDirStream,
changeWorkingDirectoryFd,
) where

@@ -57,21 +55,6 @@ foreign import ccall unsafe "closedir"

newtype DirStreamOffset = DirStreamOffset COff

-seekDirStream :: DirStream -> DirStreamOffset -> IO ()
-seekDirStream (DirStream dirp) (DirStreamOffset off) =
- c_seekdir dirp off
-
-foreign import ccall unsafe "seekdir"
- c_seekdir :: Ptr CDir -> COff -> IO ()
-
-tellDirStream :: DirStream -> IO DirStreamOffset
-tellDirStream (DirStream dirp) = do
- off <- c_telldir dirp
- return (DirStreamOffset off)
-
-foreign import ccall unsafe "telldir"
- c_telldir :: Ptr CDir -> IO COff
-
changeWorkingDirectoryFd :: Fd -> IO ()
changeWorkingDirectoryFd (Fd fd) =
throwErrnoIfMinus1Retry_ "changeWorkingDirectoryFd" (c_fchdir fd)
diff --git a/System/Posix/Terminal/Common.hsc b/System/Posix/Terminal/Common.hsc
index 5d718a8..9d077bf 100644
--- a/System/Posix/Terminal/Common.hsc
+++ b/System/Posix/Terminal/Common.hsc
@@ -272,7 +272,7 @@ controlChar termios cc = unsafePerformIO $ do
withTerminalAttributes termios $ \p -> do
let c_cc = (#ptr struct termios, c_cc) p
val <- peekElemOff c_cc (cc2Word cc)
- if val == ((#const _POSIX_VDISABLE)::CCc)
+ if val == ((#const '\0')::CCc)
then return Nothing
else return (Just (chr (fromEnum val)))

@@ -290,7 +290,7 @@ withoutCC :: TerminalAttributes
withoutCC termios cc = unsafePerformIO $ do
withNewTermios termios $ \p -> do
let c_cc = (#ptr struct termios, c_cc) p
- pokeElemOff c_cc (cc2Word cc) ((#const _POSIX_VDISABLE) :: CCc)
+ pokeElemOff c_cc (cc2Word cc) ((#const '\0') :: CCc)

inputTime :: TerminalAttributes -> Int
inputTime termios = unsafePerformIO $ do
diff --git a/System/Posix/User.hsc b/System/Posix/User.hsc
index a62648d..9887c97 100644
--- a/System/Posix/User.hsc
+++ b/System/Posix/User.hsc
@@ -453,7 +453,7 @@ unpackUserEntry ptr = do
passwd <- (#peek struct passwd, pw_passwd) ptr >>= peekCAString
uid <- (#peek struct passwd, pw_uid) ptr
gid <- (#peek struct passwd, pw_gid) ptr
- gecos <- (#peek struct passwd, pw_gecos) ptr >>= peekCAString
+ gecos <- (#peek struct passwd, pw_name) ptr >>= peekCAString
dir <- (#peek struct passwd, pw_dir) ptr >>= peekCAString
shell <- (#peek struct passwd, pw_shell) ptr >>= peekCAString
return (UserEntry name passwd uid gid gecos dir shell)
--
1.7.10.4

0 comments on commit 7b2dea2

Please sign in to comment.