Commit | Line | Data |
---|---|---|
6001596e BF |
1 | If you read this file _as_is_, just ignore the funny characters you |
2 | see. It is written in the POD format (see pod/perlpod.pod) which is | |
3 | specially designed to be readable as is. | |
4 | ||
5 | =head1 NAME | |
6 | ||
7 | perlandroid - Perl under Android | |
8 | ||
9 | =head1 SYNOPSIS | |
10 | ||
fbda5f20 BF |
11 | The first portions of this documents contains instructions |
12 | to cross-compile Perl for Android 2.0 and later, using the | |
13 | binaries provided by Google. The latter portion describes how to build | |
14 | perl native using one of the toolchains available on the Play Store. | |
6001596e BF |
15 | |
16 | =head1 DESCRIPTION | |
17 | ||
18 | This document describes how to set up your host environment when | |
fbda5f20 BF |
19 | attempting to build Perl for Android. |
20 | ||
30bba555 | 21 | =head1 Cross-compilation |
fbda5f20 BF |
22 | |
23 | These instructions assume an Unixish build environment on your host system; | |
24 | they've been tested on Linux and OS X, and may work on Cygwin and MSYS. | |
25 | While Google also provides an NDK for Windows, these steps won't work | |
26 | native there, although it may be possible to cross-compile through different | |
27 | means. | |
6001596e | 28 | |
77edee38 BF |
29 | If your host system's architecture is 32 bits, remember to change the |
30 | C<x86_64>'s below to C<x86>'s. On a similar vein, the examples below | |
31 | use the 4.8 toolchain; if you want to use something older or newer (for | |
32 | example, the 4.4.3 toolchain included in the 8th revision of the NDK), just | |
33 | change those to the relevant version. | |
34 | ||
6001596e BF |
35 | =head2 Get the Android Native Development Kit (NDK) |
36 | ||
37 | You can download the NDK from L<https://developer.android.com/tools/sdk/ndk/index.html>. | |
38 | You'll want the normal, non-legacy version. | |
39 | ||
40 | =head2 Determine the architecture you'll be cross-compiling for | |
41 | ||
42 | There's three possible options: arm-linux-androideabi for ARM, | |
43 | mipsel-linux-android for MIPS, and simply x86 for x86. | |
44 | As of 2014, most Android devices run on ARM, so that is generally a safe bet. | |
45 | ||
46 | With those two in hand, you should add | |
47 | ||
77edee38 | 48 | $ANDROID_NDK/toolchains/$TARGETARCH-4.8/prebuilt/`uname | tr '[A-Z]' '[a-z]'`-x86_64/bin |
6001596e BF |
49 | |
50 | to your PATH, where $ANDROID_NDK is the location where you unpacked the | |
51 | NDK, and $TARGETARCH is your target's architecture. | |
52 | ||
53 | =head2 Set up a standalone toolchain | |
54 | ||
55 | This creates a working sysroot that we can feed to Configure later. | |
56 | ||
57 | $ export ANDROID_TOOLCHAIN=/tmp/my-toolchain-$TARGETARCH | |
58 | $ export SYSROOT=$ANDROID_TOOLCHAIN/sysroot | |
59 | $ $ANDROID_NDK/build/tools/make-standalone-toolchain.sh \ | |
60 | --platform=android-9 \ | |
61 | --install-dir=$ANDROID_TOOLCHAIN \ | |
62 | --system=`uname | tr '[A-Z]' '[a-z]'`-x86_64 \ | |
77edee38 | 63 | --toolchain=$TARGETARCH-4.8 |
6001596e BF |
64 | |
65 | =head2 adb or ssh? | |
66 | ||
67 | adb is the Android Debug Bridge. For our purposes, it's basically a way | |
fbda5f20 BF |
68 | of establishing an ssh connection to an Android device without having to |
69 | install anything on the device itself, as long as the device is either on | |
70 | the same local network as the host, or it is connected to the host through | |
71 | USB. | |
6001596e BF |
72 | Perl can be cross-compiled using either adb or a normal ssh connection; |
73 | in general, if you can connect your device to the host using a USB port, | |
fbda5f20 | 74 | or if you don't feel like installing an sshd app on your device, |
6001596e BF |
75 | you may want to use adb, although you may be forced to switch to ssh if |
76 | your device is not rooted and you're unlucky -- more on that later. | |
b962ec99 | 77 | Alternatively, if you're cross-compiling to an emulator, you'll have to |
6001596e BF |
78 | use adb. |
79 | ||
80 | =head3 adb | |
81 | ||
82 | To use adb, download the Android SDK from L<https://developer.android.com/sdk/index.html>. | |
83 | The "SDK Tools Only" version should suffice -- if you downloaded the ADT | |
84 | Bundle, you can find the sdk under $ADT_BUNDLE/sdk/. | |
85 | ||
86 | Add $ANDROID_SDK/platform-tools to your PATH, which should give you access | |
87 | to adb. You'll now have to find your device's name using 'adb devices', | |
88 | and later pass that to Configure through '-Dtargethost=$DEVICE'. | |
89 | ||
90 | However, before calling Configure, you need to check if using adb is a | |
91 | viable choice in the first place. Because Android doesn't have a /tmp, | |
92 | nor does it allow executables in the sdcard, we need to find somewhere in | |
93 | the device for Configure to put some files in, as well as for the tests | |
94 | to run in. If your device is rooted, then you're good. Try running these: | |
95 | ||
96 | $ export TARGETDIR=/mnt/asec/perl | |
97 | $ adb -s $DEVICE shell "echo sh -c '\"mkdir $TARGETDIR\"' | su --" | |
98 | ||
99 | Which will create the directory we need, and you can move on to the next | |
100 | step. /mnt/asec is mounted as a tmpfs in Android, but it's only | |
101 | accessible to root. | |
102 | ||
103 | If your device is not rooted, you may still be in luck. Try running this: | |
104 | ||
105 | $ export TARGETDIR=/data/local/tmp/perl | |
106 | $ adb -s $DEVICE shell "mkdir $TARGETDIR" | |
107 | ||
108 | If the command works, you can move to the next step, but beware: | |
109 | B<You'll have to remove the directory from the device once you are done! | |
110 | Unlike /mnt/asec, /data/local/tmp may not get automatically garbage | |
111 | collected once you shut off the phone>. | |
112 | ||
113 | If neither of those work, then you can't use adb to cross-compile to your | |
114 | device. Either try rooting it, or go for the ssh route. | |
115 | ||
116 | =head3 ssh | |
117 | ||
118 | To use ssh, you'll need to install and run a sshd app and set it up | |
119 | properly. There are several paid and free apps that do this rather | |
b962ec99 | 120 | easily, so you should be able to spot one on the store. |
6001596e BF |
121 | Remember that Perl requires a passwordless connection, so set up a |
122 | public key. | |
123 | ||
124 | Note that several apps spew crap to stderr every time you | |
125 | connect, which can throw off Configure. You may need to monkeypatch | |
126 | the part of Configure that creates 'run-ssh' to have it discard stderr. | |
127 | ||
128 | Since you're using ssh, you'll have to pass some extra arguments to | |
129 | Configure: -Dtargetrun=ssh -Dtargethost=$TARGETHOST -Dtargetuser=$TARGETUSER -Dtargetport=$TARGETPORT | |
130 | ||
131 | =head2 Configure and beyond | |
132 | ||
133 | With all of the previous done, you're now ready to call Configure. | |
134 | ||
135 | If using adb, a "basic" Configure line will look like this: | |
136 | ||
137 | $ ./Configure -des -Dusedevel -Dusecrosscompile -Dtargetrun=adb \ | |
138 | -Dcc=$TARGETARCH-gcc \ | |
139 | -Dsysroot=$SYSROOT \ | |
140 | -Dtargetdir=$TARGETDIR \ | |
141 | -Dtargethost=$DEVICE | |
142 | ||
143 | If using ssh, it's not too different -- we just change targetrun to ssh, | |
144 | and pass in targetuser and targetport. It ends up looking like this: | |
145 | ||
146 | $ ./Configure -des -Dusedevel -Dusecrosscompile -Dtargetrun=ssh \ | |
147 | -Dcc=$TARGETARCH-gcc \ | |
148 | -Dsysroot=$SYSROOT \ | |
149 | -Dtargetdir=$TARGETDIR \ | |
150 | -Dtargethost="$TARGETHOST" \ | |
151 | -Dtargetuser=$TARGETUSER \ | |
152 | -Dtargetport=$TARGETPORT | |
153 | ||
154 | Now you're ready to run make and make test! | |
155 | ||
156 | As a final word of warning, if you're using adb, make test may appear to | |
157 | hang; this is because it doesn't output anything until it finishes | |
158 | running all tests. You can check its progress by logging into the | |
159 | device, moving to $TARGETDIR, and looking at the file output.stdout. | |
160 | ||
161 | =head3 Notes | |
162 | ||
163 | =over | |
164 | ||
165 | =item * | |
166 | ||
167 | If you are targetting x86 Android, you will have to change $TARGETARCH-gcc | |
168 | to i686-linux-android-gcc. | |
169 | ||
170 | =item * | |
171 | ||
172 | On some older low-end devices -- think early 2.2 era -- some tests, | |
173 | particularly t/re/uniprops, may crash the phone, causing it to turn | |
174 | itself off once, and then back on again. | |
175 | ||
d639e0ae BF |
176 | =back |
177 | ||
fbda5f20 BF |
178 | =head1 Native Builds |
179 | ||
180 | While Google doesn't provide a native toolchain for Android, | |
181 | you can still get one from the Play Store; for example, there's the CCTools | |
182 | app which you can get for free. | |
183 | Keep in mind that you want a full | |
184 | toolchain; some apps tend to default to installing only a barebones | |
185 | version without some important utilities, like ar or nm. | |
186 | ||
187 | Once you have the toolchain set up properly, the only | |
188 | remaining hurdle is actually locating where in the device it was installed | |
189 | in. For example, CCTools installs its toolchain in | |
190 | /data/data/com.pdaxrom.cctools/root/cctools. With the path in hand, | |
191 | compiling perl is little more than: | |
192 | ||
f185f654 KW |
193 | export SYSROOT=<location of the native toolchain> |
194 | export LD_LIBRARY_PATH="$SYSROOT/lib:`pwd`:`pwd`/lib:`pwd`/lib/auto:$LD_LIBRARY_PATH" | |
195 | sh Configure -des -Dsysroot=$SYSROOT -Alibpth="/system/lib /vendor/lib" | |
fbda5f20 | 196 | |
6001596e BF |
197 | =head1 AUTHOR |
198 | ||
199 | Brian Fraser <fraserbn@gmail.com> | |
200 | ||
201 | =cut |