Project

General

Profile

Actions

Installing Wt on Android

Warning: Installation of Wt on Android is a bit more complex than it should be. The dependencies (NDK, boost) don't support this platform perfectly, and thus you must be prepared to patch these if you encounter problems. This page describes how I made my first Wt on Android build.

Installing the Cross Compilation Tools

At the time of writing, Google's NDK C support is insufficient to compile boost or Wt. Use the crystax NDK, a fork of the official Google NDK, instead. Download the prebuilt tools for your platform and install them somewhere.

Cross Compiling Boost for Android

I used boost 1.44.0. Download and unpack it somewhere.

Run the bootstrap script to compile bjam. http://kupitchasi24.ru

Edit the boost_1_44_0/project-config.jam file to add some defaults. I made the following changes:

# Python configuration
#using python : 2.6 : /usr ;

libraries = --with-date_time --with-filesystem --with-program_options --with-regex --with-signals --with-system --with-thread ; 

# These settings are equivivalent to corresponding command-line
# options.
option.set prefix : /home/wim/project/android/boost ;
option.set exec-prefix : /home/wim/project/android/boost ;
option.set libdir : /home/wim/project/android/boost/lib ;
option.set includedir : /home/wim/project/android/boost/include ;

In boost_1_44_0/tools/build/v2/user-config.jam, add the following lines (modify paths to your NDK installation directory as needed):

using gcc : arm : /home/wim/project/android/android-ndk-r4-crystax/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-c++ :
<compileflags>-I/home/wim/project/android/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/include/
<compileflags>-fpic
<compileflags>-mthumb-interwork
<compileflags>-ffunction-sections
<compileflags>-funwind-tables
<compileflags>-fstack-protector
<compileflags>-fno-short-enums
<compileflags>-D__ARM_ARCH_5__
<compileflags>-D__ARM_ARCH_5T__
<compileflags>-D__ARM_ARCH_5E__
<compileflags>-D__ARM_ARCH_5TE__
<compileflags>-Wno-psabi
<compileflags>-march=armv5te
<compileflags>-mtune=xscale
<compileflags>-msoft-float
<compileflags>-mthumb
<compileflags>-Os
<compileflags>-fomit-frame-pointer
<compileflags>-fno-strict-aliasing
<compileflags>-finline-limit=64
<compileflags>-DANDROID
<compileflags>-D__ANDROID__
<compileflags>-Wa,--noexecstack
# 'official' android flags stop here
<architecture>arm
<compileflags>-fvisibility=hidden
<compileflags>-fvisibility-inlines-hidden
<compileflags>-fdata-sections
<cxxflags>-DBOOST_THREAD_LINUX
<cxxflags>-DBOOST_HAS_PTHREADS
<cxxflags>-D__arm__
<cxxflags>-D_REENTRANT
<cxxflags>-D_GLIBCXX__PTHREADS
<cxxflags>-DBOOST_HAS_GETTIMEOFDAY
;

You'll need to patch boost. This is a diff of my patched boost against an original one:

diff -ru orig/boost_1_44_0/boost/asio/detail/fenced_block.hpp boost_1_44_0/boost/asio/detail/fenced_block.hpp
--- orig/boost_1_44_0/boost/asio/detail/fenced_block.hpp    2010-07-12 01:42:34.000000000 +0200
+++ boost_1_44_0/boost/asio/detail/fenced_block.hpp 2010-09-02 10:43:21.000000000 +0200
@@ -25,14 +25,14 @@
 # include <boost/asio/detail/macos_fenced_block.hpp>
 #elif defined(__sun)
 # include <boost/asio/detail/solaris_fenced_block.hpp>
-#elif defined(__GNUC__) && defined(__arm__)
+#elif defined(__GNUC__) && defined(__arm__) && !defined(__thumb__)
 # include <boost/asio/detail/gcc_arm_fenced_block.hpp>
 #elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))
 # include <boost/asio/detail/gcc_hppa_fenced_block.hpp>
 #elif defined(__GNUC__) \
   && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \
   && !defined(__INTEL_COMPILER) && !defined(__ICL) \
-  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)
+  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) && !defined(ANDROID)
 # include <boost/asio/detail/gcc_sync_fenced_block.hpp>
 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
 # include <boost/asio/detail/gcc_x86_fenced_block.hpp>
@@ -54,14 +54,14 @@
 typedef macos_fenced_block fenced_block;
 #elif defined(__sun)
 typedef solaris_fenced_block fenced_block;
