From 88d57f26b935671cdb69a5abecaa6e5452a65758 Mon Sep 17 00:00:00 2001 From: Kumar Appaiah Date: Wed, 27 Jul 2016 12:32:46 +0530 Subject: [PATCH 01/13] Add basic make notes --- slides/build-tools/Makefile | 6 ++++++ slides/build-tools/build-tools.rst | 31 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 slides/build-tools/Makefile create mode 100644 slides/build-tools/build-tools.rst diff --git a/slides/build-tools/Makefile b/slides/build-tools/Makefile new file mode 100644 index 0000000..7ec58de --- /dev/null +++ b/slides/build-tools/Makefile @@ -0,0 +1,6 @@ +RST2S5 = $(shell if which rst2s5.py > /dev/null; then echo rst2s5.py; else echo rst2s5; fi) + +all: build-tools.html + +build-tools.html: build-tools.rst + $(RST2S5) --theme=small-white $< $@ diff --git a/slides/build-tools/build-tools.rst b/slides/build-tools/build-tools.rst new file mode 100644 index 0000000..f5ad697 --- /dev/null +++ b/slides/build-tools/build-tools.rst @@ -0,0 +1,31 @@ +======================= +An introduction to Make +======================= + +.. class:: center + + July 27, 2016 + + Department of Electrical Engineering, + IIT Bombay + + :Author: Kumar Appaiah + + + +Agenda +====== + +- Introduction to build tools + +- Makefiles: simple examples + +- Writing good make rules + +- Advanced concepts + + +Motivation +================== + + $ make From fcc2eadb28ee1ea5ebccdb4c0dcb6d29955efa39 Mon Sep 17 00:00:00 2001 From: Kumar Appaiah Date: Wed, 27 Jul 2016 12:33:51 +0530 Subject: [PATCH 02/13] Add clean rule to Makefile --- slides/build-tools/Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/slides/build-tools/Makefile b/slides/build-tools/Makefile index 7ec58de..7f7c393 100644 --- a/slides/build-tools/Makefile +++ b/slides/build-tools/Makefile @@ -4,3 +4,8 @@ all: build-tools.html build-tools.html: build-tools.rst $(RST2S5) --theme=small-white $< $@ + +.PHONY: clean + +clean: + $(RM) build-tools.html From 650ca3b94298a51e2eb3d22269fc3a4d4755e678 Mon Sep 17 00:00:00 2001 From: Kumar Appaiah Date: Wed, 27 Jul 2016 13:06:31 +0530 Subject: [PATCH 03/13] Add a basic make example --- .../Figures/example-dependencies.svg | 172 ++++++++++++++++++ slides/build-tools/build-tools.rst | 46 ++++- 2 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 slides/build-tools/Figures/example-dependencies.svg diff --git a/slides/build-tools/Figures/example-dependencies.svg b/slides/build-tools/Figures/example-dependencies.svg new file mode 100644 index 0000000..92cd429 --- /dev/null +++ b/slides/build-tools/Figures/example-dependencies.svg @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + mylib.h + + mylib.c + + + main.c + + + + + diff --git a/slides/build-tools/build-tools.rst b/slides/build-tools/build-tools.rst index f5ad697..9e6575c 100644 --- a/slides/build-tools/build-tools.rst +++ b/slides/build-tools/build-tools.rst @@ -26,6 +26,48 @@ Agenda Motivation -================== +========== + +- Much of what we write is code that is compiled/built/rendered + +- Single run of ``gcc``, ``pdflatex``, etc. is easy + +- But what about large code trees, or large documents, bib files etc.? + +Motivation +========== + +- Simple: create a ``build.sh`` to compile + +- Problem: wastes time recompiling even when not needed + +- What we really need: something that builds only what is needed based + on some **rules** + +- Potential solutions: ``make``, ``ant``, ``scons``, ``qmake``, + ``jam`` and many more + +- We restrict this treatment to **GNU Make** + +Example +======= +``mylib.h``:: + + int myadd(int a, int b); + +``mylib.c``:: + + int myadd(int a, int b) { return a + b; } + +``main.c``:: + + #include "mylib.h" + int main(void) { int a = myadd(2, 3); return 0; } + +Example +======= + +.. image:: Figures/example-dependencies.svg + :scale: 50% + :align: center - $ make From 34f68a5d10c883b2ca89ba13f2f0e5e51e0b39fd Mon Sep 17 00:00:00 2001 From: Kumar Appaiah Date: Tue, 2 Aug 2016 16:46:47 +0530 Subject: [PATCH 04/13] Expand my make example --- slides/build-tools/build-tools.rst | 51 +++++++++++++++++++++++++ slides/build-tools/example-1/.gitignore | 2 + slides/build-tools/example-1/Makefile | 8 ++++ slides/build-tools/example-1/main.c | 7 ++++ slides/build-tools/example-1/mylib.c | 7 ++++ slides/build-tools/example-1/mylib.h | 7 ++++ 6 files changed, 82 insertions(+) create mode 100644 slides/build-tools/example-1/.gitignore create mode 100644 slides/build-tools/example-1/Makefile create mode 100644 slides/build-tools/example-1/main.c create mode 100644 slides/build-tools/example-1/mylib.c create mode 100644 slides/build-tools/example-1/mylib.h diff --git a/slides/build-tools/build-tools.rst b/slides/build-tools/build-tools.rst index 9e6575c..c98af63 100644 --- a/slides/build-tools/build-tools.rst +++ b/slides/build-tools/build-tools.rst @@ -71,3 +71,54 @@ Example :scale: 50% :align: center +Note that changing ``mylib.h`` would require rebuilding ``main.c`` and +``mylib.c``, but not so if you edit any of the C files. + +Steps to build +============== + +1. ``gcc -c main.c -o main.o`` +2. ``gcc -c mylib.c -o mylib.o`` +3. ``gcc -o main main.o mylib.o`` + +How do we write a Makefile for this? + +Our first Makefile +================== +Format:: + + target: prerequisites + recipe + +Rule for the build:: + + main: main.o + gcc -c main.c -o main.o + gcc -c mylib.c -o mylib.o + gcc -o main main.o mylib.o + +Our first Makefile +================== +Run:: + + # make + gcc -c main.c -o main.o + gcc -c mylib.c -o mylib.o + gcc -o main main.o mylib.o + # make + make: 'main' is up to date. + +Issue: Even updating main.c will cause a recompile of all files. + +Our first Makefile v2 +===================== +Makefile:: + + main: main.o mylib.o + gcc -o main main.o mylib.o + + main.o: main.c mylib.h + gcc -c -o main.o main.c + + mylib.o: mylib.c mylib.h + gcc -c -o mylib.o mylib.c diff --git a/slides/build-tools/example-1/.gitignore b/slides/build-tools/example-1/.gitignore new file mode 100644 index 0000000..15afbc5 --- /dev/null +++ b/slides/build-tools/example-1/.gitignore @@ -0,0 +1,2 @@ +*.c +main diff --git a/slides/build-tools/example-1/Makefile b/slides/build-tools/example-1/Makefile new file mode 100644 index 0000000..70de448 --- /dev/null +++ b/slides/build-tools/example-1/Makefile @@ -0,0 +1,8 @@ +main: main.o mylib.o + gcc -o main main.o mylib.o + +main.o: main.c mylib.h + gcc -c -o main.o main.c + +mylib.o: mylib.c mylib.h + gcc -c -o mylib.o mylib.c diff --git a/slides/build-tools/example-1/main.c b/slides/build-tools/example-1/main.c new file mode 100644 index 0000000..97c1aef --- /dev/null +++ b/slides/build-tools/example-1/main.c @@ -0,0 +1,7 @@ +#include "mylib.h" +int +main(void) +{ + int a = myadd(2, 3); + return 0; +} diff --git a/slides/build-tools/example-1/mylib.c b/slides/build-tools/example-1/mylib.c new file mode 100644 index 0000000..238fa7a --- /dev/null +++ b/slides/build-tools/example-1/mylib.c @@ -0,0 +1,7 @@ +#include "mylib.h" + +int +myadd(int a, int b) +{ + return a + b; +} diff --git a/slides/build-tools/example-1/mylib.h b/slides/build-tools/example-1/mylib.h new file mode 100644 index 0000000..c12f3b9 --- /dev/null +++ b/slides/build-tools/example-1/mylib.h @@ -0,0 +1,7 @@ +#ifndef MYLIB_H +#define MYLIB_H + +int +myadd(int a, int b); + +#endif From 487ef148b17fc85938533397e92099dfc0676f64 Mon Sep 17 00:00:00 2001 From: Kumar Appaiah Date: Sat, 6 Aug 2016 12:11:51 +0530 Subject: [PATCH 05/13] Fix incorrect gitignore --- slides/build-tools/example-1/.gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/slides/build-tools/example-1/.gitignore b/slides/build-tools/example-1/.gitignore index 15afbc5..b8a7662 100644 --- a/slides/build-tools/example-1/.gitignore +++ b/slides/build-tools/example-1/.gitignore @@ -1,2 +1,4 @@ -*.c +*.o main + + From 8727df6ff61474292b3a38d24e0c287318cc9689 Mon Sep 17 00:00:00 2001 From: Kumar Appaiah Date: Sat, 6 Aug 2016 12:12:07 +0530 Subject: [PATCH 06/13] Add more make examples --- slides/build-tools/example-1/Makefile-2 | 8 ++++++++ slides/build-tools/example-1/Makefile-3 | 8 ++++++++ 2 files changed, 16 insertions(+) create mode 100644 slides/build-tools/example-1/Makefile-2 create mode 100644 slides/build-tools/example-1/Makefile-3 diff --git a/slides/build-tools/example-1/Makefile-2 b/slides/build-tools/example-1/Makefile-2 new file mode 100644 index 0000000..3826557 --- /dev/null +++ b/slides/build-tools/example-1/Makefile-2 @@ -0,0 +1,8 @@ +objects = main.o mylib.o +main: $(objects) + +main.o: mylib.h +mylib.o: mylib.h +.PHONY: clean +clean: + rm main $(objects) diff --git a/slides/build-tools/example-1/Makefile-3 b/slides/build-tools/example-1/Makefile-3 new file mode 100644 index 0000000..4d1de55 --- /dev/null +++ b/slides/build-tools/example-1/Makefile-3 @@ -0,0 +1,8 @@ +objects = main.o mylib.o +main: $(objects) + +$(objects): mylib.h + +.PHONY: clean +clean: + rm main $(objects) From eec3551da53e3b5c562237f423719f404b1bdd28 Mon Sep 17 00:00:00 2001 From: Kumar Appaiah Date: Sat, 6 Aug 2016 12:12:40 +0530 Subject: [PATCH 07/13] Add more examples for the presentation --- slides/build-tools/build-tools.rst | 55 ++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/slides/build-tools/build-tools.rst b/slides/build-tools/build-tools.rst index c98af63..f2a25f7 100644 --- a/slides/build-tools/build-tools.rst +++ b/slides/build-tools/build-tools.rst @@ -122,3 +122,58 @@ Makefile:: mylib.o: mylib.c mylib.h gcc -c -o mylib.o mylib.c + +Cleaning up: phony rules +======================== +We can use ``make`` to handle cleanups as well:: + + clean: + rm mylib.o main.o main + +Issue: what if you create a file called ``clean``? Ignore it by +calling it a ``.PHONY``:: + + .PHONY: clean + + clean: + rm mylib.o main.o main + +Simplifying with variables, implicit rules +========================================== +Example:: + + objects = main.o mylib.o + main: $(objects) + + main.o: mylib.h + mylib.o: mylib.h + .PHONY: clean + clean: + rm main $(objects) + +Another style +============= +Example:: + + objects = main.o mylib.o + main: $(objects) + + $(objects): mylib.h + + .PHONY: clean + clean: + rm main $(objects) + +Another style +============= +Suppose that ``main.o`` depends on ``mylib.h`` and ``main.h`` and ``mylib.o`` depends +on ``mylib.h`` and ``utils.h``, then:: + + objects = main.o mylib.o + main: $(objects) + + $(objects): mylib.h + main.o: main.h + mylib.o: utils.h + + .PHONY: ... From 4ab7b606047ddbd4db5a224bc991f3b03acdd3f8 Mon Sep 17 00:00:00 2001 From: Kumar Appaiah Date: Sat, 6 Aug 2016 16:12:40 +0530 Subject: [PATCH 08/13] Move to advanced make concepts --- slides/build-tools/build-tools.rst | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/slides/build-tools/build-tools.rst b/slides/build-tools/build-tools.rst index f2a25f7..eec4a72 100644 --- a/slides/build-tools/build-tools.rst +++ b/slides/build-tools/build-tools.rst @@ -177,3 +177,31 @@ on ``mylib.h`` and ``utils.h``, then:: mylib.o: utils.h .PHONY: ... + +Handling errors during clean +============================ + +- As you may have seen in bash, commands return status messages + +- ``make`` passes the status to the shell + +- Usually useful, except when using the ``clean`` rule + +- Avoid error status with ``clean`` rule by prepending the commands + with a hyphen + +Handling errors during clean +============================ +Example to handle ``clean``:: + + objects = main.o mylib.o + main: $(objects) + + $(objects): mylib.h + + .PHONY: clean + clean: + -rm main $(objects) + +Rules for multiple targets +========================== From 61b04d9e06b19387bf9ab2217ad5f9735e2f20cd Mon Sep 17 00:00:00 2001 From: Kumar Appaiah Date: Sat, 6 Aug 2016 16:13:15 +0530 Subject: [PATCH 09/13] Add second make example --- slides/build-tools/example-2/Makefile | 10 ++++++++++ slides/build-tools/example-2/file1.tex | 4 ++++ slides/build-tools/example-2/file2.tex | 4 ++++ slides/build-tools/example-2/file3.tex | 4 ++++ 4 files changed, 22 insertions(+) create mode 100644 slides/build-tools/example-2/Makefile create mode 100644 slides/build-tools/example-2/file1.tex create mode 100644 slides/build-tools/example-2/file2.tex create mode 100644 slides/build-tools/example-2/file3.tex diff --git a/slides/build-tools/example-2/Makefile b/slides/build-tools/example-2/Makefile new file mode 100644 index 0000000..edd8061 --- /dev/null +++ b/slides/build-tools/example-2/Makefile @@ -0,0 +1,10 @@ +FILES = file1.pdf file2.pdf file3.pdf + +all: $(FILES) + +%.pdf: %.tex + pdflatex $< + +.PHONY: clean +clean: + $(RM) $(FILES) diff --git a/slides/build-tools/example-2/file1.tex b/slides/build-tools/example-2/file1.tex new file mode 100644 index 0000000..82255ff --- /dev/null +++ b/slides/build-tools/example-2/file1.tex @@ -0,0 +1,4 @@ +\documentclass{article} +\begin{document} +This is file 1. +\end{document} diff --git a/slides/build-tools/example-2/file2.tex b/slides/build-tools/example-2/file2.tex new file mode 100644 index 0000000..df626ad --- /dev/null +++ b/slides/build-tools/example-2/file2.tex @@ -0,0 +1,4 @@ +\documentclass{article} +\begin{document} +This is file 2. +\end{document} diff --git a/slides/build-tools/example-2/file3.tex b/slides/build-tools/example-2/file3.tex new file mode 100644 index 0000000..8677b3b --- /dev/null +++ b/slides/build-tools/example-2/file3.tex @@ -0,0 +1,4 @@ +\documentclass{article} +\begin{document} +This is file 3. +\end{document} From 643f24134611fd52b39056eb4f0cd848f590241f Mon Sep 17 00:00:00 2001 From: Kumar Appaiah Date: Sat, 6 Aug 2016 16:28:40 +0530 Subject: [PATCH 10/13] Fix example makefile --- slides/build-tools/example-2/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/slides/build-tools/example-2/Makefile b/slides/build-tools/example-2/Makefile index edd8061..30c428e 100644 --- a/slides/build-tools/example-2/Makefile +++ b/slides/build-tools/example-2/Makefile @@ -1,4 +1,6 @@ -FILES = file1.pdf file2.pdf file3.pdf +FILES := file1.pdf file2.pdf file3.pdf +AUXFILES := $(FILES:.pdf=.aux) +LOGFILES := $(FILES:.pdf=.log) all: $(FILES) @@ -7,4 +9,4 @@ all: $(FILES) .PHONY: clean clean: - $(RM) $(FILES) + $(RM) $(FILES) $(AUXFILES) $(LOGFILES) From a25208b4bc04e081c62f5b8e9897d1595f52c529 Mon Sep 17 00:00:00 2001 From: Kumar Appaiah Date: Sat, 6 Aug 2016 16:28:48 +0530 Subject: [PATCH 11/13] Add second example with variables --- slides/build-tools/build-tools.rst | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/slides/build-tools/build-tools.rst b/slides/build-tools/build-tools.rst index eec4a72..64ac4b9 100644 --- a/slides/build-tools/build-tools.rst +++ b/slides/build-tools/build-tools.rst @@ -142,7 +142,7 @@ Simplifying with variables, implicit rules ========================================== Example:: - objects = main.o mylib.o + objects := main.o mylib.o main: $(objects) main.o: mylib.h @@ -155,7 +155,7 @@ Another style ============= Example:: - objects = main.o mylib.o + objects := main.o mylib.o main: $(objects) $(objects): mylib.h @@ -169,7 +169,7 @@ Another style Suppose that ``main.o`` depends on ``mylib.h`` and ``main.h`` and ``mylib.o`` depends on ``mylib.h`` and ``utils.h``, then:: - objects = main.o mylib.o + objects := main.o mylib.o main: $(objects) $(objects): mylib.h @@ -194,7 +194,7 @@ Handling errors during clean ============================ Example to handle ``clean``:: - objects = main.o mylib.o + objects := main.o mylib.o main: $(objects) $(objects): mylib.h @@ -205,3 +205,15 @@ Example to handle ``clean``:: Rules for multiple targets ========================== +Example:: + + FILES := file1.pdf file2.pdf file3.pdf + AUXFILES := $(FILES:.pdf=.aux) + LOGFILES := $(FILES:.pdf=.log) + all: $(FILES) + %.pdf: %.tex + pdflatex $< + .PHONY: clean + clean: + $(RM) $(FILES) $(AUXFILES) $(LOGFILES) + From 8f9144f49027bac994fc4fcda5c31addecf5f9a3 Mon Sep 17 00:00:00 2001 From: Kumar Appaiah Date: Mon, 8 Aug 2016 14:38:30 +0530 Subject: [PATCH 12/13] Minor neatness fix in Makefile --- slides/build-tools/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/slides/build-tools/Makefile b/slides/build-tools/Makefile index 7f7c393..8c8d8b7 100644 --- a/slides/build-tools/Makefile +++ b/slides/build-tools/Makefile @@ -1,4 +1,5 @@ -RST2S5 = $(shell if which rst2s5.py > /dev/null; then echo rst2s5.py; else echo rst2s5; fi) +RST2S5 = $(shell if which rst2s5.py > /dev/null; \ +then echo rst2s5.py; else echo rst2s5; fi) all: build-tools.html From 584f8b6d6df1999f6a3f3c76177e16fdba7f5e91 Mon Sep 17 00:00:00 2001 From: Kumar Appaiah Date: Mon, 8 Aug 2016 14:38:40 +0530 Subject: [PATCH 13/13] Add shell example in make notes --- slides/build-tools/build-tools.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/slides/build-tools/build-tools.rst b/slides/build-tools/build-tools.rst index 64ac4b9..9df9329 100644 --- a/slides/build-tools/build-tools.rst +++ b/slides/build-tools/build-tools.rst @@ -217,3 +217,17 @@ Example:: clean: $(RM) $(FILES) $(AUXFILES) $(LOGFILES) + +Handling shell requests +======================= +Example: This presentation is built with ``rst2s5``. But some people +have it in their computer as ``rst2s5.py``. To handle both:: + + RST2S5 = $(shell if which rst2s5.py > /dev/null; \ + then echo rst2s5.py; else echo rst2s5; fi) + all: build-tools.html + build-tools.html: build-tools.rst + $(RST2S5) --theme=small-white $< $@ + .PHONY: clean + clean: + $(RM) build-tools.html