make
make
The make
command is a build automation tool that automatically builds executable programs and libraries from source code by reading files called Makefiles which specify how to derive the target program. The make
command is essential for compiling software in Unix-like operating systems, including Linux.
Key Concepts of make
make
Makefile: A file named
Makefile
(ormakefile
) that contains rules defining how to build the targets. It specifies the dependencies between files and the commands needed to create or update each target.Targets: The file or files to be built or the actions to be taken. Each target is typically an executable program or an object file.
Dependencies: Files that a target depends on. If any of these files change, the target must be rebuilt.
Rules: Instructions that define how to build the targets. A rule consists of a target, dependencies, and a command to build the target.
Basic Structure of a Makefile
A simple Makefile typically has the following structure:
target: dependencies
command
target
: The file to be created or the action to be performed.dependencies
: The files that the target depends on.command
: The command to be executed to build the target. This must be preceded by a tab character.
Example Makefile
Consider a simple C project with the following files:
main.c
utils.c
utils.h
A corresponding Makefile might look like this:
# Compiler and flags
CC = gcc
CFLAGS = -Wall -g
# Targets
all: myprogram
myprogram: main.o utils.o
$(CC) $(CFLAGS) -o myprogram main.o utils.o
main.o: main.c utils.h
$(CC) $(CFLAGS) -c main.c
utils.o: utils.c utils.h
$(CC) $(CFLAGS) -c utils.c
clean:
rm -f myprogram *.o
Commands in the Example
all
: The default target. It depends onmyprogram
.myprogram
: The executable to be created. It depends onmain.o
andutils.o
.main.o
: An object file created frommain.c
. It depends onmain.c
andutils.h
.utils.o
: An object file created fromutils.c
. It depends onutils.c
andutils.h
.clean
: A utility target to remove generated files. It does not create a file namedclean
.
Running make
make
To use the Makefile, simply run:
make
This will execute the first target in the Makefile (usually all
). To execute a specific target, specify it as an argument:
make clean
Variables in Makefiles
Makefiles can use variables to simplify the code and make it more maintainable. For example:
CC = gcc
CFLAGS = -Wall -g
OBJ = main.o utils.o
all: myprogram
myprogram: $(OBJ)
$(CC) $(CFLAGS) -o myprogram $(OBJ)
main.o: main.c utils.h
$(CC) $(CFLAGS) -c main.c
utils.o: utils.c utils.h
$(CC) $(CFLAGS) -c utils.c
clean:
rm -f myprogram $(OBJ)
Useful make
Options
make
Options-f FILE
: UseFILE
as the Makefile.-C DIR
: Change to directoryDIR
before reading the Makefile.-j [N]
: AllowN
jobs at once; infinite jobs with no argument.-k
: Continue as much as possible after an error.-n
: Print the commands that would be executed, but do not execute them.
Conclusion
The make
command is a powerful and flexible tool for automating the build process of software projects. By defining rules and dependencies in a Makefile, make
can efficiently compile and link programs, rebuild only the necessary components, and simplify the management of complex build processes. Understanding make
and writing effective Makefiles is a valuable skill for developers working in Unix-like environments.
help
Usage: make [options] [target] ...
Options:
-b, -m Ignored for compatibility.
-B, --always-make Unconditionally make all targets.
-C DIRECTORY, --directory=DIRECTORY
Change to DIRECTORY before doing anything.
-d Print lots of debugging information.
--debug[=FLAGS] Print various types of debugging information.
-e, --environment-overrides
Environment variables override makefiles.
-E STRING, --eval=STRING Evaluate STRING as a makefile statement.
-f FILE, --file=FILE, --makefile=FILE
Read FILE as a makefile.
-h, --help Print this message and exit.
-i, --ignore-errors Ignore errors from recipes.
-I DIRECTORY, --include-dir=DIRECTORY
Search DIRECTORY for included makefiles.
-j [N], --jobs[=N] Allow N jobs at once; infinite jobs with no arg.
-k, --keep-going Keep going when some targets can't be made.
-l [N], --load-average[=N], --max-load[=N]
Don't start multiple jobs unless load is below N.
-L, --check-symlink-times Use the latest mtime between symlinks and target.
-n, --just-print, --dry-run, --recon
Don't actually run any recipe; just print them.
-o FILE, --old-file=FILE, --assume-old=FILE
Consider FILE to be very old and don't remake it.
-O[TYPE], --output-sync[=TYPE]
Synchronize output of parallel jobs by TYPE.
-p, --print-data-base Print make's internal database.
-q, --question Run no recipe; exit status says if up to date.
-r, --no-builtin-rules Disable the built-in implicit rules.
-R, --no-builtin-variables Disable the built-in variable settings.
-s, --silent, --quiet Don't echo recipes.
--no-silent Echo recipes (disable --silent mode).
-S, --no-keep-going, --stop
Turns off -k.
-t, --touch Touch targets instead of remaking them.
--trace Print tracing information.
-v, --version Print the version number of make and exit.
-w, --print-directory Print the current directory.
--no-print-directory Turn off -w, even if it was turned on implicitly.
-W FILE, --what-if=FILE, --new-file=FILE, --assume-new=FILE
Consider FILE to be infinitely new.
--warn-undefined-variables Warn when an undefined variable is referenced.
Last updated