Today I learned how makefiles work. Makefile is a recipe of what commands to run and in what sequence to compile or build your software. Usually, a makefile will look like that:
obj_files = foo.c bar.c
.PHONY: all
all: $(obj_files)
echo "Done!"
foo.c:
echo "int main() { return 0; }" > foo.c
bar.c:
touch $@
clean:
rm -f *.c *.o all
looks scary? let’s go line by line and see what it means:
The first line obj_files = foo.c bar.c just statically says that we have 2 configured files, foo.c, and bar.c.
Next, .PHONY: all means that we ignore a file/directory name “all”. Makefiles have special meaning for files and folders names within the project, the PHONY directive just ignores it.
all: $(obj_files) is the main thing here. This like configures the bash command with “all” as the name of it:
$ make all
All it does is print “Done!” but it takes the list of files obj_files as “dependencies” and run them before the echo command. This is similar to running:
$ make foo.c
$ make bar.c
Eventually, to create foo.c it will run echo "int main() { return 0; }" > foo.c and for bar.c it will run touch bar.c. notice the $@ that is equivalent to the target name (bar.c) but as a variable. It is useful if you have a wildcard target. I’ll give you to look it up.
To sum up, running make all will do the next commands sequence:
$ make all
|__$ make foo.c
| |_$ echo "int main() { return 0; }" > foo.c
|__$ make bar.c
|_$ touch bar.c
And that’s it for now. Make and Makefiles are a powerful tool used in most places understanding how it works is a big advantage of fast and deterministic builds
Read more about makefiles here: https://makefiletutorial.com/