Makefile: Quote all $@ and $< expansion
[assignment-template.git] / Makefile
1 # Copyright (C) 2012-2013  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 RUN_PROGRAM = hello_world
28 SCRIPTS = 
29 C_PROGRAMS = hello_world
30 CXX_PROGRAMS = goodbye_world
31 PROGRAMS = $(C_PROGRAMS) $(CXX_PROGRAMS)
32
33 # Define the source files that will be distributed in the tarball
34 SOURCE = *.c *.cpp *.h COPYING Makefile README $(SCRIPTS)
35
36 # Define a list of object files needed to link PROGRAM.  We're setting
37 # things up here so that a program % depends on the object file %.o.
38 # For details on `foreach` and `eval`, see
39 #   http://www.gnu.org/software/make/manual/html_node/Foreach-Function.html
40 #   http://www.gnu.org/software/make/manual/html_node/Eval-Function.html
41 $(foreach PROGRAM, $(PROGRAMS), $(eval $(PROGRAM)_OBJECTS = $(PROGRAM).o))
42
43 # You can override a paricular case here with something like:
44 #hello_world_OBJECTS = hello_world.o utility_code.o
45
46 # You may want to link agains external libraries.  For example, to
47 # link against the system math library, use.
48 #   hello_world_LIBS = -lm
49 $(foreach PROGRAM, $(PROGRAMS), $(eval $(PROGRAM)_LIBS =))
50
51 # Define useful programs (this makes it easy to swap in alternates)
52 CP = cp
53 GREP = grep
54 MKDIR = mkdir
55 RM = rm
56 TAR = tar
57
58 # Declare targets that do not generate files of the same name.
59 #   http://www.gnu.org/software/make/manual/html_node/Phony-Targets.html
60 .PHONY: all help clean dist run print- printvars
61
62 # target: all - the default target
63 # The target of the first rule is the default goal.  See:
64 #   http://www.gnu.org/software/make/manual/html_node/Rules.html
65 all: $(PROGRAMS)
66
67 # target: help - display callable targets
68 # Use `grep` to search this file for target comments
69 help:
70         $(GREP) '^# target:' [Mm]akefile
71
72 # target: clean - remove automatically generated files
73 clean:
74         $(RM) -rf $(PROGRAMS) *.o $(RELEASE)*
75
76 # target: dist - generate a tarball packaging the source
77 # Here, we move the source into a temporary release directory, tar the
78 # release directory, and remove the release directory.
79 dist:
80         $(MKDIR) $(RELEASE)
81         $(CP) -r $(SOURCE) $(RELEASE)
82         $(TAR) -czf $(RELEASE).tar.gz $(RELEASE)
83         $(RM) -rf $(RELEASE)
84
85 # target: hello_world - compile the hello_world program
86 # Use GCC to link the program from object files.
87 # For an explanation of the
88 #   targets ...: target-pattern: prereq-patterns ...
89 # syntax, see
90 #   http://www.gnu.org/software/make/manual/html_node/Static-Usage.html
91 # For an explanation of $@, $^, and other special variables, see
92 #   http://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html
93 # For an explanation of .SECONDEXPANSION, see
94 #   http://www.gnu.org/software/make/manual/html_node/Secondary-Expansion.html
95 # `$$` escapes make-variable expansion for the first pass through the
96 # recipe.  See
97 #   http://www.gnu.org/software/make/manual/html_node/Variables-in-Recipes.html
98 #
99 # What's going on here?  During the read-in phase, Make expands the
100 # rule to
101 #   hello_world goodbye_world: % : $($(@)_OBJECTS)
102 # Because we're using .SECONDEXPANSION, Make expands the prerequisites
103 # again during the target-update phase.  If we're building
104 # hello_world, $(@) will expand to hello_world, and we'll have
105 #   hello_world goodbye_world: hello_world : $(hello_world_OBJECTS)
106 # as the variable expansion continues, we end up with
107 #   hello_world goodbye_world: hello_world : hello_world.o
108 # which is the final rule used to determine the prerequisites.
109 #
110 # The recipe expands to
111 #   cc  -o hello_world hello_world.o $(hello_world_LIBS)
112 # which expands to (if hello_world_LIBS was set to `-lm`)
113 #   cc  -o hello_world hello_world.o -lm
114 #
115 # Striking the right balance between "everything handled
116 # automatically" (i.e. "complicated") and "everything handled
117 # manually" (i.e. tedious) is difficult, and maybe this rule crosses
118 # the line.  The simpler alternative would be to define your own
119 # prerequisites for each program you wish to compile, and you're
120 # certainly allowed to go that route if you wish.
121 .SECONDEXPANSION:
122 $(C_PROGRAMS): % : $$($$(@)_OBJECTS)
123         $(CC) $(LDFLAGS) -o "$@" $^ $($(@)_LIBS)
124
125 .SECONDEXPANSION:
126 $(CXX_PROGRAMS): % : $$($$(*)_OBJECTS)
127         $(CXX) $(LDFLAGS) -o "$@" $^ $($(@)_LIBS)
128
129 # target: run - use the program for its intended purpose
130 # Here we just execute RUN_PROGRAM, but you could also use something
131 # like
132 #   run: $(RUN_PROGRAM) plot.gp
133 #     ./$(RUN_PROGRAM) > data
134 #     gnuplot plot.gp
135 # where plot.gp was a gnuplot script for plotting data generated by
136 # RUN_PROGRAM.
137 run: $(PROGRAMS)
138         ./$(RUN_PROGRAM)
139
140 # Pattern rule for compiling object files from C++ source
141 # There is an implicit rule for this in GNU make
142 #   http://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html
143 # but I redefine it here for clarity.  For an explanation of the
144 #   %.o: %.cpp
145 # syntax, see
146 #   http://www.gnu.org/software/make/manual/html_node/Pattern-Intro.html
147 #
148 # CXX and CXXFLAGS have defaults defined by make
149 #   http://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
150 # but they can also be come from the environment
151 #   http://www.gnu.org/software/make/manual/html_node/Environment.html
152 # for example, try
153 #    $ make CXX=/usr/local/bin/g++ CXXFLAGS=-Wall
154 %.o: %.cpp
155         $(CXX) $(CXXFLAGS) -c "$<"
156
157 # Pattern rule for compiling object files from C source
158 # The comments from the C++ rule above also apply here
159 %.o: %.c
160         $(CC) $(CFLAGS) -c "$<"
161
162 # target: print-% - display a variable value (e.g. print-PROGRAMS)
163 # Take some of the mystery out of variable manipulation.  For example,
164 #   $ make print-hello_world_OBJECTS
165 # The `@` suppresses recipe echoing.  See
166 #   http://www.gnu.org/software/make/manual/html_node/Echoing.html
167 # The `info` function acts like the shell `echo` command.  See
168 #   http://www.gnu.org/software/make/manual/html_node/Make-Control-Functions.html
169 # For an explanation of $* and other special variables, see
170 #   http://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html
171 print-%:
172         @$(info $* = $($*))
173
174 # target: printvars - display all non-default variables
175 # .VARIBALES holds a list of all global variables.  See
176 #   http://www.gnu.org/software/make/manual/html_node/Special-Variables.html
177 # The functions---`sort`, `if`, `filter-out`, `origin`, `warning`, and
178 # `value`--- are discussed, respectively, here:
179 #   http://www.gnu.org/software/make/manual/html_node/Text-Functions.html#index-sort-580
180 #   http://www.gnu.org/software/make/manual/html_node/Conditional-Functions.html
181 #   http://www.gnu.org/software/make/manual/html_node/Text-Functions.html#index-filter_002dout-577
182 #   http://www.gnu.org/software/make/manual/html_node/Origin-Function.html
183 #   http://www.gnu.org/software/make/manual/html_node/Value-Function.html
184 printvars:
185         @$(foreach V, \
186                 $(sort $(.VARIABLES)), \
187                 $(if \
188                         $(filter-out environment default automatic, \
189                                 $(origin $V)), \
190                         $(info $V=$($V) (origin: $(origin $V), value: $(value $V))) \
191                         ) \
192                 )