[Android Software Development] Doc_cheilvenerdi.org:
Added some stuffs to the octave binary...

Here there is a new compiled version of octave 3.2.4 for Android...

Just added support to ncurses and readline and to several math improvements...

Actually the binary still lacks "arpack", "fftw3", "cholmod", "umfpack" and "qhull" libraries...

Of course no "native graphics" support (I think I'll cannot do it...) but, so forth, I think it's really a usable version for students and so on...

HOW I DID IT!

Chapter 1 - the cross compiler toolchain

I could not immediately use one of the toolchains freely distributed on the net because they usually lack fortran language, so I made one on my own...

I work on a Gentoo LinuX Distribution 64Bit No multilib... briefly I made a chroot environment locked to 32bit executables, binaries and libraries... inside that jail I compiled a cross toolchain using the wonderful package "Crossdev"!

My working parts of the toolchian are:

binutils-2.22

gcc-4.5.3 with gfortran enabled

glibc-2.14.1

kernel-headers-2.35.7

Finally I choose the followin tuplet as the name for this local toolchain:

arm-vfp-linux-gnueabi

Actually it was a "no effort" step... my Gentoo made everything I asked for :)

Chapter 2 - compiling octave dependencies from scratch

I had to compile several dependencies and then octave itself... in the following I report the console commands used for any of them assuming that I'm always inside their working source directory.

I prepared a sysroot environment on my PC starting from /data/local to meet my android path and to avoid strange configurations during compile time...

That is: /data/local is /data/local everywhere...

Man Pages 3.38

make prefix=/data/local/usr install

ZLib 1.26

CC="arm-vfp-linux-gnueabi-gcc" CXX="arm-vfp-linux-gnueabi-g++" AR="arm-vfp-linux-gnueabi-ar" AS="arm-vfp-linux-gnueabi-as" RANLIB="arm-vfp-linux-gnueabiranlib" LD="arm-vfp-linux-gnueabi-ld" STRIP="arm-vfp-linux-gnueabi-strip" ./configure --prefix=/data/local/usr --shared
make
make install
cp /usr/arm-vfp-linux-gnueabi/lib/libc-2.14.1.so /data/local/usr/lib/libc.so.6
cp /usr/arm-vfp-linux-gnueabi/lib/ld-2.14.1.so /data/local/usr/lib/ld-linux.so.3
cp /usr/arm-vfp-linux-gnueabi/lib/libdl-2.14.1.so /data/local/usr/lib/libdl.so.2
cp /usr/lib/gcc/arm-vfp-linux-gnueabi/4.5.3/libgcc_s.so /data/local/usr/lib/
cp /usr/lib/gcc/arm-vfp-linux-gnueabi/4.5.3/libgcc_s.so.1 /data/local/usr/lib/
cp /usr/arm-vfp-linux-gnueabi/lib/libm-2.14.1.so /data/local/usr/lib/libm.so.6
cp /usr/lib/gcc/arm-vfp-linux-gnueabi/4.5.3/libstdc++.so.6.0.14 /data/local/usr/lib/libstdc++.so.6
cp /usr/arm-vfp-linux-gnueabi/lib/libpthread-2.14.1.so /data/local/usr/lib/libpthread.so.0

XZ 5.0.3

./configure --prefix=/data/local/usr --host=arm-vfp-linux-gnueabi
make
make install

Ncurses 5.9

./configure --prefix=/data/local/usr --host=arm-vfp-linux-gnueabi --with-shared
getting this message: ** Include-directory is not in a standard location
make
make install

ReadLine 6.2

./configure --prefix=/data/local/usr --host=arm-vfp-linux-gnueabi --with-curses
make
make install

BLAS (march 2007)

I edited the make.inc file adding/changing the following lines:

#PLAT = _LINUX
FORTRAN = arm-vfp-linux-gnueabi-gfortran
LOADER = arm-vfp-linux-gnueabi-gfortran
ARCH = arm-vfp-linux-gnueabi-ar
RANLIB = arm-vfp-linux-gnueabi-ranlib

and the compiled with

make clean
make
cp blas.a /data/local/usr/lib/
cp /usr/lib/gcc/arm-vfp-linux-gnueabi/4.5.3/libgfortran.so.3.0.0 /data/local/usr/lib/libgfortran.so.3

Lapack 3.4.0

I edited the make.inc file adding/changing the following lines:

FORTRAN = arm-vfp-linux-gnueabi-gfortran
LOADER = arm-vfp-linux-gnueabi-gfortran
ARCH = arm-vfp-linux-gnueabi-ar
RANLIB = arm-vfp-linux-gnueabi-ranlib
BLASLIB = /data/local/usr/lib/blas.a

