The Android/Linux:junction

13.1 The Android/Linux:junction

Applications for Android/Linux are markedly different from applications con- structed with the Android SDK. Applications built with Eclipse and the context-sensitive Java syntax tools make for a comfortable learning environment. In line with the spirit of Linux development, from here on out all development takes place with command- line tools and nothing more sophisticated than a text editor. While the Eclipse environ- ment could certainly be leveraged for non-Java development, the focus of this chapter is on core C language coding for Android/Linux. The first place to start is with the cross- compiling tool chain required to build Android/Linux applications.

13.1.1 Tool chain Building applications for Android/Linux requires the use of a cross-compiler tool

chain from CodeSourcery. The specific version required is the Sourcery G++ Lite Edi- tion for ARM, found at http://www.codesourcery.com/gnu_toolchains/arm/portal/ package2548?@template=release . Once installed, the Sourcery G++ tool chain con- tributes a number of useful tools to assist in the creation of applications targeting Linux on ARM, which is the architecture of the Android platform. The ARM platform is a 32-bit reduced instruction set computer (RISC) processor, used in numerous devices including smartphones, PDAs, and technology appliances such as low-end routers and disk drive controllers. The CodeSourcery installation comes with a fairly comprehensive set of PDF documents describing the main components of the tool chain, including the C compiler, the assembler, the linker, and many more tools. A full discussion of these versatile tools is well beyond the scope of this chapter; however, three tools in particular are demonstrated in the construction of this chapter’s sample applications. We will be using these tools right away, so we briefly introduce them in this section.

The first and most important tool introduced is gcc. This tool is the compiler responsible for turning C source files into object files and optionally initiating the link process to build an executable suitable for the Android/Linux target platform. The full name of the gcc compiler for our cross-compilation environment is arm-none- linux-gnueabi-gcc. This tool is invoked from the command line of the development

The Android/Linux:junction

machine. The tool takes command-line arguments of one or more source files along with zero or more of the numerous available switches.

The linker, arm-none-linux-gnueabi-ld, is responsible for producing an executable application for our target platform. When performing the link step, object code along with routines from one or more library files are combined into a relocatable, execut- able binary file, compatible with the Android Emulator’s Linux environment. While a simple application may be compiled and linked directly with gcc, the linker is used when creating applications with more than one source file and/or more complex application requirements.

If the linker is responsible for constructing applications from more than one con- tributing component, the object dump utility is useful for dissecting, or disassembling, an application. We introduce the objdump, or arm-none-linux-gnueabi-objdump, tool presently; its usefulness becomes more apparent later in the chapter. This utility examines an executable application—a binary file—and turns the machine instruc- tions found there into an assembly language listing file, suitable for analysis.

NOTE: All of the examples in this chapter take place on a Windows XP worksta- tion. It is also possible to use this tool chain on a Linux development machine.

With this brief introduction behind us, let’s build the obligatory Hello Android appli- cation to run in the Linux foundation of the Android Emulator.

13.1.2 Building an application The first thing we want to accomplish with our journey into Android/Linux develop-

ment is to print something to the screen of the emulator to demonstrate that we are running something on the platform outside the Android SDK and its Java application environment. There is no better way to accomplish this feat than by writing a variant of the Hello World application. At this point, there will be little talk of Android activi- ties, views, or resource layouts. Most code samples in this chapter are in the C lan- guage. Listing 13.1 shows the code listing for our first Hello Android application.

Listing 13.1 Hello.c

#include <stdio.h>

B Standard include file

int main(int argc,char * argv[])

C Application entry point

{ printf("Hello, Android!\n");

D Display a string

return 0; }

Virtually all C language applications require a #include header file containing func- tion definitions, commonly referred to as prototypes. In this case, the application

includes the header file B for the standard input and output routines, stdio.h. The standard C language entry point for user code C is the function named main. The

C HAPTER 13 Hacking Android

function returns an integer return code (a value of zero is returned in this simple example) and takes two arguments. The first, argc, is an integer indicating the num- ber of command-line arguments passed in to the program when invoked. The second, argv , is an array of pointers to null-terminated strings representing each of the com- mand-line arguments. The first argument, argv[0], is always the name of the program executing. This application has but a single useful instruction, printf, which is to

write to standard output (the screen) a textual string D . The printf function is

declared in the header file, stdio.h. To build this application, we employ the gcc tool:

arm-none-linux-gnueabi-gcc hello.c -static -o hellostatic There are a few items to note about this command-line instruction:

The compiler is invoked with the full name arm-none-linux-gnueabi-gcc.

The source file is named hello.c.

The –static command-line switch is used to instruct gcc to fully link all required routines and data into the resulting binary application file. In essence, the application is fully standalone and ready to be run on the target Android Emulator without any additional components. An application that’s statically linked tends to be rather large because so much code and data are included in the executable file. For example, this statically linked application with basically

a single line of code weighs in at 568,231 bytes. Ouch! If this -static switch is omitted, the application is built without any extra routines linked in. In this case the application will be much smaller; however, it will rely on finding com- patible routines on the target system in order to run. For now, we are keeping things simple and building our sample application in such a manner that all support routines are linked statically.

The output switch, -o, is used to request the name of the executable applica- tion to be hellostatic. If this switch is not provided, the default application name is a.out.

Now that the application is built, it’s time to try it out on the Android Emulator. In order to do this we will rely on the adb tool introduced in chapter 2.

