This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
bump version to v5.22.0 with Porting/bump-perl-version
[perl5.git] / hints / linux-android.sh
index d2f4118..6a59cb7 100644 (file)
@@ -1,9 +1,142 @@
 # set -x
 
-# Having fun with the dlopen check.. :(
-#d_dlopen='define'
-#d_dlerror='define'
+# Install the perl and its libraries anywhere:
+case "$userelocatableinc" in
+'') userelocatableinc='define' ;;
+esac
+
+# The Android linker has some unusual behavior: No matter what
+# path is passed in to dlopen(), it'll only use the path's
+# basename when trying to find a cached library.
+# Unfortunately, this is quite problematic for us, since for example,
+# Hash::Util and List::Util both end up creating a Util.so --
+# So if you load List::Util and then Hash::Util, the dlopen() for
+# the latter will return the handle for the former.
+# See the implementation for details:
+# https://code.google.com/p/android-source-browsing/source/browse/linker/linker.c?repo=platform--bionic&r=9ec0f03a0d0b17bbb94ac0b9fef6add28a133c3a#1231
+# What d_libname_unique does is inform MakeMaker that, rather than
+# creating Hash/Util/Util.so, it needs to make Hash/Util/Perl_Hash_Util.so
+d_libname_unique='define'
+
+# On Android the shell is /system/bin/sh:
+targetsh='/system/bin/sh'
+case "$usecrosscompile" in
+define) ;;
+   # If we aren't cross-compiling, then sh should also point
+   # to /system/bin/sh.
+*) sh=$targetsh ;;
+esac
+
+# Make sure that we look for libm
+libswanted="$libswanted m"
+
+# Down with locales!
+# https://github.com/android/platform_bionic/blob/master/libc/CAVEATS
+d_locconv='undef'
+d_setlocale='undef'
+d_setlocale_r='undef'
+d_lc_monetary_2008='undef'
+i_locale='undef'
+
+# https://code.google.com/p/android-source-browsing/source/browse/libc/netbsd/net/getservent_r.c?repo=platform--bionic&r=ca6fe7bebe3cc6ed7e2db5a3ede2de0fcddf411d#95
+d_getservent_r='undef'
+
+# Bionic defines several stubs that just warn and return NULL
+# https://gitorious.org/0xdroid/bionic/blobs/70b2ef0ec89a9c9d4c2d4bcab728a0e72bafb18e/libc/bionic/stubs.c
+# https://android.googlesource.com/platform/bionic/+/master/libc/bionic/stubs.cpp
+
+# If they warn with 'FIX' or 'Android', assume they are the stubs
+# we want to avoid.
+
+# These are all stubs as well, but the core doesn't use them:
+# getusershell setusershell endusershell
+
+# This script UU/archname.cbu will get 'called-back' by Configure.
+$cat > UU/archname.cbu <<'EOCBU'
+# egrep pattern to detect a stub warning on Android.
+# Right now we're checking for:
+# Android 2.x: FIX ME! implement FUNC
+# Android 4.x: FUNC is not implemented on Android
+android_stub='FIX|Android'
+
+$cat > try.c << 'EOM'
+#include <netdb.h>
+int main() { (void) getnetbyname("foo"); return(0); }
+EOM
+$cc $ccflags try.c -o try
+android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
+if test "X$android_warn" != X; then
+   d_getnbyname="$undef"
+fi
 
