perldelta for 43e5ab2e34fe
[perl.git] / hints / linux-android.sh
1 # set -x
2
3 # Install the perl and its libraries anywhere:
4 case "$userelocatableinc" in
5 '') userelocatableinc='define' ;;
6 esac
7
8 # The Android linker has some unusual behavior: No matter what
9 # path is passed in to dlopen(), it'll only use the path's
10 # basename when trying to find a cached library.
11 # Unfortunately, this is quite problematic for us, since for example,
12 # Hash::Util and List::Util both end up creating a Util.so --
13 # So if you load List::Util and then Hash::Util, the dlopen() for
14 # the latter will return the handle for the former.
15 # See the implementation for details:
16 # https://code.google.com/p/android-source-browsing/source/browse/linker/linker.c?repo=platform--bionic&r=9ec0f03a0d0b17bbb94ac0b9fef6add28a133c3a#1231
17 # What d_libname_unique does is inform MakeMaker that, rather than
18 # creating Hash/Util/Util.so, it needs to make Hash/Util/Perl_Hash_Util.so
19 d_libname_unique='define'
20
21 # On Android the shell is /system/bin/sh:
22 targetsh='/system/bin/sh'
23 case "$usecrosscompile" in
24 define) ;;
25    # If we aren't cross-compiling, then sh should also point
26    # to /system/bin/sh.
27 *) sh=$targetsh ;;
28 esac
29
30 # Make sure that we look for libm
31 libswanted="$libswanted m log"
32
33 # Older Androids lack locale support and may need the following undefs
34 # uncommenting. This isn't necessary from at least Android 8.1 (Oreo)
35 # https://github.com/android/platform_bionic/blob/master/libc/CAVEATS
36 #d_locconv='undef'
37 #d_setlocale='undef'
38 #d_setlocale_r='undef'
39 #d_lc_monetary_2008='undef'
40 #i_locale='undef'
41 #d_newlocale='undef'
42
43 # https://code.google.com/p/android-source-browsing/source/browse/libc/netbsd/net/getservent_r.c?repo=platform--bionic&r=ca6fe7bebe3cc6ed7e2db5a3ede2de0fcddf411d#95
44 d_getservent_r='undef'
45
46 # Bionic defines several stubs that warn (in older releases) and return NULL
47 # https://gitorious.org/0xdroid/bionic/blobs/70b2ef0ec89a9c9d4c2d4bcab728a0e72bafb18e/libc/bionic/stubs.c
48 # https://android.googlesource.com/platform/bionic/+/master/libc/bionic/stubs.cpp
49
50 # These tests originally looked for 'FIX' or 'Android' warnings, as they
51 # indicated stubs to avoid. At some point, Android stopped emitting
52 # those warnings; the tests were adapted to check function return values
53 # and hopefully now detect stubs on both older and newer Androids.
54
55 # These are all stubs as well, but the core doesn't use them:
56 # getusershell setusershell endusershell
57
58 # This script UU/archname.cbu will get 'called-back' by Configure.
59 $cat > UU/archname.cbu <<'EOCBU'
60 # original egrep pattern to detect a stub warning on Android.
61 # Right now we're checking for:
62 # Android 2.x: FIX ME! implement FUNC
63 # Android 4.x: FUNC is not implemented on Android
64 # Android 8.x: <no warnings; tests now printf a compatible warning>
65 android_stub='FIX|Android'
66
67 $cat > try.c << 'EOM'
68 #include <netdb.h>
69 #include <stdio.h>
70 int main() {
71   struct netent* test = getnetbyname("loopback");
72   if (test == NULL) {
73     printf("getnetbyname is still a stub function on Android");
74   }
75   return(0);
76 }
77 EOM
78 $cc $ccflags try.c -o try
79 android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
80 if test "X$android_warn" != X; then
81    d_getnbyname="$undef"
82 fi
83
84 $cat > try.c << 'EOM'
85 #include <netdb.h>
86 #include <stdio.h>
87 int main() {
88   struct netent* test = getnetbyaddr(127, AF_INET);
89   if (test == NULL) {
90     printf("getnetbyaddr is still a stub function on Android");
91   }
92   return(0);
93 }
94 EOM
95 $cc $ccflags try.c -o try
96 android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
97 if test "X$android_warn" != X; then
98    d_getnbyaddr="$undef"
99 fi
100
101 $cat > try.c << 'EOM'
102 #include <stdio.h>
103 #include <mntent.h>
104 #include <unistd.h>
105 int main() { (void) getmntent(stdout); return(0); }
106 EOM
107 $cc $ccflags try.c -o try
108 android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
109 if test "X$android_warn" != X; then
110    d_getmntent="$undef"
111 fi
112
113 $cat > try.c << 'EOM'
114 #include <netdb.h>
115 #include <stdio.h>
116 int main() {
117   struct protoent* test = getprotobyname("tcp");
118   if (test == NULL) {
119     printf("getprotobyname is still a stub function on Android");
120   }
121   return(0);
122 }
123 EOM
124 $cc $ccflags try.c -o try
125 android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
126 if test "X$android_warn" != X; then
127    d_getpbyname="$undef"
128 fi
129
130 $cat > try.c << 'EOM'
131 #include <netdb.h>
132 #include <stdio.h>
133 int main() {
134   struct protoent* test = getprotobynumber(1);
135   if (test == NULL) {
136     printf("getprotobynumber is still a stub function on Android");
137   }
138   return(0);
139 }
140 EOM
141 $cc $ccflags try.c -o try
142 android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
143 if test "X$android_warn" != X; then
144    d_getpbynumber="$undef"
145 fi
146
147 $cat > try.c << 'EOM'
148 #include <sys/types.h>
149 #include <pwd.h>
150 int main() { endpwent(); return(0); }
151 EOM
152 $cc $ccflags try.c -o try
153 android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
154 if test "X$android_warn" != X; then
155    d_endpwent="$undef"
156 fi
157
158 $cat > try.c << 'EOM'
159 #include <unistd.h>
160 #include <stdio.h>
161 int main() {
162   char *tty = ttyname(STDIN_FILENO);
163   if (tty == NULL) {
164     printf("ttyname is still a stub function on Android");
165   }
166   return(0);
167 }
168 EOM
169 $cc $ccflags try.c -o try
170 android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
171 if test "X$android_warn" != X; then
172    d_ttyname="$undef"
173 fi
174
175 EOCBU
176
177 if $test "X$targetrun" = "Xadb"; then
178
179 $rm $run $to $from $targetmkdir
180
181 case "$src" in
182     /*) run=$src/Cross/run
183             targetmkdir=$src/Cross/mkdir
184             to=$src/Cross/to
185             from=$src/Cross/from
186             ;;
187     *)  pwd=`test -f ../Configure && cd ..; pwd`
188             run=$pwd/Cross/run
189             targetmkdir=$pwd/Cross/mkdir
190             to=$pwd/Cross/to
191             from=$pwd/Cross/from
192                ;;
193 esac
194
195 targetrun=adb-shell
196 targetto=adb-push
197 targetfrom=adb-pull
198 run=$run-$targetrun
199 to=$to-$targetto
200 from=$from-$targetfrom
201
202 $cat >$run <<EOF
203 #!/bin/sh
204 doexit="echo \\\$? >$targetdir/output.status"
205 env=''
206 case "\$1" in
207 -cwd)
208   shift
209   cwd=\$1
210   shift
211   ;;
212 esac
213 case "\$1" in
214 -env)
215   shift
216   env=\$1
217   shift
218   ;;
219 esac
220 case "\$cwd" in
221 '') cwd=$targetdir ;;
222 esac
223 case "\$env" in
224 '') env="echo "
225 esac
226 exe=\$1
227 shift
228 args=\$@
229 $to \$exe > /dev/null 2>&1
230
231 # send copy results to /dev/null as otherwise it outputs speed stats which gets in our way.
232 # sometimes there is no $?, I dunno why? we then get Cross/run-adb-shell: line 39: exit: XX: numeric argument required
233 adb -s $targethost shell "sh -c '(cd \$cwd && \$env ; \$exe \$args > $targetdir/output.stdout 2>$targetdir/output.stderr) ; \$doexit '" > /dev/null
234
235 rm output.stdout output.stderr output.status 2>/dev/null
236
237 $from output.stdout
238 $from output.stderr
239 $from output.status
240
241 # We get back Ok\r\n on android for some reason, grrr:
242 $cat output.stdout | $tr -d '\r'
243 if test -s output.stderr; then
244     $cat output.stderr | $tr -d '\r' >&2
245 fi
246
247 result_status=\`$cat output.status | $tr -d '\r'\`
248
249 rm output.stdout output.stderr output.status
250
251 # Also, adb doesn't exit with the commands exit code, like ssh does, double-grr
252 exit \$result_status
253
254 EOF
255 $chmod a+rx $run
256
257 $cat >$targetmkdir <<EOF
258 #!/bin/sh
259 adb -s $targethost shell "mkdir -p \$@"
260 EOF
261 $chmod a+rx $targetmkdir
262
263 $cat >$to <<EOF
264 #!/bin/sh
265 for f in \$@
266 do
267   case "\$f" in
268   /*)
269     adb -s $targethost push \$f \$f            || exit 1
270     ;;
271   *)
272     (adb -s $targethost push \$f $targetdir/\$f < /dev/null 2>&1) || exit 1
273     ;;
274   esac
275 done
276 exit 0
277 EOF
278 $chmod a+rx $to
279
280 $cat >$from <<EOF
281 #!/bin/sh
282 for f in \$@
283 do
284   $rm -f \$f
285   (adb -s $targethost pull $targetdir/\$f . > /dev/null 2>&1) || exit 1
286 done
287 exit 0
288 EOF
289 $chmod a+rx $from
290
291 fi # Cross-compiling with adb
292
293 case "$usecrosscompile" in
294 define)
295 # The tests for this in Configure doesn't play nicely with
296 # cross-compiling
297 d_procselfexe="define"
298 if $test "X$hostosname" = "Xdarwin"; then
299   firstmakefile=GNUmakefile;
300 fi
301
302 # When cross-compiling, full_csh and d_csh will get the
303 # host's values, which is all sorts of wrong.  So unless
304 # full_csh has been set on the command line, set d_csh to
305 # undef.
306 case "$full_csh" in
307 '') d_csh="$undef"
308 ;;
309 esac
310
311 ;;
312 *)
313 ldflags="$ldflags -L/system/lib"
314 ;;
315 esac
316
317 osvers="`$run getprop ro.build.version.release`"
318
319 # We want osname to be linux-android during Configure,
320 # but plain 'android' afterwards.
321 case "$src" in
322     /*) pwd="$src";;
323     *)  pwd=`test -f ../Configure && cd ..; pwd`
324         ;;
325 esac
326
327 $cat <<'EOO' >> $pwd/config.arch
328
329 osname='android'
330 eval "libpth='$libpth /system/lib /vendor/lib'"
331
332 if $test "X$procselfexe" = X; then
333     case "$d_procselfexe" in
334         define) procselfexe='"/proc/self/exe"';;
335     esac
336 fi
337 EOO
338
339 # Android is a linux variant, so run those hints.
340 . ./hints/linux.sh