Makefile: Add print-% and printvars rules for Makefile introspection.
[assignment-template.git] / Makefile
1 # Copyright (C) 2012  W. Trevor King
2 #
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation, either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 # Declare variables describing package information.
17 #   http://www.gnu.org/software/make/manual/html_node/Setting.html
18 # The $(...) syntax references a variable's value.
19 #   http://www.gnu.org/software/make/manual/html_node/Reference.html
20 # You can override variables from the command line.  For example
21 #   $ make VERSION=2 dist
22 # will generate phys405-hw0-2.tar.gz
23 COURSE = phys405
24 PACKAGE = hw0
25 VERSION = 1
26 RELEASE = $(COURSE)-$(PACKAGE)-$(VERSION)
27 PROGRAM = hello_world
28
29 # Define the source files that will be distributed in the tarball
30 SOURCE = *.c COPYING Makefile README
31
32 # Define a list of object files needed to link PROGRAM
33 OBJECTS = $(PROGRAM).o
34
35 # You may want to link agains external libraries.  For example, to
36 # link against the system math library, use.
37 #   LIBS = -lm
38 LIBS =
39
40 # Define useful programs (this makes it easy to swap in alternates)
41 CP = cp
42 GREP = grep
43 MKDIR = mkdir
44 RM = rm
45 TAR = tar
46
47 # Declare targets that do not generate files of the same name.
48 #   http://www.gnu.org/software/make/manual/html_node/Phony-Targets.html
49 .PHONY: all help clean dist run print- printvars
50
51 # target: all - the default target
52 all: $(PROGRAM)
53
54 # target: help - display callable targets
55 # Use `grep` to search this file for target comments
56 help:
57         $(GREP) '^# target:' [Mm]akefile
58
59 # target: clean - remove automatically generated files
60 clean:
61         $(RM) -rf $(PROGRAM) *.o $(RELEASE)*
62
63 # target: dist - generate a tarball packaging the source
64 # Here, we move the source into a temporary release directory, tar the
65 # release directory, and remove the release directory.
66 dist:
67         $(MKDIR) $(RELEASE)
68         $(CP) -r $(SOURCE) $(RELEASE)
69         $(TAR) -czf $(RELEASE).tar.gz $(RELEASE)
70         $(RM) -rf $(RELEASE)
71
72 # target: hello_world - compile the hello_world program
73 # Use GCC to link the program from object files.
74 $(PROGRAM): $(OBJECTS)
75         $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
76
77 # target: run - use the program for its intended purpose
78 # Here we just execute PROGRAM, but you could also use something like
79 #   run: $(PROGRAM) plot.gp
80 #     ./$(PROGRAM) > data
81 #     gnuplot plot.gp
82 # where plot.gp was a gnuplot script for plotting data generated by
83 # PROGRAM.
84 run: $(PROGRAM)
85         ./$(PROGRAM)
86
87 # Matching rule for compiling object files from C++ source
88 # There is an implicit rule for this in GNU make
89 #   http://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html
90 # but I redefine it here for clarity.
91 #
92 # CXX and CXXFLAGS have defaults defined by make
93 #   http://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
94 # but they can also be come from the environment
95 #   http://www.gnu.org/software/make/manual/html_node/Environment.html
96 # for example, try
97 #    $ make CXX=/usr/local/bin/g++ CXXFLAGS=-Wall
98 %.o: %.cpp
99         $(CXX) $(CXXFLAGS) -c $<
100
101 # Matching rule for compiling object files from C source
102 # The comments from the C++ rule above also apply here
103 %.o: %.c
104         $(CC) $(CFLAGS) -c $<
105
106 # target: print-% - display a variable value (e.g. print-PROGRAMS)
107 # Take some of the mystery out of variable manipulation.  For example,
108 #   $ make print-hello_world_OBJECTS
109 # The `@` suppresses recipe echoing.  See
110 #   http://www.gnu.org/software/make/manual/html_node/Echoing.html
111 # The `info` function acts like the shell `echo` command.  See
112 #   http://www.gnu.org/software/make/manual/html_node/Make-Control-Functions.html
113 # For an explanation of $* and other special variables, see
114 #   http://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html
115 print-%:
116         @$(info $* = $($*))
117
118 # target: printvars - display all non-default variables
119 # .VARIBALES holds a list of all global variables.  See
120 #   http://www.gnu.org/software/make/manual/html_node/Special-Variables.html
121 # The functions---`sort`, `if`, `filter-out`, `origin`, `warning`, and
122 # `value`--- are discussed, respectively, here:
123 #   http://www.gnu.org/software/make/manual/html_node/Text-Functions.html#index-sort-580
124 #   http://www.gnu.org/software/make/manual/html_node/Conditional-Functions.html
125 #   http://www.gnu.org/software/make/manual/html_node/Text-Functions.html#index-filter_002dout-577
126 #   http://www.gnu.org/software/make/manual/html_node/Origin-Function.html
127 #   http://www.gnu.org/software/make/manual/html_node/Value-Function.html
128 printvars:
129         @$(foreach V, \
130                 $(sort $(.VARIABLES)), \
131                 $(if \
132                         $(filter-out environment default automatic, \
133                                 $(origin $V)), \
134                         $(info $V=$($V) (origin: $(origin $V), value: $(value $V))) \
135                         ) \
136                 )