-#elif defined(__GNUC__) && defined(__arm__)
+#elif defined(__GNUC__) && defined(__arm__) && !defined(__thumb__)
 typedef gcc_arm_fenced_block fenced_block;
 #elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))
 typedef gcc_hppa_fenced_block fenced_block;
 #elif defined(__GNUC__) \
   && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \
   && !defined(__INTEL_COMPILER) && !defined(__ICL) \
-  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)
+  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) && !defined(ANDROID)
 typedef gcc_sync_fenced_block fenced_block;
 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
 typedef gcc_x86_fenced_block fenced_block;
diff -ru orig/boost_1_44_0/boost/asio/detail/socket_types.hpp boost_1_44_0/boost/asio/detail/socket_types.hpp
--- orig/boost_1_44_0/boost/asio/detail/socket_types.hpp    2010-06-09 11:40:46.000000000 +0200
+++ boost_1_44_0/boost/asio/detail/socket_types.hpp 2010-09-01 19:10:27.000000000 +0200
@@ -121,7 +121,11 @@
 typedef int socket_type;
 const int invalid_socket = -1;
 const int socket_error_retval = -1;
+#ifdef INET_ADDRSTRLEN
 const int max_addr_v4_str_len = INET_ADDRSTRLEN;
+#else
+const int max_addr_v4_str_len = 16;
+#endif
 #if defined(INET6_ADDRSTRLEN)
 const int max_addr_v6_str_len = INET6_ADDRSTRLEN + 1 + IF_NAMESIZE;
 #else // defined(INET6_ADDRSTRLEN)
diff -ru orig/boost_1_44_0/boost/asio/ip/impl/address_v6.ipp boost_1_44_0/boost/asio/ip/impl/address_v6.ipp
--- orig/boost_1_44_0/boost/asio/ip/impl/address_v6.ipp 2010-06-09 11:40:46.000000000 +0200
+++ boost_1_44_0/boost/asio/ip/impl/address_v6.ipp  2010-09-01 19:10:27.000000000 +0200
@@ -11,6 +11,23 @@
 #ifndef BOOST_ASIO_IP_IMPL_ADDRESS_V6_IPP
 #define BOOST_ASIO_IP_IMPL_ADDRESS_V6_IPP

+#ifndef IN6_IS_ADDR_MULTICAST 
+#define IN6_IS_ADDR_MULTICAST(a) (((__const uint8_t *) (a))[0] == 0xff)
+#endif
+
+#ifndef IN6_IS_ADDR_MC_NODELOCAL
+#define IN6_IS_ADDR_MC_NODELOCAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a)                                             \
+         && ((((__const uint8_t *) (a))[1] & 0xf) == 0x1))
+#endif
+
+#ifndef IN6_IS_ADDR_MC_GLOBAL
+#define IN6_IS_ADDR_MC_GLOBAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a)                                             \
+         && ((((__const uint8_t *) (a))[1] & 0xf) == 0xe))
+#endif
+
+
 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
Only in boost_1_44_0/: bootstrap.log
diff -ru orig/boost_1_44_0/libs/filesystem/v2/src/v2_operations.cpp boost_1_44_0/libs/filesystem/v2/src/v2_operations.cpp
--- orig/boost_1_44_0/libs/filesystem/v2/src/v2_operations.cpp  2010-08-10 22:00:09.000000000 +0200
+++ boost_1_44_0/libs/filesystem/v2/src/v2_operations.cpp   2010-09-02 17:38:22.000000000 +0200
@@ -58,14 +58,16 @@

 # else // BOOST_POSIX_API
 #   include <sys/types.h>
-#   if !defined(__APPLE__) && !defined(__OpenBSD__)
+#   if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(ANDROID)
 #     include <sys/statvfs.h>
 #     define BOOST_STATVFS statvfs
 #     define BOOST_STATVFS_F_FRSIZE vfs.f_frsize
 #   else
-#ifdef __OpenBSD__
-#     include <sys/param.h>
-#endif
+#     ifdef __OpenBSD__
+#       include <sys/param.h>
+#     elif defined(ANDROID)
+#       include <sys/vfs.h>
+#     endif
 #     include <sys/mount.h>
 #     define BOOST_STATVFS statfs
 #     define BOOST_STATVFS_F_FRSIZE static_cast<boost::uintmax_t>( vfs.f_bsize )
