The iPhone can run “web apps” very easily. These web apps are really just specially-crafted web pages that take advantage of the iPhone’s built-in web browser. Such web apps can be very cool, but they don’t provide the full functionality that you can get from an actual executable program running on the iPhone. A “native app” that runs on the iPhone can read the iPhone’s built-in accelerometer, for example.
So lots of people want to write independent/third-party native apps that run on the iPhone. The problem is that while Apple hasn’t squashed the development of native apps, they haven’t helped, either. For example, Apple hasn’t provided a toolchain to compile programs for the iPhone.
What is a toolchain?
Yeah, I know, it’s been I while since I had my compiler class too. Here’s a rough diagram of what happens when you compile source code into a program:
Here’s the process as I recall it. You write code in high-level computer languages such as C, C++, or Objective-C. That gets piped through a compiler (“gcc” in this diagram), which creates assembly code targeted for a certain type of machine architecture such as Intel x86, PowerPC (PPC), or ARM. Most desktop machines, including newer Apple computers, use Intel or Intel-compatible chips. Older Apple computers use PowerPC chips. ARM chips are embedded in lots of popular consumer electronics devices (e.g. the iPod and iPhone).
Now you’ve got assembly code for a particular type of computer chip. That code is processed through an assembler (“as” in this diagram), which spits out actual machine code (also called “object code”) of zeros and ones. In some cases that code can be executed directly. However, usually you have multiple files of object code to combine, or you need to link in built-in functions from system libraries. A linker (“ld” in this diagram) pulls all the object code into one executable program that a user can run.
So what is a toolchain? Roughly, a toolchain is a set of programs that allow you to compile source code into a program. It can include the programs that I just mentioned, plus a host of other programs such as “make” or a debugger that make compiling programs easier.
What is a cross-compiler?
Look back at the diagram above. Typically someone on (say) a newer Apple computer would have an Intel chip inside. So gcc would output assembly code for an Intel chip, and that assembly code would eventually be transformed into an executable program that runs on a Intel chip. That lets you compile and run programs on your own computer.
But nothing in the diagram above says that you have to output assembly code for the same type of computer chip as the machine that you’re running. For example, an Intel-based Apple computer could translate source code into assembly code for an ARM-based machine architecture. That’s called “cross-compiling,” because you’re compiling your code across for a different type of chip.
Why would you want to cross-compile anything? Well, iPods and iPhones are based on ARM chips. Can you imagine trying to compile source code on one of those little devices? It would be a real pain. Cross-compiling solves that problem: you can compile code on a desktop machine for (say) the iPhone, then figure out how to copy your executable program over to the iPhone, and figure out some way to run your program.
What does this have to do with the iPhone?
It’s possible (but currently difficult) to make a working toolchain for Apple computers that cross-compiles code so that the iPhone can run it. Once you have a cross-compiling toolchain, you can write code that runs on the iPhone.
Unfortunately, Apple hasn’t provided any documentation on the application programming interface (API) or system libraries that would allow people to write native applications for the iPhone. Luckily, dedicated people have helped to produce not only a toolchain but also to fill in documentation on the system APIs that the iPhone supports. In the same way that Apple desktop machines have a framework called AppKit, the iPhone has a user-interface (UI) framework called UIKit.
More reading about toolchains/cross-compiling
If you dig deeper into nearly anything I just said about toolchains or cross-compiling, you’ll discover that it’s more complicated than I just laid out. For example, libraries of built-in system functions don’t have to be statically combined into a program. It’s possible to wait until the program is being loaded to execute before linking in a library. And so-called “binutils” provide lots of functionality other than compilation. For an overview of the compilation process, see the book Running Linux for a good description. To learn about linking vs. loading, I enjoyed this Linux Journal article. You can read more about GCC or binutils on the official GNU site. And of course Wikipedia provides a variety of strong articles about the GNU tool chain, linkers, and crosscompiling.