Project

General

Profile

Installing Wt on Android » History » Version 3

Wim Dumon, 09/07/2010 04:41 PM

1 3 Wim Dumon
{{toc}}
2
3 1 Wim Dumon
h1. Installing Wt on Android
4
5
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.
6
7 3 Wim Dumon
h2. Installing the Cross Compilation Tools
8 1 Wim Dumon
9
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.
10
11 3 Wim Dumon
h2. Cross Compiling Boost for Android
12 1 Wim Dumon
13
I used boost 1.44.0. Download and unpack it somewhere.
14
15
Run the bootstrap script to compile bjam.
16
17
Edit the boost_1_44_0/project-config.jam file to add some defaults. I made the following changes:
18
<pre>
19
# Python configuration
20
#using python : 2.6 : /usr ;
21
22
libraries = --with-date_time --with-filesystem --with-program_options --with-regex --with-signals --with-system --with-thread ; 
23
24
# These settings are equivivalent to corresponding command-line
25
# options.
26
option.set prefix : /home/wim/project/android/boost ;
27
option.set exec-prefix : /home/wim/project/android/boost ;
28
option.set libdir : /home/wim/project/android/boost/lib ;
29
option.set includedir : /home/wim/project/android/boost/include ;
30
</pre>
31
32
In boost_1_44_0/tools/build/v2/user-config.jam, add the following lines (modify paths to your NDK installation directory as needed):
33
<pre>
34
using gcc : arm : /home/wim/project/android/android-ndk-r4-crystax/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-c++ :
35
<compileflags>-I/home/wim/project/android/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/include/
36
<compileflags>-fpic
37
<compileflags>-mthumb-interwork
38
<compileflags>-ffunction-sections
39
<compileflags>-funwind-tables
40
<compileflags>-fstack-protector
41
<compileflags>-fno-short-enums
42
<compileflags>-D__ARM_ARCH_5__
43
<compileflags>-D__ARM_ARCH_5T__
44
<compileflags>-D__ARM_ARCH_5E__
45
<compileflags>-D__ARM_ARCH_5TE__
46
<compileflags>-Wno-psabi
47
<compileflags>-march=armv5te
48
<compileflags>-mtune=xscale
49
<compileflags>-msoft-float
50
<compileflags>-mthumb
51
<compileflags>-Os
52
<compileflags>-fomit-frame-pointer
53
<compileflags>-fno-strict-aliasing
54
<compileflags>-finline-limit=64
55
<compileflags>-DANDROID
56
<compileflags>-D__ANDROID__
57
<compileflags>-Wa,--noexecstack
58
# 'official' android flags stop here
59
<architecture>arm
60
<compileflags>-fvisibility=hidden
61
<compileflags>-fvisibility-inlines-hidden
62
<compileflags>-fdata-sections
63
<cxxflags>-DBOOST_THREAD_LINUX
64
<cxxflags>-DBOOST_HAS_PTHREADS
65
<cxxflags>-D__arm__
66
<cxxflags>-D_REENTRANT
67
<cxxflags>-D_GLIBCXX__PTHREADS
68
<cxxflags>-DBOOST_HAS_GETTIMEOFDAY
69
;
70
71
</pre>
72
73
You'll need to patch boost. This is a diff of my patched boost against an original one:
74
<pre>
75
diff -ru orig/boost_1_44_0/boost/asio/detail/fenced_block.hpp boost_1_44_0/boost/asio/detail/fenced_block.hpp
76
--- orig/boost_1_44_0/boost/asio/detail/fenced_block.hpp	2010-07-12 01:42:34.000000000 +0200
77
+++ boost_1_44_0/boost/asio/detail/fenced_block.hpp	2010-09-02 10:43:21.000000000 +0200
78
@@ -25,14 +25,14 @@
79
 # include <boost/asio/detail/macos_fenced_block.hpp>
80
 #elif defined(__sun)
81
 # include <boost/asio/detail/solaris_fenced_block.hpp>
