Skip to content

Commit

Permalink
Add android build on CircleCI 2.0.
Browse files Browse the repository at this point in the history
  • Loading branch information
iphydf committed Jun 11, 2017
1 parent 7a416de commit d905a20
Show file tree
Hide file tree
Showing 17 changed files with 355 additions and 13 deletions.
74 changes: 74 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
version: 2

jobs:
build:
working_directory: ~/work
docker:
- image: circleci/python:latest

steps:
- checkout
- run: .circleci/launch-job aarch64
- run: .circleci/launch-job arm
- run: .circleci/launch-job i686
- run: .circleci/launch-job x86_64

# aarch64-linux-android-4.9
aarch64:
working_directory: ~/work
docker:
- image: toktoknet/ghc-android:latest.aarch64

steps:
- checkout
- restore_cache:
key: v1-cabal-cache-aarch64
- run: android/build.sh
- save_cache:
key: v1-cabal-cache-aarch64
paths: [~/.ghc/android-21/aarch64-linux-android-4.9]

# arm-linux-androideabi-4.9
arm:
working_directory: ~/work
docker:
- image: toktoknet/ghc-android:latest.arm

steps:
- checkout
- restore_cache:
key: v1-cabal-cache-arm
- run: android/build.sh
- save_cache:
key: v1-cabal-cache-arm
paths: [~/.ghc/android-9/arm-linux-androideabi-4.9]

# x86-4.9
i686:
working_directory: ~/work
docker:
- image: toktoknet/ghc-android:latest.i686

steps:
- checkout
- restore_cache:
key: v1-cabal-cache-i686
- run: android/build.sh
- save_cache:
key: v1-cabal-cache-i686
paths: [~/.ghc/android-9/x86-4.9]

# x86_64-4.9
x86_64:
working_directory: ~/work
docker:
- image: toktoknet/ghc-android:latest.x86_64

steps:
- checkout
- restore_cache:
key: v1-cabal-cache-x86_64
- run: android/build.sh
- save_cache:
key: v1-cabal-cache-x86_64
paths: [~/.ghc/android-21/x86_64-4.9]
6 changes: 6 additions & 0 deletions .circleci/launch-job
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

curl --user ${CIRCLE_API_TOKEN}: \
--data build_parameters[CIRCLE_JOB]=$1 \
--data revision=$CIRCLE_SHA1 \
https://circleci.com/api/v1.1/project/github/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/tree/$CIRCLE_BRANCH
5 changes: 0 additions & 5 deletions .travis/android-install

This file was deleted.

4 changes: 0 additions & 4 deletions .travis/android-script

This file was deleted.

20 changes: 20 additions & 0 deletions android/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash

set -exu

export SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

$NDK_TARGET-cabal update

$SCRIPT_DIR/user-scripts/cabal-install-clock.sh
$SCRIPT_DIR/user-scripts/cabal-install-network.sh
$SCRIPT_DIR/user-scripts/cabal-install-setup.sh distributive 0.5.0.2
$SCRIPT_DIR/user-scripts/cabal-install-setup.sh comonad 5
$SCRIPT_DIR/user-scripts/cabal-install-setup.sh entropy 0.3.7
$SCRIPT_DIR/user-scripts/cabal-install-zlib.sh
$SCRIPT_DIR/user-scripts/install-happy.sh
$SCRIPT_DIR/user-scripts/install-hspec.sh
$SCRIPT_DIR/user-scripts/install-libsodium.sh

$NDK_TARGET-cabal install --enable-tests --enable-benchmarks --only-dependencies
$NDK_TARGET-cabal install -flibrary-only
21 changes: 21 additions & 0 deletions android/patches/hs-clock-ffi.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
diff -u -r a/System/Clock.hsc b/System/Clock.hsc
--- a/System/Clock.hsc 2016-04-20 02:14:45.000000000 +0100
+++ b/System/Clock.hsc 2017-06-09 12:15:31.229226983 +0100
@@ -41,8 +41,6 @@
# endif
#endif