13.1.3 Installing and running the application In preparation to install and run the Hello Android

application, let’s take a tour of our build and testing envi- ronment. We need to identify four distinct environ- ments/tools and clearly understand them when building applications for Android/Linux. The first environment to grasp is the big-picture architecture of the Android Emulator running essentially on top of Linux, as shown

Figure 13.1 Android runs

in figure 13.1.

atop a Linux kernel.

The Android/Linux:junction

As presented in the early chapters of this book, there is a Linux kernel running underneath the pretty, graphical face of Android. There exist device drivers, process lists, and memory management, among other elements of a sophisticated operat- ing system.

As shown in the previous section, we need an environment in which to compile our

C code. This is most likely to be a command-prompt window on a Windows machine, or a shell window on a Linux desktop machine, exercising the CodeSourcery tool chain. This is the second environment to be comfortable operating within.

NOTE The CodeSourcery tool chain is not designed to run on the Android/Linux

environment itself, so the development work being done here is consid- ered to be cross compiling. The figures and example code presented in this chapter were taken from a Windows development environment used by the author. There are a number of long path and directory structures in the Android SDK and the CodeSourcery tools. In order to help simplify some of the examples and keep certain command line entries from running over multiple lines some drive mappings were set up. For example a drive letter of “m:” seen in scripts and figures corresponds to the root location of source code examples on the author’s development machine. Likewise the “g:” drive points to the currently installed Android SDK on the author’s development machine. Note that this technique may also be used in Linux of Mac OSX environments with a “soft link” (ln) command.

The next requirement is to copy our newly constructed binary executable application to the Android Emulator. This can be done with a call to the adb utility or by using the DDMS view in Eclipse. Both of these tools were demonstrated in chapter 2. Here is the syntax for copying the executable file to the Android Emulator:

adb push hellostatic /data/ch13 Note a few items about this command:

The command name is adb. This command takes a number of arguments that guide its behavior. In this case, the subcommand is push, which means to copy a file to the Android Emulator. There is also a pull option for moving files from the Android Emulator file system to the local development machine’s hard drive.

After the push option, the next argument, hellostatic in this case, represents the local file, stored on the development machine’s hard drive.

The last argument is the destination directory (and/or filename) for the trans- ferred file. In this sample, we are copying the hellostatic file from the current working directory to the /data/ch13 directory on the Android Emulator.

Be sure that the desired target directory exists first! You can accomplish this with a mkdir command on the adb shell, described next.

The final tool to become familiar with is the shell option of the adb shell. Using this command, we can interact directly on the Android Emulator’s file system with a limited shell environment. To enter this environment (and assuming the Android Emulator is

C HAPTER 13 Hacking Android

already running), execute adb shell from the command line. When invoked, the shell displays the # prompt, just as if you had made a secure shell (ssh) or telnet connection to a remote Unix-based machine. Figure 13.2 shows these steps in action.

Figure 13.2 The build, copy, run cycle

Note the sequence shown in figure 13.2. First the application is built with a call to gcc. Next we push the file over to the Android Emulator. We then connect to the Android emulator via the adb shell command, which gives us the # prompt, indicating that we are now on the shell. Next we change directory (cd) to /data/ch13. Remember that this is Linux, so the application by default may not be executable. A call to chmod sets the file’s attributes, turning on the executable bits and allowing the application to be invoked. Lastly, we invoke the application with a call to ./hellostatic. The search path for executable applications does not by default include the current directory on a Linux system, so we must provide a more properly qualified path, which explains the ./ prefix. Of course, we can see that our application has run successfully because we see the “Hello, Android!” text displayed on the screen.

Congratulations! We have a successful, albeit simple, Android/Linux application running on the Android Emulator. In the next section, we take a quick look at stream- lining this build process.

13.1.4 Build script In the last section we reviewed each step in building and preparing to test our applica-

tion. Due to the rather tedious nature of executing each of these steps, we have a strong desire to utilize command-line tools when building C applications, as it greatly speeds up the edit, compile, copy, debug cycle. This example with only a single C source file is rather simplistic; however, when multiple source files must be linked together, the thought of having a build script is very appealing. The need for a build

A better way

script is particularly evident where there are numerous source files to compile and link, as we will encounter later in this chapter.

Listing 13.2 shows the build script for our Hello Android application. Listing 13.2 Build script for Hello Android, buildhello.bat

arm-none-linux-gnueabi-gcc hello.c -static -o hellostatic

B Compile and link

g:\tools\adb push hellostatic /data/ch13

C Copy file

g:\tools\adb shell "chmod 777 /data/ch13/hellostatic"

D Change permissions

A call to arm-none-linux-gnueabi-gcc B compiles the source file, hello.c. The file is stat-

ically linked against the standard C libraries, and the resulting binary executable file is

written out as hellostatic. The file hellostatic is copied to the Android Emulator C and placed in the directory /data/ch13. The permissions for this file are changed D ,

permitting execution. Note the use of the adb shell with a quote-delimited command. Once this command executes, the adb application exits and returns to the Windows command prompt.

This example can be extended to perform other build steps or cleanup proce- dures such as removing temporary test data files on the Android Emulator or any sim- ilarly helpful tasks. As you progress, it will become clear what commands to put into your build script to make the testing process more efficient.

Now that the pressure is off—we have successfully written, built, and executed an application in the Android/Linux environment—it is time to deal with the problem- atic issue of a simple application requiring a file size of half a megabyte.