and then compiled with

cd SRC
make clean
make
cd ..
cp lib{lapack,tmglib}.a /data/local/usr/lib/

UFconfig 3.7.0

CC="arm-vfp-linux-gnueabi-gcc" CXX="arm-vfp-linux-gnueabi-g++" AR="arm-vfp-linux-gnueabi-ar" AS="arm-vfp-linux-gnueabi-as" RANLIB="arm-vfp-linux-gnueabiranlib" LD="arm-vfp-linux-gnueabi-ld" STRIP="arm-vfp-linux-gnueabi-strip" make
cp libufconfig.a /data/local/usr/lib
cp UFconfig.h /data/local/usr/include
chmod 0644 /data/local/usr/lib/libufconfig.a
chmod 0644 /data/local/usr/include/UFconfig.h

AMD 2.2.3

cd Lib
CC="arm-vfp-linux-gnueabi-gcc" Cf="arm-vfp-linux-gnueabi-gfortran" ARCHIVE="arm-vfp-linux-gnueabi-ar" RANLIB="arm-vfp-linux-gnueabiranlib" make
cd ..
cp Lib/libamd.a /data/local/usr/lib
cp Include/amd.h /data/local/usr/include
chmod 0644 /data/local/usr/lib/libamd.a
chmod 0644 /data/local/usr/include/amd.h

CAMD 2.2.3

cd Lib
CC="arm-vfp-linux-gnueabi-gcc" Cf="arm-vfp-linux-gnueabi-gfortran" ARCHIVE="arm-vfp-linux-gnueabi-ar" RANLIB="arm-vfp-linux-gnueabiranlib" make
cd ..
cp Lib/libcamd.a /data/local/usr/lib
cp Include/camd.h /data/local/usr/include
chmod 0644 /data/local/usr/lib/libcamd.a
chmod 0644 /data/local/usr/include/camd.h

COLAMD 2.7.4

cd Lib
CC="arm-vfp-linux-gnueabi-gcc" Cf="arm-vfp-linux-gnueabi-gfortran" ARCHIVE="arm-vfp-linux-gnueabi-ar" RANLIB="arm-vfp-linux-gnueabiranlib" make
cd ..
cp Lib/libcolamd.a /data/local/usr/lib
cp Include/colamd.h /data/local/usr/include
chmod 0644 /data/local/usr/lib/libcolamd.a
chmod 0644 /data/local/usr/include/colamd.h

CCOLAMD 2.7.4

cd Lib
CC="arm-vfp-linux-gnueabi-gcc" Cf="arm-vfp-linux-gnueabi-gfortran" ARCHIVE="arm-vfp-linux-gnueabi-ar" RANLIB="arm-vfp-linux-gnueabiranlib" make
cd ..
cp Lib/libccolamd.a /data/local/usr/lib
cp Include/ccolamd.h /data/local/usr/include
chmod 0644 /data/local/usr/lib/libccolamd.a
chmod 0644 /data/local/usr/include/ccolamd.h

CHOLMOD

cd Lib
CC="arm-vfp-linux-gnueabi-gcc" Cf="arm-vfp-linux-gnueabi-gfortran" ARCHIVE="arm-vfp-linux-gnueabi-ar" RANLIB="arm-vfp-linux-gnueabiranlib" make
cd ..
cp Lib/libcholmod.a /data/local/usr/lib
cp Include/cholmod.h /data/local/usr/include
chmod 0644 /data/local/usr/lib/libcholmod.a
chmod 0644 /data/local/usr/include/cholmod.h

UMFPACK 5.5.2

cd Lib
CC="arm-vfp-linux-gnueabi-gcc" Cf="arm-vfp-linux-gnueabi-gfortran" ARCHIVE="arm-vfp-linux-gnueabi-ar" RANLIB="arm-vfp-linux-gnueabiranlib" make
cd ..
cp Lib/libumfpack.a /data/local/usr/lib
cp Include/umfpack.h /data/local/usr/include
chmod 0644 /data/local/usr/lib/libumfpack.a
chmod 0644 /data/local/usr/include/umfpack.h

CXSparse 2.2.6

cd Lib
CC="arm-vfp-linux-gnueabi-gcc" Cf="arm-vfp-linux-gnueabi-gfortran" ARCHIVE="arm-vfp-linux-gnueabi-ar" RANLIB="arm-vfp-linux-gnueabiranlib" make
cd ..
cp Lib/libcxsparse.a /data/local/usr/lib
cp Include/cs.h /data/local/usr/include
chmod 0644 /data/local/usr/lib/libcxsparse.a
chmod 0644 /data/local/usr/include/cs.h

