Building From Source
What to do when the software you need isn't packaged for your distribution - the standard configure/make/install pattern, and why it deserves a different install location than package-managed software.
Every package manager covered in this section (APT, DNF, pacman) is ultimately installing software that someone already compiled from source and packaged. When nothing has done that for the software you need, you do it yourself.
Install build tools first
Compiling from source requires a compiler and standard build tools, which aren't installed by default on most systems:
sudo apt install build-essential # Debian/Ubuntu
sudo dnf group install "Development Tools" # Fedora/RHEL
sudo pacman -S base-devel # Arch
The classic pattern: configure, make, install
Most C/C++ projects distributed as a source tarball follow the same three steps:
tar xzf project-1.4.0.tar.gz
cd project-1.4.0
./configure
make
sudo make install
./configure- a generated script that checks your system for required libraries and tools, and produces aMakefiletailored to what it found. If it fails, the error almost always names a missing dependency (a-dev/-develpackage, since headers needed for compiling are usually packaged separately from the runtime library) - install that and re-run.make- actually compiles the source, using the generatedMakefile. Run with-j$(nproc)to parallelize across all CPU cores and speed this step up meaningfully on anything nontrivial.sudo make install- copies the built binaries, libraries, and man pages into place, by convention under/usr/local/rather than/usr/.
Why /usr/local, specifically
This isn't arbitrary - it's the Filesystem Hierarchy Standard's
designated space for software installed outside the distribution's own
package manager (see
The Filesystem Hierarchy). Keeping
manually-built software out of /usr means it can never collide with or
get silently overwritten by a package manager update, and which /
$PATH ordering typically checks /usr/local/bin first, letting a
manual build take precedence without touching anything package-managed.
The problem this creates: no easy uninstall or upgrade
A package manager tracks exactly which files belong to which package, so
removal and upgrades are clean. make install does not - there's no
built-in record of what got copied where, so removing a source-built
program later usually means either keeping the original build directory
around to run sudo make uninstall (only works if the project's Makefile
defines that target, which not all do) or hunting down files manually.
checkinstall is a common workaround: it runs the install step
inside a wrapper that captures what changed, then builds an actual
.deb or .rpm from that, giving you a normal, trackable, removable
package instead of an untracked scattering of files:
sudo checkinstall # instead of `sudo make install`
Building from a git repository instead of a tarball
Cloning a project's repository directly sometimes skips the configure
step (since it wasn't generated for a release) - an autoreconf or
./autogen.sh step typically has to run first to generate it:
git clone https://example.com/project.git
cd project
./autogen.sh
./configure
make
sudo make install
CMake as an alternative to configure/make
Many newer C/C++ projects use CMake instead of the traditional Autotools pattern above - same underlying idea (detect the environment, generate build files, compile), different commands:
mkdir build && cd build
cmake ..
make
sudo make install
Check a project's own README or INSTALL file for which of these two
patterns it expects - there's no universal way to tell from the source
tree alone which build system a given project uses.