82
-#elif defined(__GNUC__) && defined(__arm__)
83
+#elif defined(__GNUC__) && defined(__arm__) && !defined(__thumb__)
84
 # include <boost/asio/detail/gcc_arm_fenced_block.hpp>
85
 #elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))
86
 # include <boost/asio/detail/gcc_hppa_fenced_block.hpp>
87
 #elif defined(__GNUC__) \
88
   && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \
89
   && !defined(__INTEL_COMPILER) && !defined(__ICL) \
90
-  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)
91
+  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) && !defined(ANDROID)
92
 # include <boost/asio/detail/gcc_sync_fenced_block.hpp>
93
 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
94
 # include <boost/asio/detail/gcc_x86_fenced_block.hpp>
95
@@ -54,14 +54,14 @@
96
 typedef macos_fenced_block fenced_block;
97
 #elif defined(__sun)
98
 typedef solaris_fenced_block fenced_block;
99
-#elif defined(__GNUC__) && defined(__arm__)
100
+#elif defined(__GNUC__) && defined(__arm__) && !defined(__thumb__)
101
 typedef gcc_arm_fenced_block fenced_block;
102
 #elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))
103
 typedef gcc_hppa_fenced_block fenced_block;
104
 #elif defined(__GNUC__) \
105
   && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \
106
   && !defined(__INTEL_COMPILER) && !defined(__ICL) \
107
-  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)
108
+  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) && !defined(ANDROID)
109
 typedef gcc_sync_fenced_block fenced_block;
110
 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
111
 typedef gcc_x86_fenced_block fenced_block;
112
diff -ru orig/boost_1_44_0/boost/asio/detail/socket_types.hpp boost_1_44_0/boost/asio/detail/socket_types.hpp
113
--- orig/boost_1_44_0/boost/asio/detail/socket_types.hpp	2010-06-09 11:40:46.000000000 +0200
114
+++ boost_1_44_0/boost/asio/detail/socket_types.hpp	2010-09-01 19:10:27.000000000 +0200
115
@@ -121,7 +121,11 @@
116
 typedef int socket_type;
117
 const int invalid_socket = -1;
118
 const int socket_error_retval = -1;
119
+#ifdef INET_ADDRSTRLEN
120
 const int max_addr_v4_str_len = INET_ADDRSTRLEN;
121
+#else
122
+const int max_addr_v4_str_len = 16;
123
+#endif
124
 #if defined(INET6_ADDRSTRLEN)
125
 const int max_addr_v6_str_len = INET6_ADDRSTRLEN + 1 + IF_NAMESIZE;
126
 #else // defined(INET6_ADDRSTRLEN)
127
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
128
--- orig/boost_1_44_0/boost/asio/ip/impl/address_v6.ipp	2010-06-09 11:40:46.000000000 +0200
129
+++ boost_1_44_0/boost/asio/ip/impl/address_v6.ipp	2010-09-01 19:10:27.000000000 +0200
130
@@ -11,6 +11,23 @@
131
 #ifndef BOOST_ASIO_IP_IMPL_ADDRESS_V6_IPP
132
 #define BOOST_ASIO_IP_IMPL_ADDRESS_V6_IPP
133
 
134
+#ifndef IN6_IS_ADDR_MULTICAST 
135
+#define IN6_IS_ADDR_MULTICAST(a) (((__const uint8_t *) (a))[0] == 0xff)
136
+#endif
137
+
138
+#ifndef IN6_IS_ADDR_MC_NODELOCAL
139
+#define IN6_IS_ADDR_MC_NODELOCAL(a) \
140
+        (IN6_IS_ADDR_MULTICAST(a)                                             \
141
+         && ((((__const uint8_t *) (a))[1] & 0xf) == 0x1))
142
+#endif
143
+
144
+#ifndef IN6_IS_ADDR_MC_GLOBAL
145
+#define IN6_IS_ADDR_MC_GLOBAL(a) \
146
+        (IN6_IS_ADDR_MULTICAST(a)                                             \
147
+         && ((((__const uint8_t *) (a))[1] & 0xf) == 0xe))
148
+#endif
149
+
150
+
151
 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