ARPACK 96

I edited the ARmake.inc file:

home = $(HOME)/builds/ARPACK
DIRS = $(UTILdir) $(SRCdir)
ARPACKLIB = $(home)/libarpack.a
LAPACKLIB = /data/local/usr/lib/lapack.a
BLASLIB = /data/local/usr/lib/blas.a
#PLAT = SUN4
FC = arm-vfp-linux-gnueabi-gfortran
FFLAGS = -O
MAKE = make
SHELL = sh
AR = arm-vfp-linux-gnueabi-ar
RANLIB = arm-vfp-linux-gnueabi-ranlib

and then compiled with

make lib
cp libarpack.a /data/local/usr/lib

fftw 3.3.1

./configure --prefix=/data/local/usr --host=arm-vfp-linux-gnueabi --enable-shared
make
make install

glpk 4.47

./configure --prefix=/data/local/usr --host=arm-vfp-linux-gnueabi
make
make install

QRupdate 1.1.1

I edited Makeconf:

FC=arm-vfp-linux-gnueabi-gfortran
#BLAS=-lblas
#LAPACK=-llapack
PREFIX=/data/local/usr

and compiled with

make solib
cp libqrupdate.so /data/local/usr/lib/libqrupdate.so.1

qhull 2010.1

I edited directly Makefile this way:

BINDIR = /data/local/usr/bin
MANDIR = /data/local/usr/man/man1
CC = arm-vfp-linux-gnueabi-gcc
# ar -r libqhull.a $(OBJS)
arm-vfp-linux-gnueabi-ar -r libqhull.a $(OBJS)
# -test -x /bin/ranlib -o -x /usr/bin/ranlib && ranlib libqhull.a
arm-vfp-linux-gnueabi-ranlib libqhull.a