-#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)
-
-- | Clock types. A clock may be system-wide (that is, visible to all processes)
-- or per-process (measuring time that is meaningful only within a process).
-- All implementations shall support CLOCK_REALTIME. (The only suspend-aware
@@ -216,7 +214,7 @@
#else
instance Storable TimeSpec where
sizeOf _ = #{size struct timespec}
- alignment _ = #{alignment struct timespec}
+ alignment _ = #{const __alignof__(struct timespec)}
poke ptr ts = do
let xs :: #{type time_t} = fromIntegral $ sec ts
xn :: #{type long} = fromIntegral $ nsec ts
12 changes: 12 additions & 0 deletions android/patches/hs-network-ffi.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
diff -u -r a/Network/Socket/Types.hsc b/Network/Socket/Types.hsc
--- a/Network/Socket/Types.hsc 2017-05-30 20:10:33.000000000 +0000
+++ b/Network/Socket/Types.hsc 2017-06-10 16:34:51.782365107 +0000
@@ -1085,7 +1085,7 @@

instance Storable In6Addr where
sizeOf _ = #const sizeof(struct in6_addr)
- alignment _ = #alignment struct in6_addr
+ alignment _ = #const __alignof__(struct in6_addr)

peek p = do
a <- peek32 p 0
67 changes: 67 additions & 0 deletions android/patches/hs-zlib-ffi.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
diff -ru a/Codec/Compression/Zlib/Stream.hsc b/Codec/Compression/Zlib/Stream.hsc
--- a/Codec/Compression/Zlib/Stream.hsc 2015-05-16 15:12:10.000000000 +0200
+++ b/Codec/Compression/Zlib/Stream.hsc 2016-07-04 22:25:40.933314724 +0200
@@ -2,6 +2,9 @@
#if __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE DeriveGeneric #-}
#endif
+#if __GLASGOW_HASKELL__ >= 706
+{-# LANGUAGE CApiFFI #-}
+#endif
-----------------------------------------------------------------------------
-- |
-- Copyright : (c) 2006-2015 Duncan Coutts
@@ -1007,7 +1010,19 @@
--
-- So we define c_inflateInit2 and c_deflateInit2 here as wrappers around
-- their _ counterparts and pass the extra args.
-
+--
+-- As of GHC 7.6, we can import macros directly using the CApiFFI extension.
+-- This avoids the need for the hsc2hs #{const_str} construct, which means
+-- hsc2hs can run in cross-compilation mode.
+
+#if __GLASGOW_HASKELL__ >= 706
+foreign import capi unsafe "zlib.h inflateInit2"
+ c_inflateInit2 :: StreamState -> CInt -> IO CInt
+
+foreign import capi unsafe "zlib.h deflateInit2"
+ c_deflateInit2 :: StreamState
+ -> CInt -> CInt -> CInt -> CInt -> CInt -> IO CInt
+#else
foreign import ccall unsafe "zlib.h inflateInit2_"
c_inflateInit2_ :: StreamState -> CInt -> Ptr CChar -> CInt -> IO CInt

@@ -1016,15 +1031,6 @@
withCAString #{const_str ZLIB_VERSION} $ \versionStr ->
c_inflateInit2_ z n versionStr (#{const sizeof(z_stream)} :: CInt)

-foreign import ccall unsafe "zlib.h inflate"
- c_inflate :: StreamState -> CInt -> IO CInt
-
-foreign import ccall unsafe "zlib.h &inflateEnd"
- c_inflateEnd :: FinalizerPtr StreamState
-
-foreign import ccall unsafe "zlib.h inflateReset"
- c_inflateReset :: StreamState -> IO CInt
-
foreign import ccall unsafe "zlib.h deflateInit2_"
c_deflateInit2_ :: StreamState
-> CInt -> CInt -> CInt -> CInt -> CInt
@@ -1036,6 +1042,16 @@
c_deflateInit2 z a b c d e =
withCAString #{const_str ZLIB_VERSION} $ \versionStr ->
c_deflateInit2_ z a b c d e versionStr (#{const sizeof(z_stream)} :: CInt)
+#endif
+
+foreign import ccall unsafe "zlib.h inflate"
+ c_inflate :: StreamState -> CInt -> IO CInt
+
+foreign import ccall unsafe "zlib.h &inflateEnd"
+ c_inflateEnd :: FinalizerPtr StreamState
+
+foreign import ccall unsafe "zlib.h inflateReset"
+ c_inflateReset :: StreamState -> IO CInt

foreign import ccall unsafe "zlib.h deflateSetDictionary"
c_deflateSetDictionary :: StreamState
21 changes: 21 additions & 0 deletions android/user-scripts/cabal-install-clock.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

export THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $HOME/ghc-build/set-env.sh
set -x
####################################################################################################

CLOCK_PACKAGE=$NDK/cabal/packages/hackage.haskell.org/clock/0.7.2/clock-0.7.2.tar.gz

if [ -f "$CLOCK_PACKAGE" ]; then
exit 0
fi

$NDK_TARGET-cabal fetch clock-0.7.2
tar zxf $CLOCK_PACKAGE
pushd clock-0.7.2
patch -p1 < $SCRIPT_DIR/patches/hs-clock-ffi.patch
$NDK_TARGET-cabal install
popd

rm -rf clock*
21 changes: 21 additions & 0 deletions android/user-scripts/cabal-install-network.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

export THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $HOME/ghc-build/set-env.sh
set -x
####################################################################################################

NETWORK_PACKAGE=$NDK/cabal/packages/hackage.haskell.org/network/2.6.3.2/network-2.6.3.2.tar.gz

if [ -f "$NETWORK_PACKAGE" ]; then
exit 0
fi

$NDK_TARGET-cabal fetch network-2.6.3.2
tar zxf $NETWORK_PACKAGE
pushd network-2.6.3.2
patch -p1 < $SCRIPT_DIR/patches/hs-network-ffi.patch
$NDK_TARGET-cabal install
popd

rm -rf network*
22 changes: 22 additions & 0 deletions android/user-scripts/cabal-install-setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash

export THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $HOME/ghc-build/set-env.sh
set -x
####################################################################################################

PACKAGE=$NDK/cabal/packages/hackage.haskell.org/$1/$2/$1-$2.tar.gz

if [ -f "$PACKAGE" ]; then
exit 0
fi

$NDK_TARGET-cabal fetch $1-$2
tar zxf $PACKAGE

pushd $1-$2
$HOME/.ghc/android-host/bin/cabal configure || true
$NDK_TARGET-cabal install
popd

rm -rf $1*
21 changes: 21 additions & 0 deletions android/user-scripts/cabal-install-zlib.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

export THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $HOME/ghc-build/set-env.sh
set -x
####################################################################################################

ZLIB_PACKAGE=$NDK/cabal/packages/hackage.haskell.org/zlib/0.6.1.1/zlib-0.6.1.1.tar.gz

if [ -f "$ZLIB_PACKAGE" ]; then
exit 0
fi

$NDK_TARGET-cabal fetch zlib-0.6.1.1
tar zxf $ZLIB_PACKAGE
pushd zlib-0.6.1.1
patch -p1 < $SCRIPT_DIR/patches/hs-zlib-ffi.patch
$NDK_TARGET-cabal install
popd

rm -rf zlib*
32 changes: 32 additions & 0 deletions android/user-scripts/install-happy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash

export THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $HOME/ghc-build/set-env.sh
set -x
####################################################################################################

if [ -f "$PLATFORM_PREFIX/.cabal/bin/happy" ]; then
exit 0
fi

#
# Terminology:
# build platform: The system platform we're building on. Build platform
# executables can be executed during build.
# host platform: The system platform we're building *for*. Host executables
# can run on the device we're building for, but can't run during build.
#
# We first install happy for the build platform, then for the host platform, and
# then we overwrite the host platform's happy with the build platform's happy.
#
# We do this because otherwise packages depending on happy will try to build a
# host happy and run it during build.
#
# We also use cabal-install-setup.sh to build happy for the host platform,
# because it uses a non-simple setup, so we need to first build the setup
# program for the build platform.
#

cabal install happy
$THIS_DIR/cabal-install-setup.sh happy 1.19.5
cp $HOME/.cabal/bin/happy $PLATFORM_PREFIX/.cabal/bin/
16 changes: 16 additions & 0 deletions android/user-scripts/install-hspec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash

export THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $HOME/ghc-build/set-env.sh
set -x
####################################################################################################

if [ -f "$PLATFORM_PREFIX/.cabal/bin/hspec-discover" ]; then
exit 0
fi

# See install-happy.sh for explanation for why we do this.

cabal install hspec-discover
$THIS_DIR/cabal-install-setup.sh hspec-discover 2.4.3
cp $HOME/.cabal/bin/hspec-discover $PLATFORM_PREFIX/.cabal/bin/
20 changes: 20 additions & 0 deletions android/user-scripts/install-libsodium.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash

source $HOME/ghc-build/set-env.sh
####################################################################################################

if [ -f "$NDK_ADDON_PREFIX/lib/libsodium.a" ]; then
exit 0
fi

cd $NDK_ADDON_SRC
apt-get source libsodium

pushd libsodium*
autoreconf -i
./configure --prefix="$NDK_ADDON_PREFIX" --host=$NDK_TARGET --build=$BUILD_ARCH --with-build-cc=$BUILD_GCC --enable-static --disable-shared
make $MAKEFLAGS
make install
popd

rm -rf libsodium*
4 changes: 1 addition & 3 deletions hstox.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ library
, lens-family
, MonadRandom
, mtl
-- network-2.6.2.1 is the last version that can be cross-compiled, so we install
-- it explicitly here.
, network <= 2.6.2.1
, network
, network-msgpack-rpc >= 0.0.3
, saltine
, random
Expand Down
2 changes: 1 addition & 1 deletion src/tox/Network/Tox/TimedT.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ newtype TimedT m a = TimedT (ReaderT Timestamp m a)
deriving (Monad, Applicative, Functor, MonadState s, MonadWriter w
, MonadRandomBytes, MonadTrans, MonadIO, Networked, Keyed)

runTimedT :: Monad m => TimedT m a -> Timestamp -> m a
runTimedT :: TimedT m a -> Timestamp -> m a
runTimedT (TimedT m) = runReaderT m

instance Monad m => Timed (TimedT m) where
Expand Down

0 comments on commit d905a20

Please sign in to comment.