152
 # pragma once
153
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
154
Only in boost_1_44_0/: bootstrap.log
155
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
156
--- orig/boost_1_44_0/libs/filesystem/v2/src/v2_operations.cpp	2010-08-10 22:00:09.000000000 +0200
157
+++ boost_1_44_0/libs/filesystem/v2/src/v2_operations.cpp	2010-09-02 17:38:22.000000000 +0200
158
@@ -58,14 +58,16 @@
159
 
160
 # else // BOOST_POSIX_API
161
 #   include <sys/types.h>
162
-#   if !defined(__APPLE__) && !defined(__OpenBSD__)
163
+#   if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(ANDROID)
164
 #     include <sys/statvfs.h>
165
 #     define BOOST_STATVFS statvfs
166
 #     define BOOST_STATVFS_F_FRSIZE vfs.f_frsize
167
 #   else
168
-#ifdef __OpenBSD__
169
-#     include <sys/param.h>
170
-#endif
171
+#     ifdef __OpenBSD__
172
+#       include <sys/param.h>
173
+#     elif defined(ANDROID)
174
+#       include <sys/vfs.h>
175
+#     endif
176
 #     include <sys/mount.h>
177
 #     define BOOST_STATVFS statfs
178
 #     define BOOST_STATVFS_F_FRSIZE static_cast<boost::uintmax_t>( vfs.f_bsize )
179
@@ -1262,7 +1264,20 @@
180
         if ( max == 0 )
181
         {
182
           errno = 0;
183
+#ifdef ANDROID
184
+          long tmp = 4096; // is it?
185
+#if 0
186
+          {
187
+            int fd = open( "/", O_RDONLY );
188
+            if (fd >= 0) {
189
+              tmp = ::fpathconf( fd, _PC_NAME_MAX );
190
+              close(fd);
191
+            }
192
+          }
193
+#endif
194
+#else
195
           long tmp = ::pathconf( "/", _PC_NAME_MAX );
196
+#endif
197
           if ( tmp < 0 )
198
           {
199
             if ( errno == 0 ) // indeterminate
200
Only in boost_1_44_0/libs/filesystem/v2/src: v2_operations.cpp~
201
diff -ru orig/boost_1_44_0/libs/filesystem/v3/src/operations.cpp boost_1_44_0/libs/filesystem/v3/src/operations.cpp
202
--- orig/boost_1_44_0/libs/filesystem/v3/src/operations.cpp	2010-08-10 22:00:09.000000000 +0200
203
+++ boost_1_44_0/libs/filesystem/v3/src/operations.cpp	2010-09-01 19:10:27.000000000 +0200
204
@@ -66,13 +66,15 @@
205
 # ifdef BOOST_POSIX_API
206
 
207
 #   include <sys/types.h>
208
-#   if !defined(__APPLE__) && !defined(__OpenBSD__)
209
+#   if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(ANDROID)
210
 #     include <sys/statvfs.h>
211
 #     define BOOST_STATVFS statvfs
212
 #     define BOOST_STATVFS_F_FRSIZE vfs.f_frsize
213
 #   else
214
 #     ifdef __OpenBSD__
215
 #     include <sys/param.h>
216
+#     elif defined(ANDROID)
217
+#       include <sys/vfs.h>
218
 #     endif
219
 #     include <sys/mount.h>
220
 #     define BOOST_STATVFS statfs
221
@@ -193,7 +195,19 @@
222
          || ::mkdir(to.c_str(),from_stat.st_mode)!= 0))
223
 #   define BOOST_COPY_FILE(F,T,FailIfExistsBool)copy_file_api(F, T, FailIfExistsBool)
224
 #   define BOOST_MOVE_FILE(OLD,NEW)(::rename(OLD, NEW)== 0)
225
+#ifndef ANDROID
226
 #   define BOOST_RESIZE_FILE(P,SZ)(::truncate(P, SZ)== 0)