@@ -1262,7 +1264,20 @@
         if ( max == 0 )
         {
           errno = 0;
+#ifdef ANDROID
+          long tmp = 4096; // is it?
+#if 0
+          {
+            int fd = open( "/", O_RDONLY );
+            if (fd >= 0) {
+              tmp = ::fpathconf( fd, _PC_NAME_MAX );
+              close(fd);
+            }
+          }
+#endif
+#else
           long tmp = ::pathconf( "/", _PC_NAME_MAX );
+#endif
           if ( tmp < 0 )
           {
             if ( errno == 0 ) // indeterminate
Only in boost_1_44_0/libs/filesystem/v2/src: v2_operations.cpp~
diff -ru orig/boost_1_44_0/libs/filesystem/v3/src/operations.cpp boost_1_44_0/libs/filesystem/v3/src/operations.cpp
--- orig/boost_1_44_0/libs/filesystem/v3/src/operations.cpp 2010-08-10 22:00:09.000000000 +0200
+++ boost_1_44_0/libs/filesystem/v3/src/operations.cpp  2010-09-01 19:10:27.000000000 +0200
@@ -66,13 +66,15 @@
 # ifdef BOOST_POSIX_API

 #   include <sys/types.h>
-#   if !defined(__APPLE__) && !defined(__OpenBSD__)
+#   if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(ANDROID)
 #     include <sys/statvfs.h>
 #     define BOOST_STATVFS statvfs
 #     define BOOST_STATVFS_F_FRSIZE vfs.f_frsize
 #   else
 #     ifdef __OpenBSD__
 #     include <sys/param.h>
+#     elif defined(ANDROID)
+#       include <sys/vfs.h>
 #     endif
 #     include <sys/mount.h>
 #     define BOOST_STATVFS statfs
@@ -193,7 +195,19 @@
          || ::mkdir(to.c_str(),from_stat.st_mode)!= 0))
 #   define BOOST_COPY_FILE(F,T,FailIfExistsBool)copy_file_api(F, T, FailIfExistsBool)
 #   define BOOST_MOVE_FILE(OLD,NEW)(::rename(OLD, NEW)== 0)
+#ifndef ANDROID
 #   define BOOST_RESIZE_FILE(P,SZ)(::truncate(P, SZ)== 0)
+#else
+int BOOST_RESIZE_FILE(const char *path, off_t size)
+{
+  int retval = -1;
+  int fd = open(path, O_WRONLY);
+  if (fd != -1)
+    retval = ftruncate(fd, size);
+  close(fd);
+  return retval;
+}
+#endif

 #   define BOOST_ERROR_NOT_SUPPORTED ENOSYS
 #   define BOOST_ERROR_ALREADY_EXISTS EEXIST
diff -ru orig/boost_1_44_0/tools/build/v2/tools/gcc.jam boost_1_44_0/tools/build/v2/tools/gcc.jam
--- orig/boost_1_44_0/tools/build/v2/tools/gcc.jam  2010-04-20 14:05:14.000000000 +0200
+++ boost_1_44_0/tools/build/v2/tools/gcc.jam   2010-09-01 16:37:36.000000000 +0200
@@ -935,8 +935,8 @@
             }
             case * :
             {
-                option = -pthread ;
-                libs = rt ;
+#                option = -pthread ;
+#                libs = rt ;
             }
         }

diff -ru orig/boost_1_44_0/tools/build/v2/tools/gcc.py boost_1_44_0/tools/build/v2/tools/gcc.py
--- orig/boost_1_44_0/tools/build/v2/tools/gcc.py   2009-10-28 08:47:51.000000000 +0100
+++ boost_1_44_0/tools/build/v2/tools/gcc.py    2010-09-01 16:36:22.000000000 +0200
@@ -672,12 +672,14 @@
         # BeOS has no threading options, don't set anything here.
         pass
     elif host_os_name.endswith('BSD'):
-        flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
+        #flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
         # there is no -lrt on BSD
+        pass
     elif host_os_name == 'DragonFly':
-        flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
+        #flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
         # there is no -lrt on BSD - DragonFly is a FreeBSD variant,
         # which anoyingly doesn't say it's a *BSD.
+        pass
     elif host_os_name == 'IRIX':
         # gcc on IRIX does not support multi-threading, don't set anything here.
         pass
@@ -685,8 +687,9 @@
         # Darwin has no threading options, don't set anything here.
         pass
     else:
-        flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
-        flags('gcc', 'FINDLIBS-SA', [], ['rt'])
+        #flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
+        #flags('gcc', 'FINDLIBS-SA', [], ['rt'])
+        pass

 def cpu_flags(toolset, variable, architecture, instruction_set, values, default=None):
     #FIXME: for some reason this fails.  Probably out of date feature code

Now invoke bjam, and you should have a nice boost installation in the path that you specified in project-config.jam.

./bjam link=static threading=multi --layout=versioned install

Preparing Cmake for Cross Compilation to Android

Create a toolchain file. Call it ~/toolchain-android.cmake

SET(ANDROID_DIR /home/wim/project/android/)
SET(ANDROID_NDK_DIR ${ANDROID_DIR}/android-ndk-r4-crystax/)
SET(STAGING_DIR ${ANDROID_NDK_DIR}/build/prebuilt/linux-x86/arm-eabi-4.4.0/)
SET(TARGET_CC ${STAGING_DIR}/bin/arm-eabi-gcc)
SET(TARGET_CXX ${STAGING_DIR}/bin/arm-eabi-c++)

SET(CMAKE_SYSTEM_NAME Android)
SET(CMAKE_SYSTEM_VERSION 1)

SET(CMAKE_SYSTEM_PROCESSOR arm-elf)
SET(CMAKE_C_COMPILER ${TARGET_CC})
SET(CMAKE_CXX_COMPILER ${TARGET_CXX})

SET(CMAKE_FIND_ROOT_PATH  ${ANDROID_DIR})

# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

Create a platform file. Put it in a file called cmake/Platform/Android.cmake

SET(ANDROID true)
SET(ANDROID_OPTION_LIST
    -I/home/wim/project/android/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/include
    -fpic
    -mthumb-interwork
    -ffunction-sections
    -funwind-tables
    -fstack-protector
    -fno-short-enums
    -D__ARM_ARCH_5__
    -D__ARM_ARCH_5T__
    -D__ARM_ARCH_5E__
    -D__ARM_ARCH_5TE__
    -Wno-psabi
    -march=armv5te
    -mtune=xscale
    -msoft-float
    -mthumb
    -Os
    -fomit-frame-pointer
    -fno-strict-aliasing
    -finline-limit=64
    -DANDROID
    -Wa,--noexecstack
#more options
    -fvisibility=hidden
    -fvisibility-inlines-hidden
    -fdata-sections
    -DBOOST_THREAD_LINUX
    -DBOOST_HAS_PTHREADS
    -D_REENTRANT
    -D_GLIBCXX__PTHREADS
    -DANDROID
    -D__ANDROID__
    -DBOOST_HAS_GETTIMEOFDAY
    -DSQLITE_OMIT_LOAD_EXTENSION
)

foreach(arg ${ANDROID_OPTION_LIST})
  set(ANDROID_COMPILE_FLAGS "${ANDROID_COMPILE_FLAGS} ${arg}")
endforeach(arg ${ANDROID_OPTION_LIST})


