How does "make" app know default target to build if no target is specified?
Categories:
Understanding 'make': How the Default Target is Determined

Explore the mechanisms 'make' uses to identify and execute the default target when none is explicitly specified on the command line, enhancing your Makefile comprehension.
When you invoke make
without specifying a target, such as simply typing make
in your terminal, the make
utility doesn't just guess what you want to build. It follows a well-defined set of rules to determine which target should be considered the 'default' and subsequently built. Understanding these rules is crucial for writing robust and predictable Makefiles, especially in larger projects where clarity and consistency are paramount. This article will break down the process make
uses to find its default target.
The First Target Rule: The Primary Default
The most fundamental rule make
follows is to build the first target encountered in the Makefile that is not a special target (like .PHONY
) or a pattern rule. This means the order of your rules matters significantly. The first 'real' target defined in your Makefile will be the default target if no other target is specified on the command line.
all: program
@echo "Building everything"
program: main.o
@echo "Linking program"
clean:
@echo "Cleaning up"
rm -f *.o program
In this Makefile, 'all' is the default target because it's the first non-special rule.
In the example above, if you run make
, it will execute the commands associated with the all
target. If all
depended on program
, make
would then build program
and its dependencies. The clean
target, despite being a common operation, would only be executed if you explicitly ran make clean
.
Using .PHONY for Explicit Default Targets
While the 'first rule' mechanism works, it's often good practice to explicitly declare your default target, especially if it's a conceptual target like all
or build
. This is where the .PHONY
special target comes in handy. Declaring a target as .PHONY
tells make
that this target does not correspond to a file of the same name. This prevents make
from getting confused if a file named all
(or whatever your phony target is) happens to exist in the directory.
.PHONY: all clean
all: program
@echo "Building everything"
program: main.o
@echo "Linking program"
clean:
@echo "Cleaning up"
rm -f *.o program
Declaring 'all' as .PHONY ensures it's always run as a command, not a file.
all
, clean
, install
) as .PHONY
. This improves performance by preventing make
from checking for a file with that name and ensures the target is always executed when invoked.The Decision Flow for Default Target Selection
To summarize, make
follows a clear sequence of checks to determine the default target. This process ensures consistency and allows for flexible Makefile design.
flowchart TD A[Start: make invoked without target] --> B{Is a target specified on command line?} B -- Yes --> C[Build specified target] B -- No --> D{Is there a .DEFAULT_GOAL variable set?} D -- Yes --> E[Build target specified by .DEFAULT_GOAL] D -- No --> F{Find first non-special, non-pattern rule in Makefile} F --> G[Build the first rule's target] G --> H[End]
Decision flow for 'make' to determine the default target.
As the diagram illustrates, the primary mechanism is the first rule in the Makefile. However, make
also offers a more explicit way to define the default goal using the .DEFAULT_GOAL
variable, which overrides the 'first rule' behavior.
Overriding the Default with .DEFAULT_GOAL
For more explicit control, GNU make
provides the .DEFAULT_GOAL
special variable. If set, this variable specifies the target that make
should build if no target is given on the command line. This can be particularly useful for Makefiles where the logical default target might not be the first one defined due to organizational reasons.
.DEFAULT_GOAL := build
clean:
@echo "Cleaning up"
rm -f *.o program
build: program
@echo "Building the main program"
program: main.o
@echo "Linking program"
main.o:
@echo "Compiling main.c"
.PHONY: build clean
Using .DEFAULT_GOAL to explicitly set 'build' as the default target.
In this scenario, even though clean
is the first rule, make
will execute the build
target because .DEFAULT_GOAL
is set to build
. This provides a clear and unambiguous way to define your project's primary build action.
.DEFAULT_GOAL
variable is a GNU make
extension. If portability to other make
implementations is critical, rely on the 'first target rule' convention.