227
+#else
228
+int BOOST_RESIZE_FILE(const char *path, off_t size)
229
+{
230
+  int retval = -1;
231
+  int fd = open(path, O_WRONLY);
232
+  if (fd != -1)
233
+    retval = ftruncate(fd, size);
234
+  close(fd);
235
+  return retval;
236
+}
237
+#endif
238
 
239
 #   define BOOST_ERROR_NOT_SUPPORTED ENOSYS
240
 #   define BOOST_ERROR_ALREADY_EXISTS EEXIST
241
diff -ru orig/boost_1_44_0/tools/build/v2/tools/gcc.jam boost_1_44_0/tools/build/v2/tools/gcc.jam
242
--- orig/boost_1_44_0/tools/build/v2/tools/gcc.jam	2010-04-20 14:05:14.000000000 +0200
243
+++ boost_1_44_0/tools/build/v2/tools/gcc.jam	2010-09-01 16:37:36.000000000 +0200
244
@@ -935,8 +935,8 @@
245
             }
246
             case * :
247
             {
248
-                option = -pthread ;
249
-                libs = rt ;
250
+#                option = -pthread ;
251
+#                libs = rt ;
252
             }
253
         }
254
     
255
diff -ru orig/boost_1_44_0/tools/build/v2/tools/gcc.py boost_1_44_0/tools/build/v2/tools/gcc.py
256
--- orig/boost_1_44_0/tools/build/v2/tools/gcc.py	2009-10-28 08:47:51.000000000 +0100
257
+++ boost_1_44_0/tools/build/v2/tools/gcc.py	2010-09-01 16:36:22.000000000 +0200
258
@@ -672,12 +672,14 @@
259
         # BeOS has no threading options, don't set anything here.
260
         pass
261
     elif host_os_name.endswith('BSD'):
262
-        flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
263
+        #flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
264
         # there is no -lrt on BSD
265
+        pass
266
     elif host_os_name == 'DragonFly':
267
-        flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
268
+        #flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
269
         # there is no -lrt on BSD - DragonFly is a FreeBSD variant,
270
         # which anoyingly doesn't say it's a *BSD.
271
+        pass
272
     elif host_os_name == 'IRIX':
273
         # gcc on IRIX does not support multi-threading, don't set anything here.
274
         pass
275
@@ -685,8 +687,9 @@
276
         # Darwin has no threading options, don't set anything here.
277
         pass
278
     else:
279
-        flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
280
-        flags('gcc', 'FINDLIBS-SA', [], ['rt'])
281
+        #flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
282
+        #flags('gcc', 'FINDLIBS-SA', [], ['rt'])
283
+        pass
284
 
285
 def cpu_flags(toolset, variable, architecture, instruction_set, values, default=None):
286
     #FIXME: for some reason this fails.  Probably out of date feature code
