C-Makefiles
A make- is a build automation tool used to compile and build projects.
Very useful if you have multiple source files.
Makefile is just a configuration file that specifies how the project should be built(rules) and the dependencies between different files.
Makefile has rules and dependencies.
When it's useful?
When you have a large project- a large program with many source files
Dependency management- different files depend on each other
efficiency - recompiles only parts of code that changed hence saving time.
Why use it:
Automation- saves you from having to manually recompile files
Dependencies tracking- able to detect changes and build.
Consistency- ensures consistent build process in different environments for different developers.
How to use it:
Start by creating a file named makefile
Define rules -write rules that specify how to build target files(output files) from dependencies(input files)
Use variables - define variables for compiler options source files and other parameters
create phony targets - for actions that don't produce files but trigger certain tasks e.g cleaning or testing
dependencies- explicitly list dependencies(input files) for each target for proper rebuild
CC = gcc
CFLAGS = -Wall
all: my_program
my_program: main.o utils.o
$(CC) $(CFLAGS) -o my_program main.o utils.o
main.o: main.c
($CC) $(CFLAGS) -c my_program main.c
utils.o: utils.c
$(CC) $(CFLAGS) -c my_program utils.c
clean:
rm -f *.o my_program
Explicit rules
specify how to build a specific target explicitly.
target: prerequisite
recipe
They are useful when you want to specify or be specific on how to build a specific target.
They are explicitly done in makefile.
my_program: main.o utils.o
gcc -Wall -o my_program main.o utils.o
main.o: main.c utils.h
gcc -Wall -c main.c
utils.o: utils.c utils.h
gcc -Wall -c utils.c
Implicit rules
These are predefined rules that do not need explicit instructions.
Often written as pattern rules, specifying a pattern for target and prerequisite names.
%.o: %.c
recipe
They are handy when you have consistent patterns for building patterns from source files.
CC = gcc
CFLAGS = -Wall
my_program: main.o utils.o
$(CC) $(CFLAGS) -o my_program main.o utils.o
main.o utils.o: %.o: %.c
$(CC) $(CFLAGS) -c $<
common rules
Simple rule for compiling source files
%.o: %.c
$(CC) $(CFLAGS) -c $<
linking them to an executable
my_program: main.o utils.o
$(CC) $(CFLAGS) -o my_program main-o utils.o
Phony targets
.PHONY: clean
clean:
rm -f*.o my_program
Default rule
.DEFAULT_GOAL := all
all: my_program
Setting variables
Basic assignment
variable_name = value
Appending to variables
VARIABLE_NAME += new_value
Using variables
Referencing variables
$(VARIABLE_NAME)
Defining targets with variables
TARGET: $(VARIABLE_NAME):
recipe
Automatic variables
target: prerequisite1 prerequisite2
command $@ $^
Example
CC = gcc
CFLAGS = -Wall
SOURCES = main.c utils.c
OBJECTS = $(SOURCES:.c=.o)
EXECUTABLE = my_program
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $^
%.o:%.c
$(CC) $(CFLAGS) -c $<
clean:
rm -f $(OBJECTS) $(EXECUTABLE)
Subscribe to my newsletter
Read articles from sammy directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
sammy
sammy
I am an aspiring software engineer.By writing this article.I am commit myself accountable to provide valuable content to you reader oftenly every weekend about amazing programming concepts and technologies.To help you in your learning journey also.