]> cloudbase.mooo.com Git - z180-stamp.git/blob - mk/Readme.txt
c341b48dfbf1e5402b1ad8fef07f842bbab950c6
[z180-stamp.git] / mk / Readme.txt
1 ################################################################################
2 # Non-recursive make build system #
3 # ------------------------------- #
4 # Copyright (C) 2012 Andrzej Ostruszka <andrzej.ostruszka@gmail.com> #
5 # #
6 # URL: http://github.com/aostruszka/nonrec-make #
7 # (or older: http://nonrec-make.googlecode.com/) #
8 # #
9 # Permission is hereby granted, free of charge, to any person obtaining a copy #
10 # of this software and associated documentation files (the "Software"), to #
11 # deal in the Software without restriction, including without limitation the #
12 # rights to use, copy, modify, merge, publish, distribute, sublicense, #
13 # and/or sell copies of the Software, and to permit persons to whom the #
14 # Software is furnished to do so, subject to the following conditions: #
15 # #
16 # The above copyright notice and this permission notice shall be included in #
17 # all copies or substantial portions of the Software. #
18 # #
19 # Except as contained in this notice, the name(s) of the above copyright #
20 # holders shall not be used in advertising or otherwise to promote the sale, #
21 # use or other dealings in this Software without prior written authorization. #
22 # #
23 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
24 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
25 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
26 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
27 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING #
28 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS #
29 # IN THE SOFTWARE. #
30 ################################################################################
31
32 NOTE: This readme _might_ not be up to date. For up to date information
33 see the above URL (and accompanying wiki pages).
34
35 This is my attempt to implement a non-recursive make build system. For
36 the motivation Google for the paper "Recursive make consider harmful" by
37 Peter Miller.
38
39 I've seen couple of other proposals and decided to have something that
40 will be a blend of nice ideas I have seen plus some improvements. If
41 you actually use this I'd like to hear from you :) - is it useful, does
42 it perform well, do you have any suggestions for the improvements ...
43 and so on. This implementation is based on GNU make and its new
44 features introduced in 3.80. But don't use that version - these
45 features had bugs in that version. Use version 3.81 where everything
46 works OK.
47
48 Before you keep on reading though, just take a look at the structure of
49 the Rules.mk files (Rules.top has exactly the same structure as Rules.mk
50 - it just has another name to ease location of the top level project
51 directory from its subfolders).
52 I've got a feeling that it is much easier to understand how the system
53 looks from the user perspective just by looking at the example than
54 reading its explanation :D.
55
56 OK, now that you have a feeling how the Rules.mk look like let me walk
57 you through an example (ex1 in the repository). Consider the project
58 that has some source files at the top directory and is depending on two
59 libraries in Dir_1 and Dir_2 and another one in Dir_3. The libraries
60 themselves are partitioned between several subdirectories and Dir_2 has
61 some examples in a separate subfolder (do not pay attention to all *.c
62 files).
63
64 ex1/
65 Makefile
66 Rules.top <- Just a symlink to Rules.mk to mark where the top level is
67 Rules.mk
68 main.c
69 top_a.c
70 top_b.c
71 cli.c
72 cli_dep.c
73 mk/* <- This is where the mk files from this build system are
74 Dir_1/
75 Makefile
76 Rules.mk
77 dir_1_file1.c
78 dir_1_file2.c
79 dir_1_file3.c
80 Dir_1a/
81 Makefile
82 Rules.mk
83 dir_1a_file1.c
84 dir_1a_file2.c
85 dir_1a_file3.c
86 Dir_1b/
87 Makefile
88 Rules.mk
89 src/
90 dir_1b_file1.c
91 dir_1b_file2.c
92 Dir_2/
93 Makefile
94 Rules.mk
95 dir_2_file1.c
96 dir_2_file2.c
97 Dir_2a/
98 Makefile
99 Rules.mk
100 dir_2a_file1.c
101 dir_2a_file2.c
102 dir_2a_file3.c
103 Dir_2b/
104 Makefile
105 Rules.mk
106 dir_2b_file1.c
107 dir_2b_file2.c
108 dir_2b_file3.c
109 Dir_ex/
110 Makefile
111 Rules.mk
112 ex.c
113 Dir_3/
114 Makefile
115 Rules.mk
116 dir_3_file1.c
117 dir_3_file2.c
118
119 There's one top level make file (Rules.top) which eventually includes
120 all the makefiles. In addition in each directory there is Makefile
121 (which can be a link to the one in the top level directory) which
122 searches for the Rules.top includes it with the default goal
123 changed to rebuild only targets for the current directory. This allows
124 you to run make from each subdirectory and update only part of the
125 targets (in contrary to other implementation which usually require
126 you to run it at the top level and make full build each time).
127
128 This build system was designed to have very simple structure of the
129 "user makefiles". The user just has to set the Rules.mk files in each
130 directory and some general configuration options. All the "magic" is
131 hidden in header.mk, footer.mk and skel.mk which don't have to be
132 modified [1].
133
134 The structure of the Rules.mk is following (this is from top level
135 Rules.top which has the same format as Rules.mk - and in fact it is
136 suggested that it should be a symlink to normal Rules.mk file since it
137 will allow for this project to act as a subproject of some super project
138 treating your whole project tree as a subdirectory[2]):
139
140 -8<---Rules.top---------------
141 1: TARGETS = app.exe cli.exe
142 2: SUBDIRS = Dir_1 Dir_2
143 3:
144 4: app.exe_DEPS = top_a.o top_b.o main.o $(SUBDIRS_TGTS)
145 5: app.exe_LIBS = -lm
146 6: # Let's use DEFAULT_MAKECMD for app.exe
147 7:
148 8: cli.exe_DEPS = cli.o cli_dep.o
149 9: cli.exe_CMD = $(LINK.c) $^ $(LDLIBS) -o $@
150 -8<---------------------------
151
152 Line 1 - this directory has two targets that should be built.
153 Line 2 - this directory has two subdirectories that should be scanned
154 Line 4 - app.exe depends on ... (SUBDIRS_TGTS is a variable that
155 contains all the targets from the subdirectories mentioned at
156 line 4)
157 Line 5 - app.exe should be linked with math library
158 Line 6 - app.exe will be built with default "rule"
159 Line 8 - cli.exe depends on ... and
160 Line 9 - use the following command to build it
161
162 You can specify the targets for current directory in two ways:
163 1. Give them in TARGETS. Each target can have it's own *_DEPS, *_LIBS
164 and *_CMD which give the dependencies, additional libs needed and
165 a command to run which will update the target. They are explained
166 a bit below.
167 2. The targets are simply objects - or in more general files that
168 match patterns in AUTO_TGTS, and have appropriate rules in 'skeleton'.
169 In that case you can list them in OBJS or SRCS like e.g. in Rules.mk
170 from Dir_1a
171
172 -8<---Dir_2/Dir_2a/Rules.mk---
173 1: SRCS := dir_2a_file1.c dir_2a_file2.c dir_2a_file3.c
174 -8<---------------------------
175
176 There are "reserved" variables that you should not modify. Most notably:
177 - $(d) is the directory of the current Rules.mk [see note 2]
178 - $(TOP) is the top level directory of the project tree
179 - $(MK) is the directory where the included *.mk makefiles are
180 For the full list you have to take a look at the makefiles in mk
181 directory (e.g. in the skel.mk there are macros 'include_subdir_rules',
182 'save_vars', 'tgt_rule' and 'skeleton' which you should not change [1]).
183
184 Going back to the Rules.mk. Normally wildcards in variable assignments
185 are not expanded in make but this make system detects wildcards in SRCS
186 and expands them (both in directory of the Rules.mk and its SRCS_VPATH
187 subdirectories - see below what SRCS_VPATH is used for). Thus you can
188 simply say in Rules.mk:
189
190 SRCS := *.c
191
192 If you have directory with large number of files where simple glob is
193 what you want to use in SRCS but there are some files that you'd like to
194 exclude just list them in SRCS_EXCLUDES :) - this is a list of makefile
195 patterns e.g.
196
197 SRCS_EXCLUDES := extra% test%
198
199 Of course you can use the built in make wildcards but you should do that
200 as follows:
201
202 SRCS := $(notdir $(wildcard $(d)/*.c))
203
204 Keep in mind that the directory where make is invoked is usually different
205 from where given Rules.mk is located.
206
207 When supplying the value for *_DEPS you can refer to the object from the
208 same directory with no directory prefix. To be specific all
209 dependencies that are not absolute paths will be treated as ones from
210 the $(OBJDIR) subdirectory of current directory (OBJDIR and OBJPATH are
211 "discussed" below). You can use SUBDIRS_TGTS variable which will list
212 all targets in subdirectories. You can also name them explicitly like
213 $(TARGETS_$(d)/subdir) and so on - see e.g. the Rules.mk in Dir_2
214 directory where Dir_ex is mentioned as a subdirectory but is excluded
215 from the *_DEPS (this allows you to create folders that "inherit" all
216 the setting from the project build system but are not meant to be a part
217 of the project itself - like examples). For instance:
218
219 dir1_lib.a_DEPS = dir_1_file1.o dir_1_file2.o dir_1_file3.o $(SUBDIRS_TGTS)
220
221 tells that dir1_lib.a (which will be created in Dir_1/$(OBJDIR)) depends
222 on several object files from the same directory and the targets from all
223 subdirectories.
224
225 One last thing about the TARGETS/OBJS. By default source files for the
226 objects are searched in the directory where Rules.mk is, but if you want
227 to have source files in a subdirectory (say 'src') you can do that via
228 SRCS_VPATH variable (see skel.mk). E.g.:
229
230 SRCS_VPATH := src1 src2
231
232 will cause make to first look at the directory where Rules.mk is present
233 and then in its src1 and src2 subdirectories.
234
235 *_LIBS are appended to the LDLIBS variable when updating the target.
236 This variable is used by several make built in rules but if you create
237 your own rule or MAKECMD.* (see next paragraph) you can refer to it (see
238 the function 'save_vars').
239
240 When *_CMD is not present and the target does not match any pattern in
241 AUTO_TGTS then either MAKECMD.suff (where .suff is the suffix of the
242 target) or DEFAULT_MAKECMD is used - take a look into skel.mk.
243
244 If you want to setup special flags for compilation you can do that via
245 "directory specific variables". As an example here's what I did for
246 compilation of C files. There's a built in rule in make which uses
247 COMPILE.c variable for making %.o out of %.c so I added $(DIR_CFLAGS) to
248 its default value and DIR_CFLAGS is defined in skel.mk as:
249
250 DIR_INCLUDES = $(addprefix -I,$(INCLUDES_$(<D)))
251 DIR_CFLAGS = $(CFLAGS_$(<D)) $(DIR_INCLUDES)
252
253 So it extracts the directory part of the first prerequisite in the rule
254 (that is %.c file - check the section 'automatic variables' in make
255 manual for the meaning of $(<) and $(<D)) and refer to variables named
256 CFLAGS_the_directory_part and INCLUDES_the_directory_part.
257 Thus if you wanted to add special includes for files in Dir_1/Dir_1b you
258 could add:
259
260 INCLUDES_$(d) := $(TOP)/some/special/include_dir
261
262 into its Rules.mk and all files in this directory will be compiled with
263 -I$(TOP)/some... switch. The same goes for CFLAGS and CXXFLAGS.
264
265 The same goes for the linker flags - quoting from skel.mk:
266
267 LDFLAGS = $(addprefix -L,$(LIBDIRS_$(subst /$(OBJDIR),,$(@D))))
268 LDLIBS = $(LIBS_$(@))
269
270 The above means that if targets in given directory need to be linked
271 with special -L switches you can provide them via LIBDIRS_$(d)
272 variables. If there are some global -L switches just append them in
273 skel.mk. The second line above shows how *_LIBS variable that you can
274 give for specific target gets added to the LDLIBS (there's 'save_vars'
275 in between if you're curious :)).
276
277 You can of course use target specific variables that GNU make supports
278 so you have more control (if you don't know what target specific
279 variables are take a look into manual). Say you want to compile
280 dir_1b_file2.c with an additional flag but all other files in
281 Dir_1/Dir_1b directory should not have this flag turned on. All you
282 need to do is to add this line into Rules.mk in Dir_1b directory.
283
284 $(OBJPATH)/dir_1b_file2.o : CFLAGS += -ansi
285
286 OBJPATH is a variable that contains the full directory where the
287 resulting object file will be placed. While we are at this, by default
288 all targets are compiled into OBJDIR (defined in skel.mk as 'obj')
289 subdirectory of the directory where Rules.mk is present. You can use
290 this OBJDIR variable (and perhaps some conditional statements) to setup
291 the output path according to your current compilation mode. E.g.
292 obj/debug for objects with debugging information or obj/ppc_7xx for
293 cross compilation to the given Power PC family and so on. There's
294 predefined (in config* files) HOST_ARCH variable that you can use for
295 this (e.g. set OBJDIR := obj/$(HOST_ARCH) in skel.mk).
296
297 Finally let me explain what targets are defined and the way you can run
298 them from command line. By default (that is if you have not modified
299 anything :)) there are several targets that are "global". It is 'all',
300 'clean_all' and 'dist_clean'. If you specify them in the command line
301 they will respectively rebuild whole tree, clean everything and clean
302 everything together with the removal of OBJDIRs - no matter from which
303 directory you started make. BTW if there's something that you want to
304 clean up and it's not in the OBJDIR - e.g. you've got file lexer.l out
305 of which lexer.c and lexer.h is generated and you want them to be
306 removed - you can specify this in the variable CLEAN (this is relative
307 to the directory where Rules.mk is).
308 In addition to those each dir has "it's own" targets. These are:
309
310 1) dir_<directory_path>
311 which builds all targets in given directory plus its dependencies
312 2) tree_<directory_path>
313 which builds all targets in subtree starting at directory given
314 3) clean_<directory_path>
315 which removes all "products" from the $(OBJDIR) subdirectory of
316 current directory
317 4) clean_tree_<directory_path>
318 which does clean_<directory_path> and the same for each its
319 subdirectory
320
321 For your convenience there are couple "aliases" defined (see Makefile).
322 When no target is given on command line it defaults to dir_$(pwd).
323 If you give 'clean' as a target that will result in execution of target
324 clean_$(pwd) and the same for 'clean_tree'. E.g. say you're in Dir_1.
325 Then:
326
327 * 'make' (same as 'make dir_$(pwd)')
328 builds all targets in the Dir_1 which in our example is
329 Dir_1/obj/dir1_lib.a - of course any of its dependencies that are not
330 up to date are updated also. This rule has one exception - if your
331 Rules.mk has no targets and only SUBDIRS (e.g. you have grouped
332 several subdirectories in one directory) then simple 'make' in this
333 directory - instead of doing nothing - will build targets of all its
334 subdirectories.
335 * 'make tree' (same as 'make tree_$(pwd)')
336 rebuilds everything in given subtree
337 * 'make clean' (same as 'make clean_$(pwd)')
338 removes everything from Dir_1/obj/
339 * 'make clean_tree (same as 'make clean_tree_$(pwd)')
340 cleans Dir_1/obj and Dir_1/Dir_1[abc]/obj
341
342 You can obviously provide the path by yourself - it does not have to
343 be $(pwd) - and as usual you can build particular object files too e.g.
344 'make $(pwd)/obj/dir_1_file1.o'
345
346 And that would be it. Gee, so much writing for something that is rather
347 simple to use - go ahead and take a look again at these Rules.mk in
348 various directories. Setting up you project should be simple by now :).
349
350 Have fun!
351
352 Andrzej Ostruszka
353
354 [1] Unless this build system does not do what you wanted :-P. In that
355 case you probably need to spiff it up. So you'll need to
356 digest it first and note [3] is my hand at it :).
357
358 [2] There is one limitation that you should be aware.
359 Prior to commit 070f681 you should not have in your project two "target
360 specific" LIBS, LDFLAGS or CMD variables (that is those that are used
361 during second phase of make execution) that have the same names! For
362 example in one part of your tree you're generating target abc which has
363 it's abc_CMD and in the other part another target that has the same name
364 and also it's own command. In such case the last assignment to abc_CMD
365 will hold and it will be used for both targets. The same goes for LIBS
366 and LDFLAGS.
367
368 And this also applied to situation when you would like to use two
369 subprojects in one larger project. There should be no clash between
370 variables from these subprojects.
371
372 Starting with commit 070f681 you can have in your (sub)projects two
373 LIBS, LDFLAGS or CMD variables. However there is a catch here! Since
374 these variables are not mandatory (you don't have to provide them for
375 each target) in order to differentiate between case where abc_CMD was
376 actually given for this instance of abc target from the situation where
377 abc_CMD is still visible from previous instance of abc target those
378 abc_(LIBS|LDFLAGS|CMD) variables are cleared once their value is
379 used/remembered (see save_vars macro in skel.mk). That means referring
380 to these variables outside Rules.mk where they were assigned will not
381 work (and even in the same Rules.mk they will work only in case of
382 simply expanded variables - not recursive). If you have such need I'd
383 advice to introduce your own variable and use this variable in all
384 places, e.g.:
385
386 MATH_LIBS := -lgsl -lgslcblas -lm
387 ...
388 TARGETS := abc
389
390 abc_DEPS = ...
391 abc_LIBS = $(MATH_LIBS)
392 ...
393
394 [3] You should know that make works in two phases - first it scans the
395 makefiles and then it begins their execution (see discussion of
396 'immediate' and 'deferred' in section 'Reading Makefiles' of make
397 manual). This implies that the $(d) variable is not valid during
398 execution of the commands used for target updates. If you need to refer
399 to the directory of the target or prerequisite you should rely on
400 automatic variables (@, <, ...) and built in functions (dir, notdir,
401 ...).
402
403 Every Rules.mk (or Rules.top) need to be included in cooperation with
404 header.mk and footer.mk. This is now done automatically but in older
405 versions this was not so and user had to include them manually.
406 The main purpose of header is to clear all variables that you can use
407 inside Rules.mk so that values set in one rules file does not propagate
408 to other. In addition at the top level it sets the $(d) variable (which
409 stands for the directory where the currently included Rules.mk is) and
410 includes the skel.mk so the top level Rules.top can have exactly the
411 same structure as other Rules.mk.
412
413 The skel.mk is a skeleton which defines variables used by make. In
414 addition it includes:
415 - config.mk - this is a file with the "configuration" for your project
416 - def_rules.mk - where to put general rules (e.g. pattern rules). E.g.
417 if you want to add a rule that builds %.o out of %.m4 (by running m4
418 preprocessor before passing the contents of file to CC) just put it in
419 here.
420
421 skel.mk also defines some functions like save_vars and tgt_rule
422 which are called in the footer.mk. Take a look into make manual for the
423 way the functions are defined and called if you're not familiar with it.
424
425 include_subdir_rules: This is where I keep track of directory of
426 currently included makefile and include the Rules.mk from the
427 subdirectories. This function is called in footer.mk in foreach
428 loop with a subdirectory name as an argument.
429
430 save_vars: This one is very simple it just saves the target specific
431 variables under their "full path" variables. E.g.
432 dir1_lib.a_DEPS will get saved as DEPS_$(TOP)/Dir_1/obj/dir1_lib.a
433 This has two purposes. First it allows you to have targets with
434 the same names in different directories (not that I recommend
435 this :)) and allows for easier definition of tgt_rules :-P
436
437 tgt_rule: This is where the rule for given target is created. First
438 I convert all relative dependencies to the absolute ones then
439 I include all dependency files (by default they are created as
440 side effects during compilation - if your compiler does not
441 allow you to do that just make simple shell script that will do
442 this). I also append appropriate libs and then issue the rule
443 for this target. By using the short circuiting 'or' command
444 I give priority to the CMD over MAKECMD.suffix which itself has
445 priority over DEFAULT_MAKECMD.
446
447 skeleton: This is just a skeleton for compilation of files in given
448 directory. If you want to add some rule here then also add
449 appropriate pattern to the AUTO_TGTS that will filter out these
450 targets and prevent generation of the specific rules via
451 tgt_rule function.
452
453 The footer.mk is where Rules.mk gets translated into the proper
454 makefile. There's not much to explain, just take a look in there.
455 First I memorize the targets for given directory (either from OBJS/SRCS
456 or from TARGETS) with appropriate directory prefix. If there's need to
457 save the target specific *_(CMD|DEP|LIB) I do it. Then I include all
458 the Rules.mk from the subdirectories. Then I define the targets for
459 given directory either explicitly (like clean_all or clean_$(d)) or by
460 evaluation of the 'skeleton' mentioned above or by iterating through all
461 targets which do not match AUTO_TGTS and evaluating what tgt_rule
462 function for this target has returned.
463
464 In case you want to play with these settings make sure you understand
465 how make works, what are it's phases, when and how the variables are
466 expanded and so on. It will save you a lot of time :).
467
468 Best regards
469 Andrzej