287
288
</pre>
289
290
Now invoke bjam, and you should have a nice boost installation in the path that you specified in project-config.jam.
291
<pre>
292
./bjam link=static threading=multi --layout=versioned install
293
</pre>
294
295 3 Wim Dumon
h2. Preparing Cmake for Cross Compilation to Android
296 1 Wim Dumon
297
Create a toolchain file. Call it ~/toolchain-android.cmake
298
<pre>
299
SET(ANDROID_DIR /home/wim/project/android/)
300
SET(ANDROID_NDK_DIR ${ANDROID_DIR}/android-ndk-r4-crystax/)
301
SET(STAGING_DIR ${ANDROID_NDK_DIR}/build/prebuilt/linux-x86/arm-eabi-4.4.0/)
302
SET(TARGET_CC ${STAGING_DIR}/bin/arm-eabi-gcc)
303
SET(TARGET_CXX ${STAGING_DIR}/bin/arm-eabi-c++)
304
305
SET(CMAKE_SYSTEM_NAME Android)
306
SET(CMAKE_SYSTEM_VERSION 1)
307
308
SET(CMAKE_SYSTEM_PROCESSOR arm-elf)
309
SET(CMAKE_C_COMPILER ${TARGET_CC})
310
SET(CMAKE_CXX_COMPILER ${TARGET_CXX})
311
312
SET(CMAKE_FIND_ROOT_PATH  ${ANDROID_DIR})
313
314
# search for programs in the build host directories
315
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
316
# for libraries and headers in the target directories
317
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
318
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
319
</pre>
320
321
Create a platform file. Put it in a file called cmake/Platform/Android.cmake
322
<pre>
323
SET(ANDROID true)
324
SET(ANDROID_OPTION_LIST
325
    -I/home/wim/project/android/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/include
326
    -fpic
327
    -mthumb-interwork
328
    -ffunction-sections
329
    -funwind-tables
330
    -fstack-protector
331
    -fno-short-enums
332
    -D__ARM_ARCH_5__
333
    -D__ARM_ARCH_5T__
334
    -D__ARM_ARCH_5E__
335
    -D__ARM_ARCH_5TE__
336
    -Wno-psabi
337
    -march=armv5te
338
    -mtune=xscale
339
    -msoft-float
340
    -mthumb
341
    -Os
342
    -fomit-frame-pointer
343
    -fno-strict-aliasing
344
    -finline-limit=64
345
    -DANDROID
346
    -Wa,--noexecstack
347
#more options
348
    -fvisibility=hidden
349
    -fvisibility-inlines-hidden
350
    -fdata-sections
351
    -DBOOST_THREAD_LINUX
352
    -DBOOST_HAS_PTHREADS
353
    -D_REENTRANT
354
    -D_GLIBCXX__PTHREADS
355
    -DANDROID
356
    -D__ANDROID__
357
    -DBOOST_HAS_GETTIMEOFDAY
358
    -DSQLITE_OMIT_LOAD_EXTENSION
359
)
360
361
foreach(arg ${ANDROID_OPTION_LIST})
362
  set(ANDROID_COMPILE_FLAGS "${ANDROID_COMPILE_FLAGS} ${arg}")
363
endforeach(arg ${ANDROID_OPTION_LIST})
364
365
366
SET(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER>  <DEFINES> <FLAGS> ${ANDROID_COMPILE_FLAGS} -o <OBJECT> -c <SOURCE>")
367
SET(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER>  <DEFINES> <FLAGS> ${ANDROID_COMPILE_FLAGS} -o <OBJECT> -c <SOURCE>")
368
369
SET(ANDROID_NDK_PREFIX "/home/wim/project/android/android-ndk-r4-crystax/")
370
SET(ANDROID_LINK_EXE_FLAGS
371
    "-nostdlib -Bdynamic -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,nocopyreloc"
372
    )
373
SET(ANDROID_CRT_PRE
374
    "${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib/crtbegin_dynamic.o"
375
   )
376
SET(ANDROID_CRT_POST_LIST
377
    "${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib/libmissing.a"
378
    "${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"
379
    "${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"
380
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a"
381
    "${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib/libc.so"
382
    "${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib/libm.so"
383
    "-Wl,--no-undefined"
384
    "-Wl,-z,noexecstack"
385
    "-L${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib"
386
    "-llog"
387
    "-Wl,-rpath-link=${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib"
388
    "${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"
389
    "${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"
390
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a"
391
    "${ANDROID_NDK_PREFIX}/build/platforms/android-3/arch-arm/usr/lib/crtend_android.o"
392
   )
393
foreach(arg ${ANDROID_CRT_POST_LIST})
394
  set(ANDROID_CRT_POST "${ANDROID_CRT_POST} ${arg}")
395
endforeach(arg ${ANDROID_CRT_POST_LIST})
396
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}")
397
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}")
398
399
SET(ANDROID_LINK_SHARED_FLAGS
400
    "-nostdlib -Wl,-soname,<TARGET> -Wl,-shared,-Bsymbolic"
401
    )