removing lines where test programs are lanched (arm binaries on linux host don't obviously work) and compiling

make
make install
cp libqhull.a /data/local/usr/lib
mkdir /data/local/usr/include/qhull
cp qhull_a.h /data/local/usr/include/qhull/qhull_a.h
chmod 0644 /data/local/usr/lib/libqhull.a
chmod 0644 /data/local/usr/include/qhull/qhull_a.h

PCRE 8.30

./configure --prefix=/data/local/usr --host=arm-vfp-linux-gnueabi
make
make install

Chapter 3 - compiling octave 3.2.4

configure script

I removed from the configure script few lines, where it tries to launch test programs failing (arm binaries on i686 machine...)

This is the 'diff' output after editing:

14710,14714c14710,14714
< { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
< $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
< as_fn_error "cannot run test program while cross compiling
< See \`config.log' for more details." "$LINENO" 5; }
< else
---
> # { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
> #$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
> #as_fn_error "cannot run test program while cross compiling
> #See \`config.log' for more details." "$LINENO" 5; }
> #else
15763,15767c15763,15767
< { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
< $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
< as_fn_error "cannot run test program while cross compiling
< See \`config.log' for more details." "$LINENO" 5; }
< else
---
> # { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
> #$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
> #as_fn_error "cannot run test program while cross compiling
> #See \`config.log' for more details." "$LINENO" 5; }
> #else

configuration options

CPPFLAGS="-I/data/local/usr/include" LDFLAGS="-L/data/local/usr/lib" ./configure --host=arm-vfp-linux-gnueabi --with-x=no --prefix=/data/local/usr --with-blas=/data/local/usr/lib/blas.a --with-lapack=/data/local/usr/lib/liblapack.a --disable-freetypetest --without-framework-carbon --without-framework-opengl --disable-docs

Actually I cannot set correctly umfpack, cholmod, arpack, fftw and qhull (working on them)

configuration TRICK

I took several days to figure out this trick: even if I disable "native graphics", opengl and "carbon framework" I got errors dealing with Linux X-Windows System...

Finally, I removed from two lines in config.status script (generated with the previous command) any reference to X_WINDOWS:

-DHAVE_X_WINDOWS=1

and

D["HAVE_X_WINDOWS"]=" 1"

And I relaunched immediately config.status to propagate these options:

./config.status

compiler time

make
make install

Yes... That's All :rolleyes:

Chapter 4 - Post Install tweaks

I decided to compile octave with shared libraries to avoid very huge binaries...

...So, first of all, I strip unwanted debug symbols from all libraries and binaries, saving about 200Mb...

arm-vfp-linux-gnueabi-strip --strip-unneeded /data/local/usr/lib/octave-3.2.4/*
arm-vfp-linux-gnueabi-strip --strip-unneeded /data/local/usr/lib/* 2>/dev/null
arm-vfp-linux-gnueabi-strip --strip-debug /data/local/usr/bin/* 2>/dev/null

Now I must deal with libraries who want references to my cross toolchain inside my PC..

using a program called patchelf I check binaries and libraries one by one changing links from my PC to the generic /data/local/usr wherever it is... :cool:

patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/libz.so.1.2.6
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/libc.so.6
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/libdl.so.2
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/libm.so.6
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/libgcc_s.so.1
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/libstdc++.so.6
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/libpthread.so.0
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/liblzma.so.5.0.3
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/libform.so.5.9
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/libmenu.so.5.9
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/libncurses.so.5.9
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/libpanel.so.5.9
patchelf --set-rpath /data/local/usr/lib /data/local/usr/bin/clear
patchelf --set-rpath /data/local/usr/lib /data/local/usr/bin/infocmp
patchelf --set-rpath /data/local/usr/lib /data/local/usr/bin/tabs
patchelf --set-rpath /data/local/usr/lib /data/local/usr/bin/tic
patchelf --set-rpath /data/local/usr/lib /data/local/usr/bin/toe
patchelf --set-rpath /data/local/usr/lib /data/local/usr/bin/tput
patchelf --set-rpath /data/local/usr/lib /data/local/usr/bin/tset
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/libgfortran.so.3
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/libfftw3.so.3.3.1
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/libglpk.so.0.32.0
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/libqrupdate.so.1
patchelf --set-rpath /data/local/usr/lib /data/local/usr/bin/qconvex
patchelf --set-rpath /data/local/usr/lib /data/local/usr/bin/qdelaunay
patchelf --set-rpath /data/local/usr/lib /data/local/usr/bin/qhalf
patchelf --set-rpath /data/local/usr/lib /data/local/usr/bin/qhull
patchelf --set-rpath /data/local/usr/lib /data/local/usr/bin/qvoronoi
patchelf --set-rpath /data/local/usr/lib /data/local/usr/bin/rbox
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/libpcre.so.1.0.0
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/libpcrecpp.so.0.0.0
patchelf --set-rpath /data/local/usr/lib /data/local/usr/bin/octave-3.2.4
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/octave-3.2.4/libcruft.so.3.2.4
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/octave-3.2.4/liboctinterp.so.3.2.4
patchelf --set-rpath /data/local/usr/lib /data/local/usr/lib/octave-3.2.4/liboctave.so.3.2.4

After that I remove symbolic links, not needed on Android while not compiling there anything else (...for now...), some static libraries and duplicates not needed too:

rm /data/local/usr/lib/libz.a
rm /data/local/usr/lib/libz.so
rm /data/local/usr/lib/libz.so.1
mv /data/local/usr/lib/libz.so.1.2.6 /data/local/usr/lib/libz.so.1
rm /data/local/usr/lib/liblzma.{a,la}
rm /data/local/usr/lib/liblzma.so
rm /data/local/usr/lib/liblzma.so.5
mv /data/local/usr/lib/liblzma.so.5.0.3 /data/local/usr/lib/liblzma.so.5
rm /data/local/usr/lib/lib{form,form_g,menu,menu_g,ncurses++,ncurses,ncurses_g,panel,panel_g}.a
rm /data/local/usr/lib/libform.so
rm /data/local/usr/lib/libform.so.5
mv /data/local/usr/lib/libform.so.5.9 /data/local/usr/lib/libform.so.5
rm /data/local/usr/lib/libmenu.so
rm /data/local/usr/lib/libmenu.so.5
mv /data/local/usr/lib/libmenu.so.5.9 /data/local/usr/lib/libmenu.so.5
rm /data/local/usr/lib/libncurses.so
rm /data/local/usr/lib/libncurses.so.5
mv /data/local/usr/lib/libncurses.so.5.9 /data/local/usr/lib/libncurses.so.5
rm /data/local/usr/lib/libpanel.so
rm /data/local/usr/lib/libpanel.so.5
mv /data/local/usr/lib/libpanel.so.5.9 /data/local/usr/lib/libpanel.so.5
rm /data/local/usr/lib/lib{history,readline}.a
rm /data/local/usr/lib/libhistory.so
rm /data/local/usr/lib/libhistory.so.6
mv /data/local/usr/lib/libhistory.so.6.2 /data/local/usr/lib/libhistory.so.6
rm /data/local/usr/lib/libreadline.so
rm /data/local/usr/lib/libreadline.so.6
mv /data/local/usr/lib/libreadline.so.6.2 /data/local/usr/lib/libreadline.so.6
rm /data/local/usr/lib/libfftw3.{a,la}
rm /data/local/usr/lib/libfftw3.so
rm /data/local/usr/lib/libfftw3.so.3
mv /data/local/usr/lib/libfftw3.so.3.3.1 /data/local/usr/lib/libfftw3.so.3
rm /data/local/usr/lib/libglpk.{a,la}
rm /data/local/usr/lib/libglpk.so
rm /data/local/usr/lib/libglpk.so.0
mv /data/local/usr/lib/libglpk.so.0.32.0 /data/local/usr/lib/libglpk.so.0
rm /data/local/usr/lib/libpcre.{a,la}
rm /data/local/usr/lib/libpcrecpp.{a,la}
rm /data/local/usr/lib/libpcreposix.{a,la}
rm /data/local/usr/lib/libpcre.so
rm /data/local/usr/lib/libpcre.so.1
mv /data/local/usr/lib/libpcre.so.1.0.0 /data/local/usr/lib/libpcre.so.1
rm /data/local/usr/lib/libpcrecpp.so
rm /data/local/usr/lib/libpcrecpp.so.0
mv /data/local/usr/lib/libpcrecpp.so.0.0.0 /data/local/usr/lib/libpcrecpp.so.0
rm /data/local/usr/lib/libpcreposix.so
rm /data/local/usr/lib/libpcreposix.so.0
mv /data/local/usr/lib/libpcreposix.so.0.0.0 /data/local/usr/lib/libpcreposix.so.0
mv /data/local/usr/lib/octave-3.2.4/* /data/local/usr/lib
rmdir /data/local/usr/lib/octave-3.2.4/
rm /data/local/usr/lib/libcruft.so
mv /data/local/usr/lib/libcruft.so.3.2.4 /data/local/usr/lib/libcruft.so
rm /data/local/usr/lib/liboctave.so
mv /data/local/usr/lib/liboctave.so.3.2.4 /data/local/usr/lib/liboctave.so
rm /data/local/usr/lib/liboctinterp.so
mv /data/local/usr/lib/liboctinterp.so.3.2.4 /data/local/usr/lib/liboctinterp.so
chmod 0644 /data/local/usr/lib/lib*
chmod 0755 /data/local/usr/lib/ld-linux.so.3

wow... did I really do this? I don't believe it... :eek:

Chapter 5 - Final stuffs and packaging

I created a really simple bash script to use like a wrapper for the octave binary:

echo '#!/system/bin/sh' > /data/local/octave.sh
echo "export HOME=/data/local/tmp" >> /data/local/octave.sh
echo "/data/local/usr/lib/ld-linux.so.3 /data/local/usr/bin/octave" >> /data/local/octave.sh
chmod 0755 /data/local/octave.sh

This wrapper is mandatory! I don't want to change the phone behaviour changing libraries path and similar environment variables... I could make unusable something else already installed on the phone...

I prefer to call the binary with this command

/data/local/usr/lib/ld-linux.so.3 /data/local/usr/bin/octave

and after that any binary or Library perfectly knows where to find what needed: /data/local/usr

root permissions and packaging

I issued these commands from my PC as superuser fixing octave permissions to the phone "shell" user... I'll use it later on the phone...

chown -R 2000:2000 /data/local/usr
chown -R 2000:2000 /data/local/octave.sh
cd /data/local
tar -cpf octave.tar octave.sh usr/
gzip octave.tar
chown -R 2000:2000 /data/local/octave.tar.gz

Finally I copy the archive onto the Sdcard

adb push /data/local/octave.tar.gz /sdcard/

and from there I install in the right place (rooted phone needed here!) with these "adb shell" commands:

$ su
# cd /data/local
# tar xpf /sdcard/octave.tar.gz
# exit
$

Chapter 6 - Daily usage

from "adb shell" or "Terminal Emulator" (no root needed anymore) I simply call the wrapper:

$ [b]/data/local/octave.sh[/b]
[color=gray]GNU Octave, version 3.2.4
Copyright (C) 2009 John W. Eaton and others.
This is free software; see the source code for copying conditions.
There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. For details, type `warranty'.

Octave was configured for "arm-vfp-linux-gnueabi".

Additional information about Octave is available at http://www.octave.org.

Please contribute if you find this software useful.
For more information, visit http://www.octave.org/help-wanted.html

Report bugs to <bug@octave.org> (but first, please read
http://www.octave.org/bugs.html to learn how to write a helpful report).

For information about changes from previous versions, type `news'.

octave:1> [/color]

:cool:

This is the link to the last version of the binary (140Mb huge)