Skip to content

Compiling from Source

This chapter covers compiling software from source code, which is essential for custom builds, security, and understanding how software works.


Terminal window
# Arch Linux
sudo pacman -S --needed base-devel
# Debian/Ubuntu
sudo apt install build-essential
# RHEL/CentOS
sudo dnf groupinstall "Development Tools"
# Verify installation
gcc --version
make --version
Terminal window
# Arch Linux - common build dependencies
sudo pacman -S \
cmake \
autoconf \
automake \
pkg-config \
libtool \
flex \
bison \
gettext \
ninja \
meson
# Install development libraries as needed
sudo pacman -S openssl dev zlib libpng libjpeg

Source Compilation Process
+------------------------------------------------------------------+
| |
| 1. Download Source |
| └─ wget/curl/git clone |
| |
| 2. Extract |
| └─ tar -xvf source.tar.gz |
| |
| 3. Configure |
| └─ ./configure --prefix=/usr/local |
| - Checks system capabilities |
| - Generates Makefile |
| |
| 4. Build |
| └─ make |
| - Compiles source into binaries |
| |
| 5. Install |
| └─ sudo make install |
| - Copies files to system |
| |
| 6. ldconfig (if needed) |
| └─ Updates library cache |
| |
+------------------------------------------------------------------+
Terminal window
# Install dependencies
sudo pacman -S openssl pcre zlib
# Download source
wget https://nginx.org/download/nginx-1.24.0.tar.gz
tar -xvzf nginx-1.24.0.tar.gz
cd nginx-1.24.0
# Configure with options
./configure \
--prefix=/usr/local/nginx \
--sbin-path=/usr/local/nginx/sbin/nginx \
--conf-path=/usr/local/nginx/conf/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_gzip_static_module \
--with-pcre \
--with-openssl=/usr/include/openssl
# Build
make -j$(nproc)
# Install
sudo make install
# Update library cache
sudo ldconfig

Terminal window
# Basic CMake workflow
mkdir build
cd build
cmake ..
make
sudo make install
Terminal window
# Configure with options
cmake -DCMAKE_INSTALL_PREFIX=/usr/local \
-DCMAKE_BUILD_TYPE=Release \
-DENABLE_FEATURE=ON \
..
# Out-of-source build (recommended)
mkdir -p build/release
cd build/release
cmake -DCMAKE_BUILD_TYPE=Release ../..
make

Terminal window
# Common configure options
./configure \
--prefix=/usr/local # Installation prefix
--sysconfdir=/etc # Config files location
--localstatedir=/var # Variable data
--enable-shared # Build shared libraries
--enable-static # Build static libraries
--disable-debug # Disable debug symbols
--with-package=option # Package-specific options
--without-package # Disable package
--help # Show all options
Terminal window
# Build with multiple cores
make -j$(nproc)
# Build specific target
make nginx
# Install to staging directory
make DESTDIR=/tmp/staging install
# Clean build
make clean
make distclean

Terminal window
# Install
sudo pacman -S meson ninja
# Configure
meson setup builddir
# Build
ninja -C builddir
# Install
sudo ninja -C builddir install

Terminal window
# Install to /usr/local
./configure --prefix=/usr/local
sudo make install
# Update library cache
sudo ldconfig
# Find installed binaries
which nginx
ldd $(which nginx)
Terminal window
# Install checkinstall
sudo pacman -S checkinstall
# Create package instead of make install
sudo checkinstall --pkgname=nginx-custom --pkgversion=1.24.0 make install

Terminal window
# Missing dependencies
configure: error: *** missing ***
# Solution: Install required -dev packages
# Library not found
# Solution: Set LDFLAGS
export LDFLAGS="-L/usr/local/lib"
export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"
# Header not found
# Solution: Set CPPFLAGS
export CPPFLAGS="-I/usr/local/include"
# Compiler not found
# Solution: Set CC
export CC=gcc-13
export CXX=g++-13
Terminal window
# Save configure output
./configure > configure.log 2>&1
# Save build output
make > build.log 2>&1
# Verbose build
make V=1

Terminal window
# Example PKGBUILD
pkgname=nginx-custom
pkgver=1.24.0
pkgrel=1
arch=('x86_64')
depends=('openssl' 'pcre' 'zlib')
build() {
cd $pkgname-$pkgver
./configure --prefix=/usr/local
make
}
package() {
cd $pkgname-$pkgver
make DESTDIR=$pkgdir install
}
Terminal window
# Example nginx.spec
Name: nginx-custom
Version: 1.24.0
Release: 1%{?dist}
Summary: Custom nginx build
%build
./configure --prefix=/usr/local
make %{?_smp_mflags}
%install
make install DESTDIR=%{buildroot}
%files
%{_prefix}/local/nginx

Compiling from source is essential for custom builds and security:

Source Compilation in DevOps
+------------------------------------------------------------------+
| |
| Custom Software: |
| +----------------------------------------------------------+ |
| | Custom nginx/Python with specific modules | |
| | Hardware-specific optimizations | |
| | Older versions not in package repos | |
| +----------------------------------------------------------+ |
| |
| Security: |
| +----------------------------------------------------------+ |
| | Patch vulnerabilities in custom builds | |
| | Compile with security flags (-D_FORTIFY_SOURCE) | |
| | Reproducible builds for verification | |
| +----------------------------------------------------------+ |
| |
| DevOps Tools: |
| +----------------------------------------------------------+ |
| | Packer → Build custom AMIs with compiled software | |
| | Docker → Multi-stage builds with compiled binaries | |
| | GitHub Actions → Compile in CI pipelines | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+

Practical Impact:

  • Custom software builds for specific requirements
  • Security patching of outdated packages
  • Optimized builds for specific hardware

Terminal window
# ❌ WRONG: Trying to build without dependencies
./configure
# Fails with "configure: error: ... not found"
# ✅ CORRECT: Install build dependencies first
sudo apt-get install build-essential libssl-dev
# Or check README for required packages
Terminal window
# ❌ WRONG: Installing directly to system
make install
# Pollutes /usr/local, hard to remove
# ✅ CORRECT: Use DESTDIR for staging
make install DESTDIR=/tmp/staging
# Package the staging directory instead
Terminal window
# ❌ WRONG: No record of how software was built
# Impossible to reproduce or update
# ✅ CORRECT: Document everything
# save configure options, patches, build steps
# Use Ansible/Chef to automate builds

  1. What is the typical build process for autotools?
  2. How do you create an RPM from source?
  3. What are the advantages of CMake over autotools?
  4. How do you troubleshoot configure errors?
  5. What is DESTDIR and why is it important?

In this chapter, you learned:

  • ✅ Setting up build environment
  • ✅ Autotools build process (configure/make)
  • ✅ CMake build system
  • ✅ Meson/Ninja builds
  • ✅ Troubleshooting build issues
  • ✅ Creating distribution packages

Chapter 30: Repository Management


Last Updated: February 2026