402
SET(ANDROID_LINK_SHARED_LIBS_LIST
403
    "-Wl,--whole-archive"
404
    "-Wl,--no-whole-archive"
405
    "${ANDROID_NDK_PREFIX}/build/platforms/android-8/arch-arm/usr/lib/libmissing.a"
406
    "${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"
407
    "${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"
408
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a"
409
    "${ANDROID_NDK_PREFIX}/build/platforms/android-8/arch-arm/usr/lib/libc.so"
410
    "${ANDROID_NDK_PREFIX}/build/platforms/android-8/arch-arm/usr/lib/libm.so"
411
    "-Wl,--no-undefined"
412
    "-Wl,-z,noexecstack"
413
    "-Wl,-rpath-link=${ANDROID_NDK_PREFIX}/build/platforms/android-8/arch-arm/usr/lib"
414
    "${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"
415
    "${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"
416
    "${ANDROID_NDK_PREFIX}/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a"
417
   )
418
foreach(arg ${ANDROID_LINK_SHARED_LIBS_LIST})
419
  set(ANDROID_LINK_SHARED_LIBS "${ANDROID_LINK_SHARED_LIBS} ${arg}")
420
endforeach(arg ${ANDROID_LINK_SHARED_LIBS_LIST})
421
SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
422
    "<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}"
423
    )
424
</pre>
425
426
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).
427
428 3 Wim Dumon
h2. Cross Build Wt
429 1 Wim Dumon
430
Adjust paths as necessary. The CMAKE_MODULE_PATH is the directory where you put your Android platform file.
431
432
<pre>
433
mkdir wt-build
434
cd wt-build
435
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
436
</pre>
437
438 2 Wim Dumon
Android doesn't have libdl, so omit it while compiling the sqlite3 backend:
439
<pre>
440
diff --git a/src/Wt/Dbo/backend/CMakeLists.txt b/src/Wt/Dbo/backend/CMakeLists.txt
441
index f268223..a915db2 100644
442
--- a/src/Wt/Dbo/backend/CMakeLists.txt
443
+++ b/src/Wt/Dbo/backend/CMakeLists.txt
444
@@ -16,7 +16,7 @@ MESSAGE("** Wt::Dbo: building SQLite3 backend.")
445
 TARGET_LINK_LIBRARIES(wtdbosqlite3 wtdbo ${SQLITE3_LIBRARIES} ${BOOST_WT_DT_LIB})
446
447
 IF(NOT WIN32)
448
-  TARGET_LINK_LIBRARIES(wtdbosqlite3 dl)
449
+  TARGET_LINK_LIBRARIES(wtdbosqlite3)
450
 ENDIF(NOT WIN32)
451
452
 INSTALL(TARGETS wtdbosqlite3
453
</pre>
454
455 1 Wim Dumon
Now compile Wt:
456
<pre>
457
make -j 8
458
cd examples
459
make -j 8 -k
460
</pre>
461
462
Examples that use crypt will fail to build.
463
464 3 Wim Dumon
h2. Deploying and running Wt on Android
465 1 Wim Dumon
466
Log in on your android device and make a temporary directory:
467
<pre>
468
$ adb shell
469
# mkdir /data/tmp
470
# cd /data/tmp
471
</pre>
472
473
Copy your executable (and all dependency files, such as the resources directory, if necessary) to the temporary directory:
474
<pre>
475
$ adb shell push hello.wt /data/tmp/hello.wt
476
</pre>
477
478
Run the executable:
479
<pre>
480
$ adb shell
481
# cd /data/tmp
482
# chmod 755 hello.wt
483
# ./hello.wt --docroot=. --http-address=0.0.0.0 --http-port=8080
484
</pre>
485
486
Set up port forwarding so that you can surf to your emulator:
487
<pre>
488
$ telnet localhost 5554
489
Android Console: type 'help' for a list of commands
490
OK
491
redir add tcp:8080:8080
492
</pre>
493
494
Point your browser to http://localhost:8080/ and enjoy your Wt application!