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 | ||
2000dc21 | 48 | $ANDROID_NDK/toolchains/$TARGETARCH-4.8/prebuilt/`uname | tr '[A-Z]' '[a-z]'`-x86_64/bin |
6001596e | 49 | |
2000dc21 LM |
50 | to your C<PATH>, where C<$ANDROID_NDK> is the location where you unpacked the |
51 | NDK, and C<$TARGETARCH> is your target's architecture. | |
6001596e BF |
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. | |
2000dc21 | 72 | |
6001596e BF |
73 | Perl can be cross-compiled using either adb or a normal ssh connection; |
74 | in general, if you can connect your device to the host using a USB port, | |
fbda5f20 | 75 | or if you don't feel like installing an sshd app on your device, |
6001596e BF |
76 | you may want to use adb, although you may be forced to switch to ssh if |
77 | your device is not rooted and you're unlucky -- more on that later. | |
b962ec99 | 78 | Alternatively, if you're cross-compiling to an emulator, you'll have to |
6001596e BF |
79 | use adb. |
80 | ||
81 | =head3 adb | |
82 | ||
83 | To use adb, download the Android SDK from L<https://developer.android.com/sdk/index.html>. | |
84 | The "SDK Tools Only" version should suffice -- if you downloaded the ADT | |
2000dc21 | 85 | Bundle, you can find the sdk under F<$ADT_BUNDLE/sdk/>. |
6001596e | 86 | |
2000dc21 LM |
87 | Add F<$ANDROID_SDK/platform-tools> to your C<PATH>, which should give you access |
88 | to adb. You'll now have to find your device's name using C<adb devices>, | |
89 | and later pass that to Configure through C<-Dtargethost=$DEVICE>. | |
6001596e BF |
90 | |
91 | However, before calling Configure, you need to check if using adb is a | |
2000dc21 | 92 | viable choice in the first place. Because Android doesn't have a F</tmp>, |
6001596e BF |
93 | nor does it allow executables in the sdcard, we need to find somewhere in |
94 | the device for Configure to put some files in, as well as for the tests | |
95 | to run in. If your device is rooted, then you're good. Try running these: | |
96 | ||
97 | $ export TARGETDIR=/mnt/asec/perl | |
98 | $ adb -s $DEVICE shell "echo sh -c '\"mkdir $TARGETDIR\"' | su --" | |
99 | ||
100 | Which will create the directory we need, and you can move on to the next | |
2000dc21 | 101 | step. F</mnt/asec> is mounted as a tmpfs in Android, but it's only |
6001596e BF |
102 | accessible to root. |
103 | ||
104 | If your device is not rooted, you may still be in luck. Try running this: | |
105 | ||
106 | $ export TARGETDIR=/data/local/tmp/perl | |
107 | $ adb -s $DEVICE shell "mkdir $TARGETDIR" | |
108 | ||
109 | If the command works, you can move to the next step, but beware: | |
110 | B<You'll have to remove the directory from the device once you are done! | |
2000dc21 | 111 | Unlike F</mnt/asec>, F</data/local/tmp> may not get automatically garbage |
6001596e BF |
112 | collected once you shut off the phone>. |
113 | ||
114 | If neither of those work, then you can't use adb to cross-compile to your | |
115 | device. Either try rooting it, or go for the ssh route. | |
116 | ||
117 | =head3 ssh | |
118 | ||
119 | To use ssh, you'll need to install and run a sshd app and set it up | |
120 | properly. There are several paid and free apps that do this rather | |
b962ec99 | 121 | easily, so you should be able to spot one on the store. |
6001596e BF |
122 | Remember that Perl requires a passwordless connection, so set up a |
123 | public key. | |
124 | ||
125 | Note that several apps spew crap to stderr every time you | |
126 | connect, which can throw off Configure. You may need to monkeypatch | |
2000dc21 | 127 | the part of Configure that creates C<run-ssh> to have it discard stderr. |
6001596e BF |
128 | |
129 | Since you're using ssh, you'll have to pass some extra arguments to | |
2000dc21 LM |
130 | Configure: |
131 | ||
132 | -Dtargetrun=ssh -Dtargethost=$TARGETHOST -Dtargetuser=$TARGETUSER -Dtargetport=$TARGETPORT | |
6001596e BF |
133 | |
134 | =head2 Configure and beyond | |
135 | ||
136 | With all of the previous done, you're now ready to call Configure. | |
137 | ||
138 | If using adb, a "basic" Configure line will look like this: | |
139 | ||
2000dc21 LM |
140 | $ ./Configure -des -Dusedevel -Dusecrosscompile -Dtargetrun=adb \ |
141 | -Dcc=$TARGETARCH-gcc \ | |
142 | -Dsysroot=$SYSROOT \ | |
143 | -Dtargetdir=$TARGETDIR \ | |
144 | -Dtargethost=$DEVICE | |
6001596e BF |
145 | |
146 | If using ssh, it's not too different -- we just change targetrun to ssh, | |
147 | and pass in targetuser and targetport. It ends up looking like this: | |
148 | ||
2000dc21 LM |
149 | $ ./Configure -des -Dusedevel -Dusecrosscompile -Dtargetrun=ssh \ |
150 | -Dcc=$TARGETARCH-gcc \ | |
151 | -Dsysroot=$SYSROOT \ | |
152 | -Dtargetdir=$TARGETDIR \ | |
153 | -Dtargethost="$TARGETHOST" \ | |
154 | -Dtargetuser=$TARGETUSER \ | |
155 | -Dtargetport=$TARGETPORT | |
6001596e | 156 | |
2000dc21 | 157 | Now you're ready to run C<make> and C<make test>! |
6001596e | 158 | |
2000dc21 | 159 | As a final word of warning, if you're using adb, C<make test> may appear to |
6001596e BF |
160 | hang; this is because it doesn't output anything until it finishes |
161 | running all tests. You can check its progress by logging into the | |
2000dc21 | 162 | device, moving to F<$TARGETDIR>, and looking at the file F<output.stdout>. |
6001596e BF |
163 | |
164 | =head3 Notes | |
165 | ||
166 | =over | |
167 | ||
168 | =item * | |
169 | ||
2000dc21 LM |
170 | If you are targetting x86 Android, you will have to change C<$TARGETARCH-gcc> |
171 | to C<i686-linux-android-gcc>. | |
6001596e BF |
172 | |
173 | =item * | |
174 | ||
175 | On some older low-end devices -- think early 2.2 era -- some tests, | |
2000dc21 | 176 | particularly F<t/re/uniprops.t>, may crash the phone, causing it to turn |
6001596e BF |
177 | itself off once, and then back on again. |
178 | ||
d639e0ae BF |
179 | =back |
180 | ||
fbda5f20 BF |
181 | =head1 Native Builds |
182 | ||
183 | While Google doesn't provide a native toolchain for Android, | |
184 | you can still get one from the Play Store; for example, there's the CCTools | |
185 | app which you can get for free. | |
186 | Keep in mind that you want a full | |
187 | toolchain; some apps tend to default to installing only a barebones | |
188 | version without some important utilities, like ar or nm. | |
189 | ||
190 | Once you have the toolchain set up properly, the only | |
191 | remaining hurdle is actually locating where in the device it was installed | |
192 | in. For example, CCTools installs its toolchain in | |
2000dc21 | 193 | F</data/data/com.pdaxrom.cctools/root/cctools>. With the path in hand, |
fbda5f20 BF |
194 | compiling perl is little more than: |
195 | ||
f185f654 KW |
196 | export SYSROOT=<location of the native toolchain> |
197 | export LD_LIBRARY_PATH="$SYSROOT/lib:`pwd`:`pwd`/lib:`pwd`/lib/auto:$LD_LIBRARY_PATH" | |
198 | sh Configure -des -Dsysroot=$SYSROOT -Alibpth="/system/lib /vendor/lib" | |
fbda5f20 | 199 | |
6001596e BF |
200 | =head1 AUTHOR |
201 | ||
202 | Brian Fraser <fraserbn@gmail.com> | |
203 | ||
204 | =cut |