divzeroweb

2f30.org website
git clone git://git.2f30.org/divzeroweb
Log | Files | Refs | README | LICENSE

commit 49bc55a0489751ef0a73b7bb0ec0a0fb2ac75aa4
parent 46c17f9a2e657a797fb9dd994929196e573523ec
Author: lostd <lostd@2f30.org>
Date:   Thu,  6 Nov 2014 17:26:03 +0200

The first part of a tutorial for using make(1)

Diffstat:
Aguides/make.md | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 103 insertions(+), 0 deletions(-)

diff --git a/guides/make.md b/guides/make.md @@ -0,0 +1,103 @@ +### How to make and make clean + +Do you write Makefiles? Do you want them to be fairly portable? Then +continue reading this. Here are some things that I keep in mind when +dealing with builds and `make`. First of all, there are cases where you +can use `make` without a Makefile. For example, if you have a simple +`test.c` just to quickly try something you can do: + + $ make test + cc -O2 -pipe -o test test.c + +And if you need some preprocessor flags: + + $ CPPFLAGS=-DDEBUG make test + cc -O2 -pipe -DDEBUG -o test test.c + +And if you also need to link with a library: + + $ CPPFLAGS=-DDEBUG LDLIBS=-lpcap make test + cc -O2 -pipe -DDEBUG -o test test.c -lpcap + +More flags or libs can be inserted like this: + + $ CPPFLAGS=-DDEBUG LDLIBS="-lpcap -lm" make test + cc -O2 -pipe -DDEBUG -o test test.c -lpcap -lm + +The reason these work is that most `make` implementations have inference +rules and default variable values, so they know how to build binaries +from certain files using the source file extension. To see the list of +inference rules do this on a Makefile-less directory: + + $ make -p + +Now it should make more sense why and how the builds worked. For +development in C these are the important variables: + + CC -- Compiler + CPPFLAGS -- Preprocessor flags + CFLAGS -- Compile flags + LDFLAGS -- Link flags + LDLIBS -- Libraries to link with + +For C++ you also have: + + CXX -- Compiler + CXXFLAGS -- Compile flags + +On the previous command line examples we define those as shell +environment variables and they are instantiated as make variables as +well. We could also provide them as command line arguments to the +`make` command: + + $ make CPPFLAGS=-DDEBUG LDLIBS=-lpcap test + cc -O2 -pipe -DDEBUG -o test test.c -lpcap + +And double quotes also work there: + + $ make CPPFLAGS=-DDEBUG LDLIBS="-lpcap -lm" test + cc -O2 -pipe -DDEBUG -o test test.c -lpcap -lm + +Now instead of writing all these variables every time you may create a +simple Makefile to handle that part, but still rely on inference rules: + + CPPFLAGS = -DDEBUG + LDLIBS = -lpcap -lm + +Assuming the above Makefile, now type: + + $ make test + cc -O2 -pipe -DDEBUG -o test test.c -lpcap -lm + +Now let's add a default target so that we also avoid typing that. It is +customary that this default target is named `all`. Our Makefile now +becomes: + + CPPFLAGS = -DDEBUG + LDLIBS = -lpcap -lm + + all: test + +Just do: + + $ make + cc -O2 -pipe -DDEBUG -o test test.c -lpcap -lm + +It is also common to have a `clean` target as well. Add the following: + + clean: + rm -f test + +Note that the shell command under the dependency line begins with a tab +character. The dependency here is empty and will always be unsatisfied, +so the `rm` command will always run: + + $ make clean + rm -f test + +That is true unless a file named `clean` appears in the filesystem. If +you want to ensure that such rules are not affected by this artifact you +can declare that they are special rules that are always evaluated. +Simple add: + + .PHONY: all clean