These classnotes are depreciated. As of 2005, I no longer teach the classes. Notes will remain online for legacy purposes

UNIX01/Application Building Under UNIX

Classnotes | UNIX01 | RecentChanges | Preferences

As we have seen, traditionally UNIX applications are distributed as source. The main reason for this, and the reason it has persisted, is because UNIX implimentations are vendor specific. A library version installed on some path under UNIX A may not be the same version or installed in the same path under UNIX B. Applications distributed as source with clever install and build scripts can adapt as needed when installed on practically and arbitrary UNIX.

  • If you wonder why this is, recall the debate about whether to use /usr for userspace applications and /home for home directories or to use /opt for userspace applications and /usr# for home directories.

The one problem with this model is that there are many different ways to write build scripts, so one project might not build quite like the other.

That being said, there is one method which is used most commonly with only minor variations. Thus, once you've learned the fundamentals of it, you will be able to easily build and install the vast majority of the applications out there.

gcc, g++, f77, etc

One of the most liberating strengths UNIX systems generally have is a wide variety of computer language compilers already included with the system. Compilers for everything from C, C++, Objective-C, Fortran, Java Bytecode, etc., can be found in a modern UNIX system.

This is not only a plus for application developers (who needn't spend additional time, effort and money tracking down and buying the compilers they need), it is very helpful to the system administrator who must have version X of application Y and doesn't want to wait for their UNIX vendor to ship it to them.

The most common suite of compilers come from the GNU project (which should come as no surprise) in the form of the GNU Compiler Collection (GCC, http://gcc.gnu.org/). The GNU Compiler Collection contains front ends for C, C++, Objective-C, Fortran, Java, and Ada, as well as libraries for these languages.

This compiler collection can be optimized for many different architectures (especially Intel-class machines) which can result in zippy binaries that are tightly integrated with your hardware.

We will now briefly examine each of the elements of the GCC group. For more information than we will cover here, consult the GCC man and info pages.

gcc

gcc is the front end for the C programming language. gcc originally was the only compiler in this collection, and stood for "GNU C Compiler". If I had a C program "program_a.c" and I wished the compile a binary from it, I would issue:
 gcc -o program_a program_a.c

  • PROJECT - Build a simple C application.
Enter the following in an editor and save it as "hello.c". Then build it using gcc as specified above.
      #include <stdio.h>
      int main() {
           printf("Hello World\n");
      }

g++

g++ is the front end for the C++ programming language. It accepts the same command-line options as gcc above.

g77

g77 is the FORTRAN compiler of the GCC collection. Believe it or not, there are still many perfectly good FORTRAN programs out there, and if you ever administrate a UNIX box in a Physics or Engineering environment, chances are you will still have people wanting to use it. Again, it uses much of the same command-line options as gcc.

gcj

gcj is the GNU compiler for Java. It can generate both .class and object files as well as read both Java source and .class files. Again, it uses much of the same command-line options as gcc.

gnat

gnat the GNU compiler for Ada. I personally don't know of many places beyond crusty old military installations that still use Ada... But I'll admit I haven't really looked. Again, it uses much of the same command-line options as gcc.

make

As you can imagine, simply using the compilers above would not make your life any easier when compiling some of the larger UNIX applications. For a project such as the Linux kernel or Mozilla you could easily have hundreds of source code files. Obviously, it is not feasable to have to compile each file by hand:
 # gcc -o parport_cs parport_cs.c
 # gcc -o parport_serial parport_serial.c
 # gcc -o parport_pc parport_pc.c
 ...

For this reason, tools such as make were created. make reads a kind of script (called a Makefile) and proceeds to build an application based upon rules in that script.

Makefile creation is well beyond what we will be doing in this class, however, for an excellent overview of it, take a look at "Linux Programmer's Reference" by Richard Petersen.

All that we need to concern ourselves with is the fact that if in a directory we have a Makefile:

 sam@rygel:~/incoming/src/temp/wmcalc-0.3$ ls -l
 total 72
 -rw-r--r--  1 sam   sam        433 Dec 10  2000 Makefile
 -rw-r--r--  1 sam   sam       1864 Nov  5  2000 readln.c
 -rw-r--r--  1 sam   sam      28999 Jan 17  2001 wmcalc.c
 -rw-r--r--  1 sam   sam      14920 Nov  9  2000 wmcalcfunc.c
 -rw-r--r--  1 sam   sam      14603 Nov  9  2000 wmcalcswitch.c

we can usually compile everything in that directory by issuing a simple 'make' command:

 $ make

and then install it with the command

 $ make install

Later, we may be able to uninstall it with

 $ make uninstall

However, there are several methods for automating the build process, and there is no real set standard. Makefiles and an autoconf process (which we will look at shortly) are the most common, but are by no means a "standard".

Thus, application developers generally put a README or possibly an INSTALL file (or even both) inside their application archive. It is very important to first check the archive and read any relevant files before attempting to build an application.



Classnotes | UNIX01 | RecentChanges | Preferences
This page is read-only | View other revisions
Last edited July 26, 2003 12:27 am (diff)
Search:
(C) Copyright 2003 Samuel Hart
Creative Commons License
This work is licensed under a Creative Commons License.