SET(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER>  <DEFINES> <FLAGS> ${ANDROID_COMPILE_FLAGS} -o <OBJECT> -c <SOURCE>")
SET(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER>  <DEFINES> <FLAGS> ${ANDROID_COMPILE_FLAGS} -o <OBJECT> -c <SOURCE>")

SET(ANDROID_NDK_PREFIX "/home/wim/project/android/android-ndk-r4-crystax/")
SET(ANDROID_LINK_EXE_FLAGS
    "-nostdlib -Bdynamic -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,nocopyreloc"
    )
SET(ANDROID_CRT_PRE
    "${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib/crtbegin_dynamic.o"
   )
SET(ANDROID_CRT_POST_LIST
    "${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib/libmissing.a"
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a"
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a"
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a"
    "${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib/libc.so"
    "${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib/libm.so"
    "-Wl,--no-undefined"
    "-Wl,-z,noexecstack"
    "-L${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib"
    "-llog"
    "-Wl,-rpath-link=${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib"
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a"
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a"
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a"
    "${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib/crtend_android.o"
   )
foreach(arg ${ANDROID_CRT_POST_LIST})
  set(ANDROID_CRT_POST "${ANDROID_CRT_POST} ${arg}")
endforeach(arg ${ANDROID_CRT_POST_LIST})
SET(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_C_COMPILER>  ${ANDROID_LINK_EXE_FLAGS} <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> ${ANDROID_CRT_PRE} <OBJECTS>  -o <TARGET> <LINK_LIBRARIES> ${ANDROID_CRT_POST}")
SET(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER>  ${ANDROID_LINK_EXE_FLAGS} <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> ${ANDROID_CRT_PRE} <OBJECTS>  -o <TARGET> <LINK_LIBRARIES> ${ANDROID_CRT_POST}")

SET(ANDROID_LINK_SHARED_FLAGS
    "-nostdlib -Wl,-soname,<TARGET> -Wl,-shared,-Bsymbolic"
    )
SET(ANDROID_LINK_SHARED_LIBS_LIST
    "-Wl,--whole-archive"
    "-Wl,--no-whole-archive"
    "${ANDROID_NDK_PREFIX}/build/platforms/android-8/arch-arm/usr/lib/libmissing.a"
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a"
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a"
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a"
    "${ANDROID_NDK_PREFIX}/build/platforms/android-8/arch-arm/usr/lib/libc.so"
    "${ANDROID_NDK_PREFIX}/build/platforms/android-8/arch-arm/usr/lib/libm.so"
    "-Wl,--no-undefined"
    "-Wl,-z,noexecstack"
    "-Wl,-rpath-link=${ANDROID_NDK_PREFIX}/build/platforms/android-8/arch-arm/usr/lib"
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a"
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a"
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a"
   )
foreach(arg ${ANDROID_LINK_SHARED_LIBS_LIST})
  set(ANDROID_LINK_SHARED_LIBS "${ANDROID_LINK_SHARED_LIBS} ${arg}")
endforeach(arg ${ANDROID_LINK_SHARED_LIBS_LIST})
SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
    "<CMAKE_C_COMPILER> ${ANDROID_LINK_SHARED_FLAGS} <CMAKE_SHARED_LIBRARY_CXX_FLAGS><LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES> ${ANDROID_LINK_SHARED_LIBS}"
    )

Disclaimer: I'm not a specialist in writing platform files, I was looking for something that works. With this platform file, you can build both executables and shared objects (and .a files of course).

Cross Build Wt

Adjust paths as necessary. The CMAKE_MODULE_PATH is the directory where you put your Android platform file.

mkdir wt-build
cd wt-build
cmake -DCMAKE_TOOLCHAIN_FILE=~/toolchain-android.cmake -DBOOST_PREFIX=~/project/android/boost/ -DBOOST_VERSION=1_44 -DBOOST_COMPILER=gcc -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MODULE_PATH=/home/wim/project/android/cmake -DSHARED_LIBS=OFF ~/project/android/wt

Android doesn't have libdl, so omit it while compiling the sqlite3 backend:

diff --git a/src/Wt/Dbo/backend/CMakeLists.txt b/src/Wt/Dbo/backend/CMakeLists.txt
index f268223..a915db2 100644
--- a/src/Wt/Dbo/backend/CMakeLists.txt
+++ b/src/Wt/Dbo/backend/CMakeLists.txt
@@ -16,7 +16,7 @@ MESSAGE("** Wt::Dbo: building SQLite3 backend.")
 TARGET_LINK_LIBRARIES(wtdbosqlite3 wtdbo ${SQLITE3_LIBRARIES} ${BOOST_WT_DT_LIB})

 IF(NOT WIN32)
-  TARGET_LINK_LIBRARIES(wtdbosqlite3 dl)
+  TARGET_LINK_LIBRARIES(wtdbosqlite3)
 ENDIF(NOT WIN32)

 INSTALL(TARGETS wtdbosqlite3

Now compile Wt:

make -j 8
cd examples
make -j 8 -k

Examples that use crypt will fail to build.

Deploying and running Wt on Android

Log in on your android device and make a temporary directory:

$ adb shell
# mkdir /data/tmp
# cd /data/tmp

Copy your executable (and all dependency files, such as the resources directory, if necessary) to the temporary directory:

$ adb shell push hello.wt /data/tmp/hello.wt

Run the executable:

$ adb shell
# cd /data/tmp
# chmod 755 hello.wt
# ./hello.wt --docroot=. --http-address=0.0.0.0 --http-port=8080

Set up port forwarding so that you can surf to your emulator:

$ telnet localhost 5554
Android Console: type 'help' for a list of commands
OK
redir add tcp:8080:8080

Point your browser to http://localhost:8080/ and enjoy your Wt application!

Updated by Checheta Yan almost 5 years ago ยท 4 revisions