Introduction

Today's modern Linux systems use package managers to enable users to install a variety of pre-compiled packages with ease, and in general is the favored method to go about installation of a given piece of software. You've no doubt heard of or been exposed to yum or apt, and these packager managers install pre-compiled packages such as rpm or deb.

However, there are times when it is advantageous to build a piece of software from it's source code. Source code is usually downloaded in one of several formats like a tarball, a gunzip or from any number of growing hosted software repositories such as github, bitbucket or sourceforge.

There are a number of reasons one may choose to build a piece of software from source:

  • The distribution does not have the desired version.
  • You want to segregate a piece of software from system packages.
  • You need a custom installation path.

The method in which you build a package depends on the language a piece of software was written in. Most of the time you will probably be compiling a C program, but it could easily be ruby, python etc...

Pre-requisites

In order to properly build a piece of software from source, you will need to meet a couple of requirements, however most of the time these tools are kept in nice package groups, but here are a few:
* A method to download the source code to the target machine, wget, curl, git, scp * Development Tools, make, automake, autoconf, binutils, gcc, gcc-c++, gettext, libtool, make, patch, bison

The package groups can be installed a bit easier if you're on a RHEL or Debian variant.

RHEL Variant

yum install "Development tools"  

Debian Variant

apt-get install build-essential  

After you've satisfied the basic requirements, you'll want to reference the documentation for the piece of software you're compiling, and also satisfy any requirements that said software needs for a successful compile. There may also be some optional items you can install to compile additional features in the the software you may be interested in, so it's important to read the documentation.

Setting Up Your Build Environment

After you've satisfied the requirements, you're ready to setup your build environment. You may do this anywhere you choose, however my personal preference (yes this is a style preference, not law) is to work in my home directory, so I may recompile, update or package the piece of software as I see fit without cluttering up the system.

A build environment is nothing special, and is simply an area on your workstation or server that you've designated as your work area. Let's create that now.

[email protected]:~$ pwd  
/home/shellfu
[email protected]:~$ mkdir -p build/{source,archives,packages,destdir}  
[email protected]:~$ ls build  
source archives packages destdir  
[email protected]:~$ cd build  

Now that we have our build environment or work area established, we can proceed with building our software.

Obtaining the Source Code

We're ready to obtain the source code and compile our software. For this example, we will be compiling joe or Joe's own editor. JOE is written in C and its only dependency is libc. JOE is very easy to build, and due to it's small size is suitable for extremely lean servers or even recovery disks.

In our example, we need to obtain the source code for JOE which is hosted on sourceforge. We can use the wget tool to obtain this, or you may go to sourceforge and download the source code from there.

After we obtain the source code, we will untar the source and move both the archive and the source code to their proper place within our build environment.

[email protected]:~$ pwd  
/home/shellfu/build
[email protected]:~$ wget http://downloads.sourceforge.net/project/joe-editor/JOE%20sources/joe-4.1/joe-4.1.tar.gz  
[email protected]:~$ tar zxvf joe-4.1.tar.gz  
[email protected]:~$ mv joe-4.1.tar.gz archives/  
[email protected]:~$ mv joe-4.1 source/  

Configure the Software

The next step after we obtain our source code, is to configure the piece of software before compiling. This allows us to specify a variety of options and parameters that can alter the behavior of the software we're compiling.

The configure script profiles information about the running system and configures the source code to to run on said system. This involves finding library locations it may need in order to compile properly. You may often times just run ./configure as is in order to accept all default options, however ./configure - -help will list arguments you may pass to the configure script.

The most common argument I tend to use is - -prefix. Prefix defines the locations where you would like the software to be installed. You may or may not care about the location, and let it install in it's default. However, you may also not have elevated privileges on the system, and can choose to install the software in your home directory for instance. (ie. - -prefix=/home/shellfu)

I won't show the entire help for JOE's configure script, as most configure scripts are quite verbose, but I will show the prefix section. Feel free to run - -help for your own edification.

[email protected]:~$ pwd  
/home/shellfu/build/source/joe4.1
[email protected]:~$ ./configure --help  
Installation directories:  
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [/usr/local]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [PREFIX]

By default, `make install' will install all the files in  
`/usr/local/bin', `/usr/local/lib' etc.  You can specify
an installation prefix other than `/usr/local' using `--prefix',  
for instance `--prefix=$HOME'.  
[email protected]:~$  

For our example, we will add our home directory as the prefix or install location for JOE. Once the configuration process is completed, and if everything went well as in required dependencies are met. Then the configure script will generate the Makefile, which is used to compile the software.

[email protected]:~$ ./configure --prefix=/home/shellfu  
checking build system type... x86_64-unknown-linux-gnu  
checking host system type... x86_64-unknown-linux-gnu  
checking target system type... x86_64-unknown-linux-gnu  
checking for a BSD-compatible install... /usr/bin/install -c  
checking whether build environment is sane... yes  
checking for a thread-safe mkdir -p... /bin/mkdir -p  
checking for gawk... gawk  
checking whether make sets MAKE... yes  
checking whether make supports nested variables... yes  
checking whether to enable maintainer-specific portions of Makefiles... no  
checking for gcc... gcc  

Compile the Software

The Makefile is used to compile the software, and is generated by the configure script. The makefile now has instructions on how to compile the software based off your configuration options you passed into the configure script. If any errors are encountered during the compilation process they will be written to stdout. You should take note, that this process can sometimes take awhile depending on your system specs, and the software that you're compiling.

For our example, we're compiling JOE, so let's do that now

[email protected]:~$ make  

Installing the Software

At this point the software has been compiled, and is ready to be installed. This is the point where you can decide if you'd like to package your software for distribution, or install your software as is.

To install your software we will again use make, but with install.

[email protected]:~$ make install  
[email protected]:~$ ls ~/bin  
jmacs  joe    jpico  jstar  rjoe  

Congratulations, your software is now installed, and ready to use.