Introduction:
I just got a new G1 Android phone, and since it runs Linux I just had to get the Bash shell running on it, the built in shell would just not do. I do need my tab completion after all. Cross compilation is the process of compiling software on one platform that is meant to run on another. With the following an ARM executable is compiled on a x86 Linux machine.
Requirements (Not sure if all this is needed, but it is what I used):
- Cupcake 1.5 JS Build with root access: http://androidandme.com/2009/05/guides/beginners-guide-for-rooting-your-android-g1-to-install-cupcake/
- ARM Toolkit (The Cross Compiler): http://www.codesourcery.com/gnu_toolchains/arm/download.html
- Android SDK installed on Linux: http://developer.android.com/sdk/1.5_r2/index.htm
- A G1
- The source code for Bash 4.0: ftp://ftp.cwru.edu/pub/bash/bash-4.0.tar.gz
Step 1: Connect your pc to your phone with the SDK
You first have to be able to connect to your computer with adp which is included with the sdk. To do this with Ubuntu Januty Jackalope you first need to create a /etc/udev/rules.d/51-android.rules file with the following contents:
SUBSYSTEM=="usb", SYSFS{idVendor}=="0bb4", MODE="0666"
After this run the following to restart udev: ‘sudo /etc/init.d/udev reload’. Lastly, on your phone make sure Settings :: Applications :: Development :: USB Debugging is enabled and the plug in your phone. When you run ‘./adp devices’ you should see a device listed.
Step 2: Build the Bash Shell
After installing ARM toolkit in /home/kbrandt/bin/arm-toolkit (used for this example) set the following environment variables in your shell.
CC='/home/kbrandt/bin/arm-toolkit/bin/arm-none-linux-gnueabi-gcc' PATH="$PATH:$HOME/bin/"
Then cd to the directory where you extracted the Bash source and run the following:
./configure --prefix=/opt/arm_bash/ -host=arm-linux --enable-static-link --without-bash-malloc
Assuming that worked, edit the ‘Makefile’ file and change ‘CFLAGS = -g -O2′ to ‘CFLAGS = -g -O2 -static’ and then run ‘make’. If this works, it should create a bash executable in the current directory. You can verify that this has been compiled for the ARM architecture with ‘file bash’. This should return:
bash: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.14, not stripped
Step 3: Copy the File to your android.
From the host computer in the tools directory of the SDK run ‘./adb push ~/src/bash-4.0/bash /data/’ to copy the executable to the phone. If you try to copy it to your sdcard, make sure the sdcard is not mounted with the noexec mount option as this disables the executable permission bit.
Step 4: Run, Enjoy, and Find Bugs.
You can now connect to your phone with ‘./adp shell’ and cd to the data directory and run ‘./bash’ and you should get a bash prompt. You might need to ‘chmod 555 bash’ if you get permission denied.
References:
http://jiggawatt.org/badc0de/android/index.html
Thanks for the tutorial.
I had to change some commands to get it to compile.
The CC en PATH was useless. And I used a modified ./configure command:
./configure –prefix=/opt/arm_bash/ –build=i686-pc-linux-gnu –host=arm-linux –enable-static-link –without-bash-malloc CC=/home/chris/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-linux-gnueabi-gcc
What might be good to know too, is that you need the cross compiler for GNU/Linux from Code Sourcery.
im currently trying to cross compile the glasgow haskell compiler for android. due to not really being familiar with linux i tried to apply your instructions to the windows version of the code sourcery g++ tool. well… didn’t work out. you dont happen to know how to conduct the second step in windows? thanks!
Thanks alot, Kyle & Qistoph. An amalgamation of both your methods worked for me. I’m going to try and compile links next
Mostly helpful and thank you!
Watch out if you copy and paste Qistoph’s ./configure options, those are not dashes!
The ./configure routine works great if you make a symlink to the compiler:
$ ls -l `which arm-linux-gcc`
lrwxrwxrwx 1 root root 74 Mar 30 17:29 /usr/bin/arm-linux-gcc -> /home/matter/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-linux-gnueabi-gcc
Then you don’t need to fuss around with the Makefile at all.
Tested on bash-4.0 and bash-4.1, but bash-4.2 throws this error:
$ make
***********************************************************
* *
* GNU bash, version 4.2.0(1)-release (arm-unknown-linux-gnu)
* *
***********************************************************
rm -f execute_cmd.o
arm-linux-gcc -DPROGRAM=’”bash”‘ -DCONF_HOSTTYPE=’”arm”‘ -DCONF_OSTYPE=’”linux-gnu”‘ -DCONF_MACHTYPE=’”arm-unknown-linux-gnu”‘ -DCONF_VENDOR=’”unknown”‘ -DLOCALEDIR=’”/opt/arm_bash/share/locale”‘ -DPACKAGE=’”bash”‘ -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -g -O2 -c execute_cmd.c
execute_cmd.c: In function ‘execute_in_subshell’:
execute_cmd.c:1507:5: warning: passing argument 1 of ‘execute_command_internal’ discards qualifiers from pointer target type
execute_cmd.c:522:1: note: expected ‘struct COMMAND *’ but argument is of type ‘volatile struct COMMAND *’
execute_cmd.c: In function ‘execute_pipeline’:
execute_cmd.c:2205:23: error: ‘job_control’ undeclared (first use in this function)
execute_cmd.c:2205:23: note: each undeclared identifier is reported only once for each function it appears in
execute_cmd.c: In function ‘execute_function’:
execute_cmd.c:4243:3: warning: passing argument 1 of ‘array_rshift’ discards qualifiers from pointer target type
array.h:56:12: note: expected ‘struct ARRAY *’ but argument is of type ‘volatile struct ARRAY *’
execute_cmd.c:4245:3: warning: passing argument 1 of ‘array_rshift’ discards qualifiers from pointer target type
array.h:56:12: note: expected ‘struct ARRAY *’ but argument is of type ‘volatile struct ARRAY *’
execute_cmd.c:4320:3: warning: passing argument 1 of ‘array_shift’ discards qualifiers from pointer target type
array.h:55:23: note: expected ‘struct ARRAY *’ but argument is of type ‘volatile struct ARRAY *’
execute_cmd.c:4321:3: warning: passing argument 1 of ‘array_shift’ discards qualifiers from pointer target type
array.h:55:23: note: expected ‘struct ARRAY *’ but argument is of type ‘volatile struct ARRAY *’
make: *** [execute_cmd.o] Error 1
Have fun!
Hi, Thanks for very useful guide. I’m trying to do this, using bash 4.2 sources and the codesourcery compiler compiled from this source package:
http://www.codesourcery.com/sgpp/lite/arm/portal/package8738/public/arm-none-linux-gnueabi/arm-2011.03-41-arm-none-linux-gnueabi.src.tar.bz2
The bash compile is failing on:
execute_cmd.c:2205:23: error: ‘job_control’ undeclared (first use in this function)
and I can’t find the necessary library anywhere to provide the function nor does disabling job-control in the bash config help.
Does anyone know how to solve this?
Cheers!
UPDATE:
It seems that only bash 4.2 has this problem. 4.1 compiled without issues.
Cheers!
Hi,
Really looks a nice tutorial. I am gonna try this to cross compile bash for my android phone.
Just one typo I have noticed, you have menioned “adp” some place instead of “adb”.
Thanks,
Amar
Thanks for posting. I just used this method to compile tar. But because there were multiple makefiles, instead of adding -static to each makefile, I just did
CC=’arm-none-linux-gnueabi-gcc -static’ ./configure [other options]
That did it everywhere.
You might want to see the updated instructions to compile latest BASH on Android:
http://www.compdigitec.com/labs/2011/09/04/compiling-bash-for-android-2-x/
Found it through Google, it works perfect.