[Penguin Logo]

Linux for Newbies, pt. 22:
Installing Packages from Source

by Gene Wilburn

(The Computer Paper, May 2001. Copyright © Wilburn Communications Ltd. All rights reserved)


"Rolling your own" software was once the main way to add new programs and packages to a Linux system. Grab a tarball, untar it, configure, compile and install. This is the "classic" way to add new stuff to a system and there are times, as we'll see in this installment, when it's still the best.

Back in Part 17 we learned how to install and remove packages using the RPM package manager. RPM and its Debian GNU/Linux counterpart, DEB, have made installing and removing software very simple. Given the large number of packages in a modern distribution, installing and removing binaries with package managers has become an accepted convenience.

Convenience, however, can lead to dependence. Once you form a dependency on pre-rolled packages, you give up a considerable amount of decision making to the maintainers of the packages. You take it on trust that they know what they're doing. Most of the time this works out, but if you ever encounter one of the "RPMs from hell" you'll think twice about the wisdom of accepting RPM's blindly.

In general, if you use a Red Hat or Mandrake system, and obtain "official" RPM's from Red Hat or Mandrake, you won't have too many surprises. But contributed RPM's are a crapshoot. They can be superb or downright stupid and ill-conceived.

Another problem with RPM's, even good ones, is that they frequently don't install files where you think they belong. I take issue with Red Hat, for instance, for putting the Apache web server's doctree and cgi-bin in /home under /home/httpd. Red Hat also scatters the Apache binaries around the file system and it does not even use Apache's own apachectl control program. If you already know how to admin an Apache web server, the Red Hat implementation is confusing, non-standard and illogical.

Should you care where things go as long as everything works? Of course you should care! Linux is about attitude and paying attention to details is part of that attitude. Not that everyone shares the same opinion about file locations. Flame wars often break out over where things should be located on a Linux filesystem and there is no absolute standard that every distribution adheres to. But you should at least have some logical preferences.

The way around RPM issues is to grab source code for the key products that matter the most to you and do your own installation. It would be extreme to do this with all packages, but there are certain packages for which hand compiling makes more sense than installing binary packages via RPM or DEB.

"Use the Source, Luke"

For example, if you're using Linux to run an Apache website, you're better off compiling Apache and any related modules by hand. This gives you greater control of how the package is compiled and you can choose your own locations for the parts. You will also find it's easier to keep Apache and modules, such as PHP, up to date if you use source. Whenever there's a new version or a patch, you just grab the source, recompile, and it's done. Waiting around for someone to create a new RPM is gormless.

So what we're going to do in this installment is to put on our Unix hardhats, grab our metal lunch buckets, de-install the Apache and PHP that Red Hat puts on the system, and re-do the installation from source. It's really not hard at all and it's a valuable Linux skill.

De-Installing Apache and PHP

A quick word about de-installing RPM's. When a package is removed, the RPM doesn't normally remove any data associated with the package. Hence, if you already have some website material under /home/httpd/html it will still be there afterwards and can be moved to its new location. However, it is always prudent to do a backup first, just in case.

As you may recall from pt. 17, we de-install with the "rpm -e" command. However, when I attempt to deinstall PHP from my stock Red Hat 6.2 system I get the following:

    # rpm -e php
    error: removing these packages would break dependencies:
            php is needed by piranha-gui-0.4.14-1
            php = 3.0.17 is needed by php-imap-3.0.17-1.6.2
            php = 3.0.17 is needed by php-ldap-3.0.17-1.6.2
            php = 3.0.17 is needed by php-manual-3.0.17-1.6.2
            php = 3.0.17 is needed by php-pgsql-3.0.17-1.6.2
    

What I have to do is deinstall each dependency separately:

    # rpm -e php-pgsql
    # rpm -e php-manual
    # rpm -e php-ldap
    # rpm -e php-imap
    # rpm -e piranha-gui
    # rpm -e php
    

When I deinstall Apache I must similarly get rid of mod_perl first:

    # rpm -e apache
    error: removing these packages would break dependencies:
            webserver is needed by mod_perl-1.23-3
    
    # rpm -e mod_perl
    # rpm -e apache
    cannot remove /var/log/httpd - directory not empty
    cannot remove /home/httpd/html - directory not empty
    cannot remove /home/httpd/cgi-bin - directory not empty
    cannot remove /home/httpd - directory not empty
    cannot remove /etc/httpd/conf - directory not empty
    

