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