A simple Makefile
CC = gcc
NAME = binary_name
CFLAGS = -Wpedantic -pedantic-errors -w -Wextra -Wall -Iinclude
SRC = core/my_printf.c \
core/save_printf.c \
src/my_putstr.c \
src/my_putchar.c \
src/my_strlen.c \
main.c
OBJ = $(SRC:.c=.o)
all: $(NAME)
$(NAME): $(OBJ)
$(CC) -c $(OBJ) -o $(NAME)
clean:
-rm -f $(OBJ)
fclean: clean
-rm -f $(NAME)
re: fclean all
.PHONY: fclean clean re
Graphical Makefile Template
In this template I have a folder named src where is located all our .c file except the main.c which is root located. The $(shell find src/ -name '.c') means to Makefile to find all the .c files which are located in the folder src* including all the sub directory inside it.
CC = gcc
CSFML += -lcsfml-graphics -lcsfml-window -lcsfml-audio -lcsfml-system
CFLAGS += -Wpedantic -pedantic-errors -w -Wextra -Wall $(CSFML) -Iinc
NAME = name_of_the_binary
SRC = $(shell find src/ -name '*.c')\
main.c
OBJ = $(SRC:.c=.o)
all: $(NAME)
$(NAME): $(OBJ)
$(CC) $(CFLAGS) $(OBJ) $(LIB) -o $(NAME)
rm -f $(OBJ) *~
clean:
rm -f src/*.o
rm -f *~ core/*~ inc/*~ src/*~
fclean: clean
rm -f $(NAME)
rm -f a.out src/a.out core/a.out a.out
re: fclean all
.PHONY: fclean clean re
Some useful flags and possibilities of customs makefile you can use
How make processes a Makefile
By default, makes start with the first target. It reads the Makefile
in the current directory and begins by processing the first rule. A
rule appears in the makefile and says when and how to remake certain
files, called the rule's targets
(most often only one per rule).
The general syntax for a rule is:
target: [ prerequisites ]
[ command ]
A target
is usually the name of a file that is generated by a program. It can also be the name of an action to carry out, such as re, fclean.
A prerequisite
is a file that is used as input to create the target.
Clean rule
Beside compiling a program, a Makefile can help you with cleaning the unnecessary files in your directory such as .o, .gcno, .gcda, .gcovr. We can write a clean
rule to help us as follows:
clean:
rm -f *.o
rm -f *.gcda
rm -f *.gcno
rm -f *.gcovr
To prevent make from getting confused by a file called "clean" and force it to stop when an error occurs, we might want to rewrite the rule:
.PHONY : clean
clean :
rm -f *.o
rm -f *.gcda
rm -f *.gcno
rm -f *.gcovr
There are two reasons to use a phony target: to avoid a conflict with a file of the same name, and to improve performance.
Adding unit_tests rule
It is considered as a good practice (pattern) to implement the unit tests for all your functions. We'll see here how you can create a rule for your unit tests inside your Makefile.
Unit tests rule
tests_run: $(TEST_SRC)
gcc $(TEST_SRC) -o $(TEST_NAME) --coverage -lcriterion
./$(TEST_NAME)
gcovr --exclude tests/
gcovr --exclude tests/ --branches
Let's understand what happened here.
The first line
help us to compile the sources files with criterion.
Criterion add it's own main so none of the files we are compiling
should contain a main function. The second one
execute the generated
binary. The execution of your unit-tests binary should create a bunch
of .gcda
and .gcno
files. These can be used by tools such as gcovr
to calculate the amount of code executed by your test. To calculate the number
of lines executed by your test, we can use the third command
The fourth command
does the same thing, but with branches.
Sources:
MIT OPEN COURSEWAR
DEV TO