+$cat > try.c << 'EOM'
+#include <netdb.h>
+int main() { (void) getnetbyaddr((uint32_t)1, AF_INET); return(0); }
+EOM
+$cc $ccflags try.c -o try
+android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
+if test "X$android_warn" != X; then
+   d_getnbyaddr="$undef"
+fi
+
+$cat > try.c << 'EOM'
+#include <stdio.h>
+#include <mntent.h>
+#include <unistd.h>
+int main() { (void) getmntent(stdout); return(0); }
+EOM
+$cc $ccflags try.c -o try
+android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
+if test "X$android_warn" != X; then
+   d_getmntent="$undef"
+fi
+
+$cat > try.c << 'EOM'
+#include <netdb.h>
+int main() { (void) getprotobyname("foo"); return(0); }
+EOM
+$cc $ccflags try.c -o try
+android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
+if test "X$android_warn" != X; then
+   d_getpbyname="$undef"
+fi
+
+$cat > try.c << 'EOM'
+#include <netdb.h>
+int main() { (void) getprotobynumber(1); return(0); }
+EOM
+$cc $ccflags try.c -o try
+android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
+if test "X$android_warn" != X; then
+   d_getpbynumber="$undef"
+fi
+
+$cat > try.c << 'EOM'
+#include <sys/types.h>
+#include <pwd.h>
+int main() { endpwent(); return(0); }
+EOM
+$cc $ccflags try.c -o try
+android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
+if test "X$android_warn" != X; then
+   d_endpwent="$undef"
+fi
+
+$cat > try.c << 'EOM'
+#include <unistd.h>
+int main() { (void) ttyname(STDIN_FILENO); return(0); }
+EOM
+$cc $ccflags try.c -o try
+android_warn=`$run ./try 2>&1 | $egrep "$android_stub"`
+if test "X$android_warn" != X; then
+   d_ttyname="$undef"
+fi
+
+EOCBU
+
+if $test "X$targetrun" = "Xadb"; then
+
+$rm $run $to $from $targetmkdir
 
 case "$src" in
     /*) run=$src/Cross/run
@@ -18,7 +151,7 @@ case "$src" in
             from=$pwd/Cross/from
                ;;
 esac
-    
+
 targetrun=adb-shell
 targetto=adb-push
 targetfrom=adb-pull
@@ -26,9 +159,10 @@ run=$run-$targetrun
 to=$to-$targetto
 from=$from-$targetfrom
 
-cat >$run <<EOF
+$cat >$run <<EOF
 #!/bin/sh
-doexit="echo \\\$?"
+doexit="echo \\\$? >$targetdir/output.status"
+env=''
 case "\$1" in
 -cwd)
   shift
@@ -36,58 +170,74 @@ case "\$1" in
   shift
   ;;
 esac
+case "\$1" in
+-env)
+  shift
+  env=\$1
+  shift
+  ;;
+esac
 case "\$cwd" in
 '') cwd=$targetdir ;;
 esac
+case "\$env" in
+'') env="echo "
+esac
 exe=\$1
 shift
+args=\$@
 $to \$exe > /dev/null 2>&1
 
 # send copy results to /dev/null as otherwise it outputs speed stats which gets in our way.
-foo=\`adb -s $targethost shell "sh -c '(cd \$cwd && \$exe \$@ > \$exe.stdout) ; \$doexit '"\`
+# sometimes there is no $?, I dunno why? we then get Cross/run-adb-shell: line 39: exit: XX: numeric argument required
+adb -s $targethost shell "sh -c '(cd \$cwd && \$env ; \$exe \$args > $targetdir/output.stdout 2>$targetdir/output.stderr) ; \$doexit '" > /dev/null
+
+rm output.stdout output.stderr output.status 2>/dev/null
+
+$from output.stdout
+$from output.stderr
+$from output.status
+
 # We get back Ok\r\n on android for some reason, grrr:
-$from \$exe.stdout
-result=\`cat \$exe.stdout\`
-rm \$exe.stdout
-foo=\`echo \$foo | sed -e 's|\r||g'\`
+$cat output.stdout | $tr -d '\r'
+if test -s output.stderr; then
+    $cat output.stderr | $tr -d '\r' >&2
+fi
+
+result_status=\`$cat output.status | $tr -d '\r'\`
+
+rm output.stdout output.stderr output.status
+
 # Also, adb doesn't exit with the commands exit code, like ssh does, double-grr
-echo \$result
-exit \$foo
-# if test "X\$doexit" != X; then
-#  exit \$foo
-#else
-#  echo \$foo
-#fi
+exit \$result_status
 
 EOF
-chmod a+rx $run
+$chmod a+rx $run
 
-cat >$targetmkdir <<EOF
+$cat >$targetmkdir <<EOF
 #!/bin/sh
 adb -s $targethost shell "mkdir -p \$@"
 EOF
-chmod a+rx $targetmkdir
+$chmod a+rx $targetmkdir
 
-cat >$to <<EOF
+$cat >$to <<EOF
 #!/bin/sh
 for f in \$@
 do
   case "\$f" in
   /*)
-    $targetmkdir \`dirname \$f\`
     adb -s $targethost push \$f \$f            || exit 1
     ;;
   *)
-    $targetmkdir $targetdir/\`dirname \$f\`
     (adb -s $targethost push \$f $targetdir/\$f < /dev/null 2>&1) || exit 1
     ;;
   esac
 done
 exit 0
 EOF
-chmod a+rx $to
+$chmod a+rx $to
 
-cat >$from <<EOF
+$cat >$from <<EOF
 #!/bin/sh
 for f in \$@
 do
@@ -96,5 +246,55 @@ do
 done
 exit 0
 EOF
-chmod a+rx $from
+$chmod a+rx $from
+
+fi # Cross-compiling with adb
+
+case "$usecrosscompile" in
+define)
+# The tests for this in Configure doesn't play nicely with
+# cross-compiling
+d_procselfexe="define"
+if $test "X$hostosname" = "Xdarwin"; then
+  firstmakefile=GNUmakefile;
+fi
+
+# When cross-compiling, full_csh and d_csh will get the
+# host's values, which is all sorts of wrong.  So unless
+# full_csh has been set on the command line, set d_csh to
+# undef.
+case "$full_csh" in
+'') d_csh="$undef"
+;;
+esac
+
+;;
+*)
+ldflags="$ldflags -L/system/lib"
+;;
+esac
+
+osvers="`$run getprop ro.build.version.release`"
+
+# We want osname to be linux-android during Configure,
+# but plain 'android' afterwards.
+case "$src" in
+    /*) pwd="$src";;
+    *)  pwd=`test -f ../Configure && cd ..; pwd`
+        ;;
+esac
+
+$cat <<'EOO' >> $pwd/config.arch
+
+osname='android'
+eval "libpth='$libpth /system/lib /vendor/lib'"
+
+if $test "X$procselfexe" = X; then
+    case "$d_procselfexe" in
+        define) procselfexe='"/proc/self/exe"';;
+    esac
+fi
+EOO
 
+# Android is a linux variant, so run those hints.
+. ./hints/linux.sh