Close Menu
    Facebook X (Twitter) Instagram
    Command Linux
    • About
    • How to
      • Q&A
    • OS
      • Windows
      • Arch Linux
    • AI
    • Gaming
      • Easter Eggs
    • Statistics
    • Blog
      • Featured
    • MORE
      • IP Address
      • Man Pages
    • Write For Us
    • Contact
    Command Linux
    Home - How to - Makefile On Linux

    Makefile On Linux

    WillieBy WillieApril 27, 2026No Comments5 Mins Read

    A makefile tells the make utility how to compile and run programs. Instead of typing long commands every time you build your code, you write the instructions once and run a single command. Before starting, confirm that make is installed on your system.

    How a Makefile Works: Rules, Targets, and Prerequisites

    Create an empty directory called myproject. Inside it, create a file named Makefile with this content:

    say_hello:
            echo "Hello World"

    Run it by typing make inside that directory:

    $ make
    echo "Hello World"
    Hello World

    Every rule in a makefile has three parts.

    PartDescription
    TargetThe name of what you’re building, or a label for a recipe
    PrerequisitesFiles or targets that the target depends on
    RecipeThe commands that produce the target

    The general syntax is:

    target: prerequisites
    <TAB> recipe

    A target doesn’t have to be a file. When it’s just a label, it’s called a phony target. The full command prints before its output by default. To suppress that, add @ before the command:

    say_hello:
            @echo "Hello World"

    Now make shows only Hello World without printing the command itself.

    Setting a Default Target in a Makefile

    By default, make runs only the first target it finds. To change this, use .DEFAULT_GOAL:

    .DEFAULT_GOAL := generate

    This tells make to run generate instead of the first target. Since .DEFAULT_GOAL handles one target at a time, most projects use an all target to call multiple targets together. Here’s a more complete example:

    .PHONY: all say_hello generate clean
    
    all: say_hello generate
    
    say_hello:
            @echo "Hello World"
    
    generate:
            @echo "Creating empty text files..."
            touch file-{1..10}.txt
    
    clean:
            @echo "Cleaning up..."
            rm *.txt

    The .PHONY declaration tells make that these targets aren’t actual files. Running make now executes both say_hello and generate. The touch command creates the files — see how it handles shell brace expansion in this context. The clean target should be called manually with make clean rather than including it in all.

    Using Variables in a Makefile to Avoid Hardcoded Values

    Hardcoded values make makefiles fragile. Variables let you reuse values and change them in one place.

    Use = to define a recursive expanded variable:

    CC = gcc
    
    hello: hello.c
        ${CC} hello.c -o hello

    Both ${CC} and $(CC) are valid references. Assigning a variable to itself with =, though, causes an infinite loop. Use := instead — called a simply expanded variable — which evaluates the right side once at assignment:

    CC := gcc
    CC := ${CC}

    This is the safer default. Reserve = for cases where you specifically need the value to re-evaluate every time it’s referenced.

    Makefile Pattern Rules and Functions for Automating C Builds

    This makefile compiles all .c files in a directory automatically:

    .PHONY = all clean
    
    CC = gcc
    LINKERFLAG = -lm
    SRCS := $(wildcard *.c)
    BINS := $(SRCS:%.c=%)
    
    all: ${BINS}
    
    %: %.o
            @echo "Checking.."
            ${CC} ${LINKERFLAG} $< -o $@
    
    %.o: %.c
            @echo "Creating object.."
            ${CC} -c $<
    
    clean:
            @echo "Cleaning up..."
            rm -rvf *.o ${BINS}

    Here’s what each part does.

    LinePurpose
    $(wildcard *.c)Collects all .c files into SRCS
    $(SRCS:%.c=%)Substitution reference — strips .c extensions to get binary names
    %: %.oPattern rule — builds each binary from its matching object file
    %.o: %.cCompiles each .c file into an object file
    $<Refers to the first prerequisite
    $@Refers to the current target

    For a single file foo.c, the makefile expands to build foo.o from foo.c, then link foo.o into the final foo binary. The clean target removes all generated files. Once you have compiled binaries, you’ll need to set the right executable permissions with chmod before they can run.

    Automatic Variables in Makefile Recipes

    The automatic variables $@ and $< are the two you’ll use most often, but make provides others that come up in larger projects.

    VariableExpands to
    $@The target name of the current rule
    $<The first prerequisite
    $^All prerequisites, deduplicated
    $?Prerequisites newer than the target
    $*The stem matched by a pattern rule

    The $? variable is useful when you want a recipe to run only for changed files rather than all prerequisites. You can verify what make will run before executing it by passing -n, which prints the commands without running them. For anything involving recursive directories or environment variables, the grep command can help you quickly search through generated output or log files during debugging.

    Common Makefile Mistakes to Avoid

    The recipe line must start with a tab character, not spaces. This is the single most common source of confusing errors — make will report “missing separator” without pointing to the actual problem. Most editors let you configure this per-file type.

    Leaving non-file targets out of .PHONY causes make to skip them when a file with that name exists. A clean target without .PHONY does nothing if a file named clean is present in the directory.

    Using = when := is more appropriate can produce subtle bugs, especially when variables reference each other. If your build produces unexpected output, check variable assignments first.

    FAQs

    What is a makefile used for?

    A makefile tells the make utility how to build a project. It defines which commands to run, in what order, and which files depend on which others — so only changed files get recompiled.

    What is .PHONY in a makefile?

    .PHONY marks targets that are not actual files. It tells make to run the recipe regardless of whether a file with the same name exists in the directory.

    What is the difference between = and := in a makefile?

    = defines a recursively expanded variable — evaluated each time it’s used. := evaluates once at assignment. Use := by default to avoid unexpected behavior.

    How do you run a specific makefile target?

    Run make target_name from the directory containing your Makefile. For example, make clean runs the clean recipe. Without a target name, make runs the default target.

    Can a makefile compile multiple files at once?

    Yes. Use $(wildcard *.c) to collect all source files automatically, then pattern rules like %.o: %.c to compile each one. The all target links the results.

    Willie
    • Website

    Willie has over 15 years of experience in Linux system administration and DevOps. After managing infrastructure for startups and enterprises alike, he founded Command Linux to share the practical knowledge he wished he had when starting out. He oversees content strategy and contributes guides on server management, automation, and security.

    Related Posts

    How to Add Me to Search: Google People Card Guide for 2026

    April 29, 2026

    How to Convert YouTube to MP3

    April 28, 2026

    How To Login On Eleads

    April 27, 2026

    How to Find Linux Version

    April 27, 2026
    Top Posts

    GIT-SUBMODULE

    April 6, 2026

    pnmfile

    January 30, 2026

    How to Use chmod Executable in Linux

    January 27, 2026

    How To Check Linux List Processes

    January 26, 2026
    • Home
    • Contact Us
    • Privacy Policy
    • Terms of Use

    Type above and press Enter to search. Press Esc to cancel.