Starexe
📖 Tutorial

A Beginner's Guide to Compiling C Programs from Source

Last updated: 2026-05-04 17:22:22 Intermediate
Complete guide
Follow along with this comprehensive guide

Why Compile C Code Yourself?

Many developers rarely touch raw C code, but occasionally you need to compile a C or C++ program from its source files. In the past, I relied on pre-built binaries—and on Linux that usually worked. After switching to macOS, however, I found myself needing to compile more often. This guide walks through the essential steps, using real examples like paperjam, sqlite, and qf (a pager that opens files from rg -n THING | qf). By the end, you'll understand the process from installing a compiler to running make.

A Beginner's Guide to Compiling C Programs from Source

Step 1: Install a C Compiler

Before anything else, you need a working C compiler. On Ubuntu or other Debian-based systems, the easiest way is to install the build-essential package:

sudo apt-get install build-essential

This installs gcc, g++, and make. On macOS, the situation is more fragmented; you typically install Xcode Command Line Tools:

xcode-select --install

Alternatively, you can use Homebrew to install gcc—but the command-line tools are usually sufficient.

Step 2: Install the Program's Dependencies

C lacks a built-in dependency manager, so you must track down libraries yourself. Fortunately, most C programs keep dependencies minimal, and they're often available via your system package manager. Always check the project's README for specific instructions.

Example: paperjam

Paperjam's README states:

To compile PaperJam, you need the headers for the libqpdf and libpaper libraries (usually available as libqpdf-dev and libpaper-dev packages). You may need a2x (found in AsciiDoc) for building manual pages.

On Debian/Ubuntu, run:

sudo apt install -y libqpdf-dev libpaper-dev

On macOS with Homebrew, the equivalent packages are often named without the -dev suffix, so you'd use brew install qpdf libpaper (though libpaper may not exist—check the project's docs).

Tip: When a README mentions a package like libqpdf-dev, assume it refers to a Debian-based distro. For other systems, search for the library's name (e.g., qpdf) in your package manager.

Example: sqlite

SQLite is famously self-contained—it has zero external dependencies. You can compile it with just a C compiler and the source files. That's why it's a great first project.

Example: qf

Qf is a simple pager written in C. Its dependencies are light (often just the standard library), but always check its README for any special requirements.

Step 3: Run ./configure (If Present)

Some C projects ship a Makefile directly; others include a ./configure script that generates one. The ./configure script checks your system for required libraries and compiler features, then produces a custom Makefile.

When to run it

If you see a configure file (or configure.ac), run:

./configure

It will output a lot of text—often cryptic. If it fails, read the error messages carefully; they usually indicate missing dependencies or incompatible tools.

Example: sqlite

SQLite's source distribution includes a configure script. Running it produces a Makefile tailored to your system. If you don't want to run configure, SQLite also provides a ready-made Makefile for simple builds (just make).

For projects without a configure script, you skip straight to make.

Step 4: Compile with make

Once you have a Makefile (either provided or generated by ./configure), compiling is usually a single command:

make

If you have multiple cores, you can speed up compilation with make -j4 (replace 4 with the number of CPU cores).

Common pitfalls

  • Missing dependencies: The compiler will complain about missing headers or libraries. Install the required packages and try again.
  • Outdated compiler: Some C11 or C17 features require a recent compiler. Update your toolchain if you see syntax errors.
  • Makefile needs editing: Occasionally you must adjust paths or flags in the Makefile itself. Look for comments like “Edit here for your system.”

Step 5: Install the Program (Optional)

After successful compilation, you'll have a binary (usually named after the program). To use it system-wide, run:

sudo make install

Be careful: this copies files into /usr/local/bin or similar. If you prefer not to install system-wide, just run the binary from the build directory.

Example: qf

Qf compiles to a single executable. You can copy it to a directory in your $PATH, or use the project's install target if provided.

Final Thoughts

Compiling C programs isn't as intimidating as it seems. The steps are almost always:

  1. Install a C compiler and make.
  2. Install dependencies (check the README).
  3. Run ./configure if present.
  4. Run make.
  5. Optionally make install.

With practice, you'll learn to read compiler errors and track down libraries. Start with simple projects like sqlite, then move to tools like paperjam that have a few dependencies. Good luck—and happy compiling!