Exam topic 206.1 โ Make and Install Programs from Source (weight: 2). Covers the full cycle of downloading, configuring, compiling, and installing a program from source code.
Why Build from Source
Sometimes the program you need is not in the distribution’s repository. Or you want to review the code before installation, enable non-standard options, or build for a specific architecture. A package manager like apt or yum handles dependencies automatically, but with a manual build you handle everything yourself.
Warning: When installing from source, there is no dependency manager. All required libraries and compilers must be installed manually before the build begins.
Install basic development tools first:
# Red Hat / CentOS / Fedora
yum groupinstall "Development Tools"
# Debian / Ubuntu
apt-get install build-essential
Where to Store Source Code
By GNU standard, source code is stored in /usr/src. That is the conventional place for archives before extraction. You can work in any directory during the build (e.g., /tmp or your home directory), but /usr/src is the default location for source code.
/usr/src/
curl-7.46.0/ <- extracted source tree
curl-7.46.0.tar.gz <- original archive
Important: For the exam โ
/usr/srcis the default source code storage location.
Extracting Archives
Source code is most often distributed as a compressed tarball. Three main compression formats: gzip (.tar.gz / .tgz), bzip2 (.tar.bz2), and xz (.tar.xz).
Extraction with GNU tar (recommended)
# gzip (.tar.gz or .tgz)
tar zxvf archive.tar.gz
# bzip2 (.tar.bz2)
tar jxvf archive.tar.bz2
# xz (.tar.xz)
tar Jxvf archive.tar.xz
Flags: z = gzip, j = bzip2, J = xz, x = extract, v = verbose, f = filename.
Two-step extraction (for old tar without compression support)
# Step 1: decompress
gunzip archive.tar.gz # or: gzip -d archive.tar.gz
bunzip2 archive.tar.bz2 # or: bzip2 -d archive.tar.bz2
unxz archive.tar.xz # or: xz -d archive.tar.xz
# Step 2: extract tar
tar xvf archive.tar
Creating an archive
tar czf archive.tar.gz ./mydir/
Flag c = create (as opposed to x = extract).
Tip: Save
configureandmakeoutput to a log withtee:./configure | tee ../configure.log make | tee ../make.log
Documentation Files Before Building
Before running configure, read the files in the source directory. The program’s author may use a non-standard installation process.
| File | Purpose |
|---|---|
README | General documentation and installation instructions |
INSTALL | Detailed installation instructions |
COPYING | Program license |
RELEASE-NOTES | Changes in the current version |
NEWS | New features and fixes |
AUTHORS | Authors and contacts |
Note: Not all files are present in every project. Names may also differ.
configure: What It Is and Why It Exists
configure is a shell script that checks the environment before compilation. It verifies the presence of the compiler, required libraries, and optional dependencies, then generates a Makefile.
The script is generated by GNU autoconf/automake tools. automake creates Makefile.in, and autoconf turns it into the final configure script.
./configure # run with default settings
./configure --help # view all available parameters
If configure cannot find a mandatory dependency, it prints an error and stops. Missing optional dependencies simply disable the corresponding feature.
What configure does
- Checks for the compiler (usually
gcc) - Searches for mandatory and optional libraries
- Determines the architecture via
uname(runs theconfig.guessscript) - Generates
MakefilefromMakefile.in - Adapts the code to the target system
configure Parameters
./configure # install in /usr/local (default)
./configure --prefix=/opt # install in /opt
./configure --prefix=/opt/sue # install in /opt/sue
# Build for deployment to another machine (DESTDIR)
./configure --prefix=/opt/sue
make
make install DESTDIR=/tmp/sue_tmp
# All program files are now in /tmp/sue_tmp/opt/sue/
Important:
--prefixsets the installation path in the final system.DESTDIRatmake installtime tells make where to put files right now. They are different things:DESTDIRis used for building packages or deploying to multiple machines.
Full cycle for transferring to another machine:
# On the build machine
tar zxvf sue-2.0.3.tar.gz
cd sue-2.0.3
./configure --prefix=/opt/sue
make
make install DESTDIR=/tmp/sue_tmp
cd /tmp
tar czf sue-installed.tar.gz sue_tmp/
# Copy the archive to target machines, then:
tar zxvf sue-installed.tar.gz -C /
make and Build Targets
make reads the Makefile and compiles the program. Without arguments it runs the all target (build everything).
make # compile (target: all)
make install # install the compiled program
make clean # remove object files after build
make distclean # remove everything including Makefile (for full rebuild)
| make target | What it does |
|---|---|
all | Compilation (default target) |
install | Copy binaries and files to their destinations |
clean | Remove object files (.o) from the source tree |
distclean | Remove everything generated, including Makefile |
uninstall | Remove the installed program (if implemented) |
Tip:
make installrequires root โ binaries are placed in system directories.
The install Utility
install copies files to the right location with correct permissions and ownership. Unlike cp, it sets permissions and owner/group in one step.
# Install binary with permissions 755 to /usr/local/bin
install -m 755 mybinary /usr/local/bin/
# Install with explicit owner and group
install -m 755 -o root -g root mybinary /usr/local/bin/
# Create a backup of the existing file before overwriting
install -b -m 755 mybinary /usr/local/bin/
# Create a directory if it does not exist
install -d /usr/local/myapp/
| Flag | Description |
|---|---|
-m mode | Set permissions (e.g., 755) |
-o owner | Set owner |
-g group | Set group |
-b | Create a backup of the existing file |
-d | Create directory |
Note: Backup behavior with
-bis controlled by theVERSION_CONTROLenvironment variable. Values:numbered,existing,simple,none.
uname
uname prints system information. configure uses it via the config.guess script to determine the architecture during cross-compilation.
uname
# Linux
uname -a
# Linux myhost 5.15.0-91-generic #101-Ubuntu SMP x86_64 GNU/Linux
| Flag | Output |
|---|---|
-a | All information |
-s | Kernel name (Linux) |
-n | Network hostname |
-r | Kernel release version |
-v | Version (build date) |
-m | Hardware architecture (x86_64) |
-p | Processor type |
-o | Operating system (GNU/Linux) |
patch
patch applies a diff file to an original file. The patch file is created by diff between the old and new versions of a file.
patch -p1 < patchfile.patch # apply a patch
patch -R -p1 < patchfile.patch # revert a patch
patch -s -p1 < patchfile.patch # silent mode, errors only
The -p flag specifies how many leading path components to strip from file names in the patch. -p0 leaves the path as-is, -p1 removes the first component.
# Example: path in the patch file is /home/user/src/prog/main.c
patch -p0 < fix.patch # looks for /home/user/src/prog/main.c
patch -p1 < fix.patch # looks for home/user/src/prog/main.c
patch -p4 < fix.patch # looks for main.c
If patch cannot apply part of a patch, the rejected hunks are saved to a file with the .rej extension.
Warning:
patch -Rassumes the old and new files are swapped. Use it to return to the original state.
Full Build Cycle
Standard process for installing a program from source:
# 1. Go to /usr/src and extract the archive
cd /usr/src
tar zxvf sue-2.0.3.tar.gz
# 2. Enter the source directory
cd sue-2.0.3
# 3. Read README and INSTALL
# 4. Run configure
./configure
# 5. Compile
make
# 6. Install (as root)
sudo make install
Installation to a non-default path:
./configure --prefix=/opt
make
sudo make install
Or using install manually:
make
sudo install -m 755 -o root -g root ./sue /usr/local/bin/sue
Exam Cheat Sheet
Paths
| Path | Purpose |
|---|---|
/usr/src | Default source code storage |
/usr/local/bin | Binaries installed from source (default with --prefix=/usr/local) |
Makefile | Generated by configure, used by make |
Makefile.in | Template for Makefile generation |
config.guess | Script for determining system architecture |
Commands and Utilities
| Command | Purpose |
|---|---|
gzip / gunzip | Compress / decompress .gz |
bzip2 / bunzip2 | Compress / decompress .bz2 |
xz / unxz | Compress / decompress .xz |
tar zxvf | Extract .tar.gz |
tar jxvf | Extract .tar.bz2 |
tar Jxvf | Extract .tar.xz |
./configure | Check environment and generate Makefile |
./configure --prefix=PATH | Set installation path |
make | Compile (target: all) |
make install | Install compiled program |
make clean | Remove object files |
install -m 755 | Copy file with permissions |
uname -a | All system information |
uname -r | Kernel version |
patch -p1 < file | Apply a patch |
patch -R -p1 < file | Revert a patch |
Common Mistakes
- Running
make installwithout root: permission error. - Forgetting dependencies:
configureexits with an error. - Confusing
-p0and-p1inpatch: file not found. - Running
makebefore./configure: no Makefile, command will fail. - Installing without
--prefix: program lands in/usr/local, possible conflict with package manager.
Practice Questions
Q1. Which tar flag is used to extract a .tar.bz2 archive?
Answer: -j. Full command: tar jxvf archive.tar.bz2.
Q2. Where is source code stored by default on a Linux system?
Answer: /usr/src.
Q3. What does ./configure --prefix=/opt do?
Answer: Sets /opt as the root installation path. All program files will go into /opt/bin, /opt/lib, etc.
Q4. What file does configure create, and why is it needed?
Answer: Makefile. It is read by make to compile and install the program.
Q5. What is the difference between make clean and make distclean?
Answer: make clean removes only object files (.o). make distclean removes everything generated by configure and make, including the Makefile itself, returning the source tree to its original state.
Q6. How do you apply a patch and strip the first path component from the patch file?
Answer: patch -p1 < fix.patch.
Q7. Why is the install utility better than cp for installing binaries?
Answer: install sets permissions and owner/group in one step. With -b it creates a backup of the existing file before overwriting.
Q8. Why does configure call uname?
Answer: To determine the system architecture via the config.guess script. Based on this information, configure adapts the code and compiler flags for the target platform.