The "cannot remove" messages are good messages that say my existing webfiles and configuration files are not being removed.

Obtaining Source

To obtain source code, you simply go to the website that houses the code, find the download section, and download the source packages (frequently called "tarballs") into a directory. I prefer to download source code into /usr/local/src. Hence I fire up Netscape (or Lynx) and first to go www.apache.org, then to www.php.net and download the following files to /usr/local/src:

    # ls -l *gz
    -rw-rw-r-- 1 root   root    1928677 Mar  3 19:22 apache_1.3.19.tar.gz
    -rw-rw-r-- 1 root   root    2439189 Mar  3 19:24 php-4.0.4pl1.tar.gz
    

Notice that both files end in ".tar.gz". This indicates Unix tar files that have been compressed using gzip (GNU Zip is unrelated to WinZIP). The next step is to unzip the files, then untar them. This can actually be done in a single step but for the first time out let's do each step manually:

    # gunzip *.gz
    # tar xvf apache*.tar
    # tar xvf php*.tar
    

You will see a lot of screen activity as these packages are untar'd into their respective directories. You can now remove the .tar files--they're no longer needed:

    # rm -i *.tar
    rm: remove `apache_1.3.19.tar'? y
    rm: remove `php-4.0.4pl1.tar'? y
    

Now issue "ls -l" to see the directories that were created:

    # ls -l
    drwxr-xr-x   8 1086   1086       4096 Feb 26 17:17 apache_1.3.19
    drwxr-xr-x  13 510    users      4096 Jan 11 18:39 php-4.0.4pl1
    

We will be working in these two directories. If you wish, you can first tidy up the ownership of these files and directories with the command:

    # chown -R root.root /usr/local/src/*
    

Compiling from Source

Let's visit Apache first. Before we get started we should give some thought to where we want Apache binaries and files to live. If your Linux server is an active webserver, you may prefer a directory such as /var/www or even /www for your Apache site. I personally like /usr/local, the traditional Unix place to put things that are "localized"--software that is not part of the base operating system. Hence I am going to use /usr/local/apache as my destination.

Use a "cd" command to put yourself into the Apache directory. Remember, you only need to type a bit of it, then hit TAB for filename completion, e.g. "cd apach[TAB][ENTER]". Take a look at what's inside:

    # pwd
    /usr/local/src/apache_1.3.19
    
    # ls -F
    ABOUT_APACHE      Makefile.tmpl     cgi-bin/          icons/
    Announcement      README            conf/             logs/
    INSTALL           README-WIN.TXT    config.layout     src/
    KEYS              README.configure  configure*
    LICENSE           WARNING-WIN.TXT   htdocs/
    

The "ls -F" command shows a very typical source code directory structure with source directory (src/) plus additional material (such as conf/ and htdocs/). There are some key files in the top directory: README, INSTALL and configure. The README and INSTALL files are essential reading. They give you the compile instructions and options.

The README file, for instance, let's us know that there are two different ways to install Apache:

     Installation
      ------------
    
      From Apache version 1.3 and up you have two possibilities to
      build and install the Apache package: The old commonly known
      but manual way from Apache 1.2 and below and the new
      out-of-the-box way through the new Apache Autoconf-style
      Interface (APACI). For detailed instructions see the file
      INSTALL in this directory.
    

The INSTALL file gives those directions. We'll be using the newer APACI method.

There are three basic steps in building and installing any package from source:

  1. configure
  2. make
  3. make install

In the "configure" step you decide things like which directories to use and which modules to include. The "make" step runs a Make script which takes input from configure, then uses your C compiler to actually compile the source code into binary executables. If the code compiles cleanly, with no errors, you then proceed to "make install", which puts the newly created binaries in their respective directories. You can then test the setup.

For the purposes of this exercise, let's assume that, initially, there are no special modules you want to add to Apache, so let's go with the defaults. Using the backslash "\" to allow us to split long command lines across several lines, let's proceed:

    # ./configure \
    > prefix=/usr/local/apache
    
    Configuring for Apache, Version 1.3.19
     + using installation path layout: Apache (config.layout)
    Creating Makefile
    Creating Configuration.apaci in src
    Creating Makefile in src
     + configured for Linux platform
     + setting C compiler to gcc
     + setting C pre-processor to gcc -E
     + checking for system header files
     + adding selected modules
     + checking sizeof various data types
     + doing sanity check on compiler and options
    Creating Makefile in src/support
    Creating Makefile in src/regex
    Creating Makefile in src/os/unix
    Creating Makefile in src/ap
    Creating Makefile in src/main
    Creating Makefile in src/lib/expat-lite
    Creating Makefile in src/modules/standard
    

