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:
A | guides/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