As you can see, the configure step did quite a bit of setup work. Now we go to the actual compile, and if this is your first time compiling a program be prepared to see a lot of strange-looking material displayed on your screen. It's all normal and can be explained (in C programming terms) but it's not your everyday kind of messaging. It also takes awhile to complete. The speed of compilation is directly related to the speed of your CPU, but Apache normally doesn't take very long to compile.

The compile step is easy:

    # make
    

When the prompt returns (and there are no errors), finish off with:

    # make install
    

Test your new setup by starting Apache (type the following):

    # /usr/local/apache/bin/apachectl start
    

If Apache starts without errors, you can now test your initial setup. Go to http://localhost/ using your Linux Netscape or Lynx browser. You should see the Apache test page, with a link at the bottom to the local Apache online documentation that gets installed as part of a default installation.

The Apache configuration files (the main one is httpd.conf) reside in /usr/local/apache/conf. The binaries reside in /usr/local/apache/bin and the main website is located in /usr/local/apache/htdocs. Log files are located in /usr/local/apache/logs.

Now let's swing over to PHP by typing:

    # cd /usr/local/src/php-4.0.4pl1
    

As with Apache, PHP has a number of files and subdirectories located in this top level directory, and it has the requisite INSTALL and README files.

The PHP configuration step references the Apache directory via relative pathing:

    # ./configure \
    > --with-mysql \
    > --with-apache=../apache_1.3.19 \
    > --enable-track-vars
    

We're configuring a very lean PHP here, with MySQL support but with no Oracle, PostgreSQL or LDAP support. That's part of the point of compiling from source. You can control exactly what a package supports.

Now that PHP is configured it must be compiled:

    # pwd
    /usr/local/src/php-4.0.4pl1
    
    # make
    # make install
    

Once again the compile cycle will look strange at first, but be patient and wait for it to finish (good time for a coffee break). When it's done, we need to repeat a bit of the work we did for Apache originally because we didn't include PHP the first time:

    # cd ../apache_1.3.19/
    # ./configure \
    > --prefix=/usr/local/apache \
    > --activate-module=src/modules/php4/libphp4.a
    
    # make
     
    # /usr/local/apache/bin/apachectl stop
    
    # cp src/httpd /usr/local/apache/bin
    
    # /usr/local/apache/bin/httpd -l
    Compiled-in modules:
      http_core.c
      ...
      mod_php4.c
    

Notice that this time around we did not type "make install". The make install option is only used the first time we install Apache. After running "make" to create a new binary, we then stopped the Apache server ("apachectl stop"), copied the new binary ("httpd") to the Apache binary directory ("/usr/local/apache/bin"), then ran httpd with the "-l" flag to see which modules are compiled in. There are several but the one we wanted to verify is "mod_php4.c".

Now we just need to edit the Apache httpd.conf file to recognize PHP and we can then set up a test page.

    # cd /usr/local/apache/conf
    # vi httpd.conf
    

In vi or another editor, uncomment the following lines by removing the hash mark "#":

        AddType application/x-httpd-php .php
        AddType application/x-httpd-php-source .phps
    

Then save the file and type:

    # /usr/local/apache/bin/apachectl start
    

We also need to add that last startup command to /etc/rc.d/rc.local if we want Apache to start each time the system is rebooted.

Now the moment of truth! Create the following file, phptest.php, in the directory /usr/local/apache/htdocs

    <html>
    <head>
    <title>PHP Test</title>
    <body>
    
    <?php phpinfo() ?>
    
    </body>
    </html>
    

and set your local Linux browser to http://localhost/phptest.php to see a deep screen of PHP info (see fig. 1)

Nice job! This was a very simple Apache and PHP installation, but once you've nailed down the basics, adding more modules or adjusting the options is just more of the same. On this system, Apache and PHP can now be easily updated whenever you want, and the files are located in your directory of choice. Moreover, you have the satisfaction of a job well done.

Now that you know how to install packages from source, you can just repeat as needed for any of the important packages on your system.

Gene Wilburn (gene@wilburn.ca) is a Toronto-based IT specialist, musician and writer who operates a small farm of Linux servers.

-30-