aboutsummaryrefslogtreecommitdiff
path: root/documentation
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-02-05 18:01:45 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-02-05 18:01:45 +0200
commitd7b7e218bfe92516f525568a6c1c9e1a9eb241fe (patch)
tree6cbc3155d7188f65e4b806c6edeecdd53393da69 /documentation
Start tracking build with git
Diffstat (limited to 'documentation')
-rw-r--r--documentation/BUGS18
-rw-r--r--documentation/CLEANUP2
-rw-r--r--documentation/CONFIGURATION64
-rw-r--r--documentation/DOC16
-rw-r--r--documentation/FACILITIES16
-rw-r--r--documentation/FEATURES5
-rw-r--r--documentation/IDEAS156
-rw-r--r--documentation/INSTALLATION5
-rw-r--r--documentation/ISSUES72
-rw-r--r--documentation/MAKE31
-rw-r--r--documentation/NOTES34
-rw-r--r--documentation/OPTIMIZATION21
-rw-r--r--documentation/PROBLEMS70
-rw-r--r--documentation/RELEASE7
-rw-r--r--documentation/SHOWCASE85
-rw-r--r--documentation/STYLE23
-rw-r--r--documentation/TARGETS30
-rw-r--r--documentation/TODO9
-rw-r--r--documentation/default.css160
-rw-r--r--documentation/index.xhtml970
20 files changed, 1794 insertions, 0 deletions
diff --git a/documentation/BUGS b/documentation/BUGS
new file mode 100644
index 0000000..ec499ae
--- /dev/null
+++ b/documentation/BUGS
@@ -0,0 +1,18 @@
+@@ Messages during configuration should be about 80 chars long.
+ Right now they are much shorter which makes it look really ugly.
+
+@@ some keywords (l:) are being framed
+
+%% Relative paths result in rebuilds.
+
+@% When configuring with -j N some strange warnings appear. Temporary
+ fix. Depends on GNU make bug #12229.
+
+%% Use src_root path as default value for out_root.
+
+@@ Intel C++ does not generate phony rule for non-existent headers.
+
+@@ It seems to me that in generated header prefix logic the dependency
+ patched by sed script and one produced by a subsequent run of the
+ compiler are different which triggers makefile reload. I wonder
+ why? \ No newline at end of file
diff --git a/documentation/CLEANUP b/documentation/CLEANUP
new file mode 100644
index 0000000..fc3e263
--- /dev/null
+++ b/documentation/CLEANUP
@@ -0,0 +1,2 @@
+%@ add project_name, add corresponding message to all configuration scripts
+ \ No newline at end of file
diff --git a/documentation/CONFIGURATION b/documentation/CONFIGURATION
new file mode 100644
index 0000000..feed13c
--- /dev/null
+++ b/documentation/CONFIGURATION
@@ -0,0 +1,64 @@
+
+@@ It would be nice if configuration happens only when it is
+ required. For example if I need to build something that
+ uses CORBA then only in this case happens configuration of
+ CORBA facilities.
+
+
+@@ 'configure' should depend on 'clean'
+
+
+@@ What if I change something in config file (let's say archive to shared)
+ and then say make - things will break.
+
+
+@@ It would be nice if I could keep build/ outside of the project. This
+ is going to be very useful when multiple projects share the same
+ build system.
+
+@@ it would be nice to have a project_base which will be
+ $(root)/example/project. However, in normal most cases project will be
+ the same as root, right? Look at CCF. Some comments:
+
+ Saying -I$(root) would be exactly what I need if its value would be
+ .../example/project. This, according to the concept of clusters, could
+ be achived if I make .../example/project a cluster (which is quite
+ natural thing to do). It would also be a good example of a cluster.
+
+
+@@ Right now I have one global implicit rule for the project. In most
+ cases this is probably enough. But what if I want to use different
+ rules for different sub-projects (config clusters). For example two
+ parts of the same project could use different compilers or ORB or...
+ Probably the generic approach would be to provide sub-dir specific
+ rules.
+
+@@ concept of configuration clusters (no more src_root).
+
+
+@@ Can I get rid of src_root and out_root (i.e. can they be /)?
+
+
+@@ It would be nice if I could configure the same sub-system
+ (like CORBA) for dirrefent parts of the project differenty.
+
+
+@@ Do I really need those configuration clusters? Is the structure
+ of CCF right? Or am I just trying to hide problems of wrong
+ structuring? Isn't it overcomplication? Even if not shouldn't
+ I postpone this until I gain more experience?
+
+---------------------
+
+@@ Each project includes (in its root directory) copy of the build system.
+
+@@ The build system is configuration cluster.
+
+@@ Configuration cluster sets src/out_root.
+
+@@ Configuration cluster can inherit configuration from its parent.
+
+@@ Configuration cluster can override inherited values.
+
+@@ sub-projects in configuration cluster should not refer to anything
+ outside of this cluster.
diff --git a/documentation/DOC b/documentation/DOC
new file mode 100644
index 0000000..0ace1cf
--- /dev/null
+++ b/documentation/DOC
@@ -0,0 +1,16 @@
+@@ Update to describe new option importing mechanism. Maybe even
+ include some general model of project building?
+
+
+@@ Create style section and put STYLE file there.
+
+
+@@ Describe canonical targets (from targets).
+
+@@ Currently I have no description of targtes (e.g., nobody knows about
+ disfigure).
+
+@@ Update documentation with the new output from examples.
+
+@@ Add News section to the index.xhtml
+
diff --git a/documentation/FACILITIES b/documentation/FACILITIES
new file mode 100644
index 0000000..26492f4
--- /dev/null
+++ b/documentation/FACILITIES
@@ -0,0 +1,16 @@
+
+@@ can I have different strategies for src/out? Would I be able
+ to come up with generic implicit rules that work for all cases?
+
+@@ optional facilities could go into pre-load.
+
+@@ from building point of view distinction on source and generated
+ files is not essential.
+
+@@ Common places for generated files (from multi-arch):
+
+ - home (out == src)
+
+ - parallel structure outside (out is set based on curdir?)
+
+ - subdirs in source (potentially many) (out := src + something)
diff --git a/documentation/FEATURES b/documentation/FEATURES
new file mode 100644
index 0000000..1068025
--- /dev/null
+++ b/documentation/FEATURES
@@ -0,0 +1,5 @@
+@@ Allow multiple files in $(call load ).
+
+@! Extract compiler-specific include paths to create do-nothing rules
+ for headers.
+
diff --git a/documentation/IDEAS b/documentation/IDEAS
new file mode 100644
index 0000000..649f375
--- /dev/null
+++ b/documentation/IDEAS
@@ -0,0 +1,156 @@
+@@ Need to create some show-case with some intermidiate compiler like
+ idl/lex/yacc. M4 comes to mind.
+
+%% Stages of building
+
+ 1. configure/configuration
+
+ 2. build/build
+
+ 3a. test/testing
+
+ 3b. install/installation
+
+@@ Maybe I should have a special function for inclusion from special
+ directories (like Build).
+
+@@ it would nice to have suffixes configurable
+
+@@ There could be a set of files to configure building environment (like
+ suffixes of files, names of utilities, etc). If I decide to ship
+ environment as standalon product I will have to somehow separate
+ those files (like putting in different directories).
+
+@@ It would make sense to split build system on subsystems like 'base'
+ 'c' 'cxx', 'corba/cxx' etc.
+
+%% Maybe I should pre-load some commonly used patterns.
+
+@@ Maybe makefiles that are not ment to be used interactively should
+ inherit their interactivity status from their includer.
+
+@@ Allow changing of options based on the category (plus all). This
+ can be done like this:
+
+ %.o : %.cpp : cxx_options = $(cxx_cpp_flags) $(cxx_debug_flags) $(cxx_diagnostic_flags)
+ %.o : %.cpp : cxx_cpp_options :=
+ %.o : %.cpp : cxx_debug_options := -g
+ %.o : %.cpp : cxx_diagnostic_options := -Wall
+
+ This will allow the user to change only what he want without much
+ hassle.
+
+@! Can I make a dependecy of lib.l on lib.so? Should I? Or should I list
+ .so/.a in the pattern rule so it gets deleted?
+
+@@ It would be nice to have a custom message for phony targets that merely
+ depend on normal targets. For example if I could get a list of targets
+ that were updated I would have been able to print such a message. This
+ would probably require modifications to make.
+
+ For default target of a dispatch makefile (better name?) I use directory
+ name which makes perfect sense. BTW, maybe I should call them directory
+ makefiles, or meta-makefiles, or stubs?
+
+@@ Since the build of multiple goals in the same target can be tricky I
+ may want to detect this and give a warning/error (this could be
+ configurable).
+
+@@ 'cxx' should depend on 'c'. 'cxx' can reuse ar facility from 'c'.
+
+@@ Make function extension framework. The idea is to use $(shell) to call
+ arbitrary executable/shell-script. The only problem is that I need a
+ way to build something before continuing to read makefile. Something
+ like .REQUIRE: target? When make sees this it stops reading makefile
+ and tries to build the target. If build succeeded make resumes to
+ read the makefile. If build failed make stops with an error.
+
+ The other, more advanced, idea is to use dynamic loading of functions.
+ This way it will be alot faster.
+
+ If included makefiles could be rebuilt on the spot (i.e. without
+ first reading the rest) then it would be a way.
+
+@@ Can I use linker script instead of my .l library descriptor (or together
+ with?).
+
+@@ There is a support for 'version script' in ld. I wonder what is that.
+
+@@ study linux kernel build system
+
+@! Maybe clean/disfigure target should include deletion of a directory
+ if (a) the build could potentially create it and (b) it is empty.
+ This way things will be cleaner and, after saying make clean in the
+ build directory, one gets just configuration.
+
+@@ I can ask user if he wants to override default .a/.so search paths
+ (for example to match the compiler).
+
+
+@@ Multidir example probably belongs to c subsystem.
+
+@@ If I have build-as-you-need-them makefile inclusion scheme then if I
+ include makefiles in a proper order I can get rid of those
+ 'configuring blah-blah' messages.
+
+@@ I can be cool and make 'ls' in cxx to find present c++ compilers. This
+ way I will be able to distribute compiler-specific files separately.
+
+@@ It would be nice to have include function that includes a file
+ relatevely to the current's Makefile directory.
+
+@@ Maybe factor out cpp as a common facility in 'c'? Right now I duplicate
+ some support code in cxx/gnu and cxx/intel.
+
+@@ All this '.l' abstraction support belongs to 'c'.
+
+@@ In import/export stubs check for version compatibilities. Oohooo!
+
+@@ What if I save src_root somewhere in out_root?
+
+%% Need to try to use build with distcc. Works well.
+
+@@ I may want to store src_root someweher in out_root so that I don't
+ need to ask for it (will not work in all cases).
+
+@! It is probably a good idea to make each file responsible for
+ making sure its guts are included right number of times.
+
+@! With introduction of .NOT_DEFAULT I can factor out aliasing into
+ (per-project) bootstrap.make. Did in some projects - works well.
+ Need to do them in example.
+
+@@ foreach is a way to define local variable.
+
+@! use $(< file) instead of cat
+
+@! use last dir + relative path in messages
+
+@! what about using few-letters vars instead of cxx_obj (o) cxx_od (d)?
+
+@! How about uniform importing facility without any subsystems? For example
+ CORBA is a translator and a library at the same time - how to handle it?
+
+ - can use whatever names in imported files.
+
+ - will need importing from project build dir and from bld_root
+
+@! Need to think about hacker mode - passing config info via command line
+ with standard names like CXX CPPFLAGS LDFLAGS, etc.
+
+@! teach import stubs to not try include anything when cleaning/disfiguring?
+
+@@ local target that will rebuild only local object files? Or maybe set an
+ order of rebuilding local files first?
+
+@! Now since I have .DEFAULT_TARGET I can do save/restore thing for export
+ import. So there won't be a need to secure default target. Way too cool!
+
+%% Usually src_root and out_root are the same. I should suggest one
+ by default when asking user for it.
+
+@@ There are two situations where I can guess src_root from out_root:
+ first is when out_root == src_root (I can check for build/bootstrap.make
+ though bootstrap.make can be named differently). The other case is when
+ out_root already contains build project (I will need to kind of marker
+ that contains value of src_root; maybe build/configuratio-dynamic.make).
diff --git a/documentation/INSTALLATION b/documentation/INSTALLATION
new file mode 100644
index 0000000..24eebcf
--- /dev/null
+++ b/documentation/INSTALLATION
@@ -0,0 +1,5 @@
+%% used install -d to create directories during installation.
+
+%@ splitting, completion, and cleanup
+
+%% terse messages for installation commands.
diff --git a/documentation/ISSUES b/documentation/ISSUES
new file mode 100644
index 0000000..e7b4263
--- /dev/null
+++ b/documentation/ISSUES
@@ -0,0 +1,72 @@
+@@ use shell && instead of multi-line rules since they don't consider
+ atomic (e.g. if something failed other files won't be deleted). Or
+ maybe not, think about it (and read the doc).
+
+@@ Some implicit rule should actually be two rules: one that looks
+ for the source under srd_root tree and the other under out_root.
+ Theoretically, any source could be just an intermidiate file generated
+ from something else (discovered while playing with idl).
+
+@@ Compensating rules: 'clean all' example.
+
+@@ Issues from "Multi-Architecture Builds Using GNU make":
+
+ - big (bloated) makefiles
+
+ - cannot say "make foo.o"
+
+@@ How can I integrate building of realpath utility in configuration
+ process?
+
+@@ Executing make from non-source directory is painful. Can I make it
+ easier?
+
+%% When shared library is linked with absolute path the loader is looking
+ for the library with the same path. See also -soname= and -rpath ls
+ options.
+
+@@ With multidir makefiles I loos the ability to say make where I am.
+ This is especially nasty when I edit a file and then say make. This
+ happens for example in CCF. The easy workaround is to say something
+ "make -C dir/to/test/driver". Once this is done life get very nice.
+ Actually I think this could be the best approach.
+
+@@ Variable inheritance doesn't play well with 'make foo.o'.
+
+@@ Configurations include absolute paths to imported libraries which
+ makes it hard to reuse them. In this light configurations on installed
+ libraries should not include any absolute paths.
+
+@@ Better name for project_name? build_name?
+
+@@ Repetition of paths in $(call message) is quite ugly. Anything I can do?
+
+@@ -MP conflicts with --no-implicit-phony. The new approach uses a special
+ terminal pattern rule to handle this. However headers without suffix
+ cannot be handled by this method.
+
+@! Delete-on-error does not cover .o.d files. I could specify it as a target
+ together with .o but then it will try to rebuild it.
+
+@! When you hide things from make (like .o.d or .l/.so) all sorts of bad things
+ happen.
+
+@@ What is a better term for development (not installed?) build?
+
+@@ /usr/bin/g++ is a link but extracted include paths have precise version in
+ them (e.g. 3.3.4). But then dependencies will trigger update, right?
+
+@! I am using some of the features of GNU find which are not available in SUS.
+
+@@ Since .l.cpp-options pattern does not have any prereqs then the file can
+ always be created (example: I misspelled file name).
+
+@@ Use abspath to prevent call-inclusion from -I dirs.
+
+@@ lib.cpp-options should be lib.cpp_options?
+
+@@ Use $@ in $$(dir $(out)/%).
+
+@! Need to make content of .l compiler-independant (rpath stuff).
+
+@@ export is now position-sensitive.
diff --git a/documentation/MAKE b/documentation/MAKE
new file mode 100644
index 0000000..50e073b
--- /dev/null
+++ b/documentation/MAKE
@@ -0,0 +1,31 @@
+
+@@ I was thinking about the way make handles inclusion of missing
+ makefile. The following strategy seems like a better choice:
+ if makefile is missing try to rebuild & read it immediately,
+ without parsing the rest of makefile and without reexecuting
+ make later. This approach has at least two benefits:
+
+ + more efficient (no make re-execution) (this is not very
+ important in most cases, thoug)
+
+ + more deterministic: if some of the code after (missing)
+ included makefile depends on some code from it (for
+ example a function) then things can break (example:
+ configuration of ORB).
+
+ - sequential (cannot build makefile in parallel)
+
+
+@! target/pattern-specific vpath
+
+@@ no `target is up to date' message when commnds are executed
+ but target is not changed.
+
+@@ %.o %.d and include
+
+%% implicit double expansion: now supports target/pattern variables
+ and $-
+
+%% create `examples' directory where I can put md5 and maybe hello.
+
+@! shortest stem
diff --git a/documentation/NOTES b/documentation/NOTES
new file mode 100644
index 0000000..7bed2c8
--- /dev/null
+++ b/documentation/NOTES
@@ -0,0 +1,34 @@
+@@ ?= is deferred
+
+@@ automatically-generated dependecies should include absolute paths
+ just like gcc does. Note that it only happens when you pass gcc
+ absolute paths in -I so I should watch out!
+
+@@ order-only dependencies allow for elegant creation of a directory
+ before build.
+
+@@ need to try generation of headers in out_dir.
+
+@@ maybe think about shared library versioning. This could be done
+ transparently at installation time.
+
+%% I should use some form of include function for -include for
+ consistency.
+
+@@ linker accepts -O options and can opimize.
+
+@@ use suffix (.make, .cxx) to specify file type - not as a mere
+ separator. Can I use '-' as separator? Should I use '_' as separator?
+
+@@ read lisp ASDF manual.
+
+@@ Use $(eval foo:=bar) in rule's command to set variable only if (and after)
+ the rule is in use.
+
+%% Files in import directory are called configuration. They are not quite
+ that. Maybe a better name would be stub?
+
+@@ For some (all? SUS?) platforms inclusion of .so in .l is redundant
+ because .so is already linked against them.
+
+@@ Need to continue cleaning if some files do not exist (rm -f ?).
diff --git a/documentation/OPTIMIZATION b/documentation/OPTIMIZATION
new file mode 100644
index 0000000..dfdb06d
--- /dev/null
+++ b/documentation/OPTIMIZATION
@@ -0,0 +1,21 @@
+%% I should keep a separate list of files that are included-once which
+ should also cache the realpaths.
+
+@@ It would make sense to use $(call include-once,out_dir) in cxx/cxx-o.make
+ etc.
+
+@@ Need to check what is being framed.
+
+@@ I wonder how much it costs to have the second expansion in implicit rule?
+
+@@ Make executes each line in a separate shell. I wonder if using && is
+ more efficient?
+
+%% check make's default hash table size.
+
+@@ would using `makefile: ' tecknique to prevent make from trying to
+ match against pattern-rules help?
+
+@@ Look for redundant $(eval ) calls (like I had in include-*).
+
+@@ use head -n 1 instead of sed -e 1q
diff --git a/documentation/PROBLEMS b/documentation/PROBLEMS
new file mode 100644
index 0000000..a07fbda
--- /dev/null
+++ b/documentation/PROBLEMS
@@ -0,0 +1,70 @@
+STRUCTURE
+
+
+VARIABLES
+
+%% It would be nice to be able to include makefile in a way that
+ variables are restored.
+
+@% I definitely need some naming convention for "global" variables.
+ Since I include potentially unknown makefiles (like library
+ dependecies) I cannot predict what they do. This is another
+ argument for variable framing.
+
+ Some ideas:
+
+ - Variables that start and end with '%' are considered global
+ and system. Subsystems may define such vars if there is
+ a real need. (Currently defined names should be documented
+ here. Each subsystem should document names that it defines.)
+ Subsystem should prefix each such var with its name (e.g. cxx_).
+
+ - Variables that contain '-' are considered 'functions' and not
+ framed. Generally subsystems should define those. The names
+ should be chosen carefully in order not to cause name clashes.
+ (Each subsystem should document names that it defines).
+ Subsystem should prefix each such function with its name
+ (e.g. cxx-).
+
+ - Variables that appear in %frame_exclude% are not framed. General
+ rule is to add only special one-word functions (usually defined
+ by base subsystem) that are used often and thus having one-word
+ terse name is very important; for example 'include' or 'import'
+
+
+%% After the inclusion of dependency makefiles I cannot use src_base
+ becasue it was reset by the included file. So I am forced to use
+ src_root now which will hurt especially sore when I include from
+ sub-directories.
+
+
+
+DEPENDENCIES : STRUCTURE
+
+@@ It would be nice to be able to chose dependency type project-wise
+ and on a by-makefile basis. This could be tricky, however.
+
+@@ Missing headers assumed generated with some inflexible logic (cur dir).
+ This can also vary among compilers (which is not something I would worry
+ too much as long as g++ works). Can I make it more reliable? Maybe capture
+ this (or essential) dependecies in a Makefile?
+
+@@ Can I specify dependencies in CORBA projects manually. Do I want to do
+ that?
+
+@@ Don't include dependecies when cleaning (configuring?).
+
+
+
+MISC
+
+@@ If I have generated idl files in src directory then build in some other
+ directory will fail or will use wrong headers.
+
+%% .NOT_DEFAULT: target in make?
+
+%@ configuration targets should not be parallel. try make -j 4 Maybe I can
+ detect that those files do not exist and disable parallelism for this
+ run. See .MUTEX bug (#3656).
+
+@@ relative paths and pattern matching does not work very well together
diff --git a/documentation/RELEASE b/documentation/RELEASE
new file mode 100644
index 0000000..fc216ed
--- /dev/null
+++ b/documentation/RELEASE
@@ -0,0 +1,7 @@
+@@ add header to every file.
+
+@@ make sure all files conform to the STYLE.
+
+@@ remove empty directoris (left after disfigure) in examples/
+
+@@ update copyright
diff --git a/documentation/SHOWCASE b/documentation/SHOWCASE
new file mode 100644
index 0000000..1a032f2
--- /dev/null
+++ b/documentation/SHOWCASE
@@ -0,0 +1,85 @@
+#@@ if a showcase complicated the initial example then it should
+# be implemented as a separate example.
+
+%% build with nested directories from single Makefile
+
+%% generation of headers/sources from some other source with
+ automatically generated dependencies (IDL showcase)
+
+%% two executables in the same dir (though generally not recomended)
+
+%% selection of PIC by a target (target-specific variables
+ inheritance) (read the bug report about this feature).
+
+%% directory Makefiles (need a nice name for them)
+
+%@ configuration target
+
+ - implemented disfigure only (for now).
+
+ - not complete
+
+ - need to implement configuration of installed dependencies.
+
+%@ installation target
+
+ - prototype design
+
+ - needs completion
+
+%@ test target
+
+ - only in libhello
+
+%% generation of actual dependencies for C++/C
+
+@@ use of C & C++ compiler from the same Makefile
+
+@@ another C++/C compiler (Sun CC?)
+
+@@ cleaning after messy compilers (Sun CC?)
+
+@@ c subsystem
+
+@@ Quite mode. all answers defaulted. Error if something is wrong.
+
+@@ I need some way of programmatically supplying configuration
+ information (for example for debian package creation). Via
+ command line variables seems like a reasonable approach. Also
+ saving configuration seems like a good idea too (i.e. keeping
+ configuration around) but then I need to make sure there are
+ no absolute paths.
+
+%@ Installation process for the build system itself.
+
+ - now installs only build system itself.
+
+%% What am I going to do with corba? Maybe package it as a separate
+ incomplete subsystem?
+
+@% All those "file not found" messages by make are quite nasty. I should
+ either fix make (preferable) or use -include.
+
+ - using -include for now
+
+%% variable unsetting: do I still need it? Yes I do.
+
+@@ installation of examples
+
+@@ need to clean source code out of @@
+
+@! target-specific vpath
+
+@! Can .INTERMIDIATE help me with .d problem? No! Also it seems
+ saying something like %.o %.d: %.cxx won't work either? Need
+ to check this.
+
+@! Need to run ranlib on certain platforms. Need to detect if I need to.
+
+@! .cpp-options: if add/remove .cpp-options prereqs the target file does not
+ get regenerated. Probably need to save list of prereqs and compare with it.
+
+@! shared library versioning
+
+@! Need to think on a general idea of state saving (like I do with
+ .cpp-options). Is there a cleaner way of doing this?
diff --git a/documentation/STYLE b/documentation/STYLE
new file mode 100644
index 0000000..32799f6
--- /dev/null
+++ b/documentation/STYLE
@@ -0,0 +1,23 @@
+@@ write "t: p" instead of "t : p" or "t :p"
+
+@@ write $(call f,a) instead of $(call f, a) or $(call f , a)
+
+@@ Use '-' to separate words in function names (e.g. foo-bar);
+ use 'define' to define functions.
+
+@@ Use '_' to separate words in variable names (e.g. foo_bar);
+ use := to assign value to a variable. Use '=' if you know
+ what you are doing.
+
+@@ Be careful with += in target-specific variables.
+
+@@ Action explicitly requested by the user (which should correspond
+ to verbs, e.g. install, clean, configure) should perform without
+ regards to up-to-dateness.
+
+@@ Use verbs for .PHONY targets. There is one notable exception:...
+
+@! maybe declare `__' variable prefix reserved?
+
+@@ Use directory name as a default phony target in directory makefiles.
+ (explain why). \ No newline at end of file
diff --git a/documentation/TARGETS b/documentation/TARGETS
new file mode 100644
index 0000000..ff5476f
--- /dev/null
+++ b/documentation/TARGETS
@@ -0,0 +1,30 @@
+
+# Configuration
+#
+
+configuration
+configure : disfigure
+disfigure : clean
+
+# build
+#
+
+build : configuration
+clean
+
+
+# test
+#
+test : build
+
+
+# install
+#
+install : build
+uninstall
+
+
+# help
+#
+
+help
diff --git a/documentation/TODO b/documentation/TODO
new file mode 100644
index 0000000..4aec2c6
--- /dev/null
+++ b/documentation/TODO
@@ -0,0 +1,9 @@
+!! Need to change include path in hello example.
+
+!! And change to #include <>
+
+!! Need to get rid of those header patterns or implement shortest stem.
+
+!! finish cxx-d.make
+
+@@ Add include-dep to examples.
diff --git a/documentation/default.css b/documentation/default.css
new file mode 100644
index 0000000..7242a94
--- /dev/null
+++ b/documentation/default.css
@@ -0,0 +1,160 @@
+body {
+ font-family : sans-serif;
+ font-weight : normal;
+
+ color : black;
+ background : white;
+
+ max-width : 42em;
+ padding : 2em 2em 2em 3em;
+ margin : 0 auto;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ font-family : sans-serif;
+ font-weight : 500;
+}
+
+h1 { font-size : 170%; }
+h2 { font-size : 145%; }
+h3 { font-size : 125%; }
+h4 { font-size : 110%; }
+h5 { font-size : 106%; }
+h6 { font-size : 100%; }
+
+
+p.indent {
+ margin-left : 1.5em;
+}
+
+
+/* table of content */
+ul.toc li {
+ padding : .4em 0em 0em 0em;
+}
+
+
+
+/* list of links */
+ul.menu {
+ list-style-type : none;
+}
+
+ul.menu li {
+ padding-top : 0.3em;
+ padding-bottom : 0.3em;
+}
+
+
+
+/* @@ I should probably use child selector here */
+/* list with multiline list-elements */
+ul.multiline li {
+ padding-top : 0.4em;
+ padding-bottom : 0.4em;
+}
+
+ol.multiline li {
+ padding-top : 0.4em;
+ padding-bottom : 0.4em;
+}
+
+dl.multiline dd {
+ padding-top : 0.4em;
+ padding-bottom : 0.4em;
+}
+
+/* code */
+
+code {
+ font-size : 114%;
+ font-family : monospace;
+}
+
+
+/* C++ code snippet */
+pre.cxx {
+
+ margin-top : 0em;
+ margin-bottom : 2em;
+
+ margin-left : 1em;
+}
+
+
+
+/* make code snippet */
+pre.make {
+
+ margin-top : 0em;
+ margin-bottom : 2em;
+
+ margin-left : 1em;
+}
+
+
+
+/* terminal output */
+pre.term {
+
+ margin-top : 0em;
+ margin-bottom : 2em;
+
+ margin-left : 1em;
+}
+
+
+/* Images */
+div.center {
+ text-align: center;
+}
+
+/* Navigation. */
+#navigation {
+ margin-top: 1em;
+ border-bottom: 1px dashed #000000;
+}
+
+#content {
+ margin-top: 2.5em;
+}
+
+
+/* Document info. */
+#docinfo {
+ margin-top: 4em;
+ border-top: 1px dashed #000000;
+ font-size: 70%;
+}
+
+/* distribution terms */
+div.terms {
+ font-size : 114%;
+ font-family : monospace;
+}
+
+
+
+/* Footnote */
+
+#footnote {
+ margin-top: 2em;
+}
+
+#footnote hr {
+ margin-left: 0;
+ margin-bottom: 1.5em;
+ width: 8em;
+ border-top: 1px solid #000000;
+ border-right: none;
+ border-bottom: none;
+ border-left: none;
+
+}
+
+#footnote p {
+ font-size: .91em;
+ text-indent: -0.8em;
+ padding-left: 0.8em;
+}
+
diff --git a/documentation/index.xhtml b/documentation/index.xhtml
new file mode 100644
index 0000000..afc655c
--- /dev/null
+++ b/documentation/index.xhtml
@@ -0,0 +1,970 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+
+<!--
+
+file : documentation/index.xhtml
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : Copyright (c) 2004-2010 Code Synthesis Tools CC
+license : GNU FDL v1.2; http://www.codesynthesis.com/licenses/fdl-1.2.txt
+
+-->
+
+<!--
+@@ maybe background code?
+
+@@ describe all feature that appear in the example.
+-->
+
+<head>
+
+ <title>build/documentation</title>
+
+ <meta name="author" content="Boris Kolpackov"/>
+ <meta name="copyright" content="&copy; 2004-2010 Code Synthesis Tools CC"/>
+ <meta name="keywords" content="build,system,make"/>
+ <meta name="description" content="build/documentation"/>
+
+ <link rel="stylesheet" type="text/css" href="default.css"/>
+
+</head>
+
+<body>
+<div id="content">
+<ul class="toc">
+<li><a href="#introduction">Introduction</a></li>
+<li><a href="#fundamentals">Fundamentals</a></li>
+<li><a href="#first_example">First Example</a>
+ <ul>
+ <li><a href="#invocation">Invocation</a></li>
+ <li><a href="#makefiles">Makefiles</a></li>
+ </ul>
+</li>
+<li><a href="#inter_project_dependencies">Inter-Project Dependencies</a></li>
+<li><a href="#administrivia">Administrivia</a>
+ <ul>
+ <li><a href="#license">License</a></li>
+ <li><a href="#bootstrapping">Bootstrapping</a></li>
+ <li><a href="#versioning">Versioning</a></li>
+ </ul>
+</li>
+</ul>
+
+
+<h1><a name="introduction">Introduction</a></h1>
+
+<p>I hear you saying: "Yeah, yeah, another marvelous make
+replacement with built-in support for various compilers, automatic
+dependency scanning, parallel and distributed builds, and XML instead of
+makefiles!" On the contrary, <em>build</em> is a software build system
+that is implemented on top of GNU make. It defines extensible framework for
+translators, delegates most of its tasks to existing tools, and uses GNU
+make syntax for makefiles. <em>Build</em> was designed with the following
+tasks in mind:</p>
+
+<ul class="multiline">
+ <li>configuration</li>
+ <li>building</li>
+ <li>testing</li>
+ <li>installation</li>
+</ul>
+
+<p>As distribution of software in source code is being replaced by
+precompiled package distributions, greater emphasis was placed on
+development-time conveniences. Some of the features of <em>build</em>
+include:</p>
+
+<ul class="multiline">
+ <li>position-independent makefiles</li>
+
+ <li>non-recursive multi-makefile include-based structure</li>
+
+ <li>leaf makefiles are full-fledged GNU makefiles, not just
+ variable definitions</li>
+
+ <li>complete dependency graph</li>
+
+ <li>inter-project dependency tracking</li>
+</ul>
+
+<p>To understand leaf makefiles in this manual you will need basic
+knowledge of how <code>make</code> works. However, inside, <em>build</em>
+uses some of the more advanced features of GNU make including</p>
+
+<ul class="multiline">
+<li>order-only prerequisites</li>
+<li>pattern and target-specific variables</li>
+<li><code>$(call )</code> and <code>$(eval )</code></li>
+<li>different flavors of <code>include</code> directive</li>
+</ul>
+
+<p>If you find usage of some of the <code>make</code> techniques obscure
+in this text you can always consult with the
+<a href="http://www.gnu.org/software/make/manual/make.html">GNU make
+manual</a>.</p>
+
+
+<h1><a name="fundamentals">Fundamentals</a></h1>
+
+<p><em>Build</em> defines a framework in terms of which user makefiles
+are written. Below is the list of fundamental concepts.</p>
+
+<dl class="multiline">
+<dt>Project</dt>
+<dd>is a separately distributable collection of source files. A more
+intuitive way of defining a project would be to say it's what you
+normally assign a version number to (e.g., <code>libhello-0.0.1</code>)
+and package as a tar ball (e.g., <code>libhello-0.0.1.tar.gz</code>).
+A reasonably complex project usually has a hierarchy of sub-directories
+under its root directory.</dd>
+
+<dt>Component</dt>
+<dd>is part of a project for which you would normally write a
+makefile. For example our <code>libhello</code> could consist of
+two components: the library itself and a test driver.</dd>
+
+<dt>Source root</dt>
+<dd>is a root directory of a project. For example, if we unpack our
+<code>libhello-0.0.1.tar.gz</code> to <code>/tmp</code> and end up with
+a directory <code>/tmp/libhello-0.0.1</code> then that would be this
+project's <em>source root</em>.</dd>
+
+<dt>Source base</dt>
+<dd>is a directory of a component in a project. Continuing our example,
+if our <code>libhello</code> project had a subdirectory <code>test</code>
+then the <em>source base</em> of the <code>test</code> component would be
+<code>/tmp/libhello-0.0.1/test</code>. By definition, any <em>source base</em>
+is a sub-directory of a <em>source root</em> for any particular project.</dd>
+
+<dt>Out root</dt>
+<dd>is a root directory of a project's build (or output) hierarchy. This
+directory signifies where generated files for the project will be placed.
+For example, if we decide to build <code>libhello</code> in
+<code>/tmp/libhello-i686-pc-linux-gnu</code> then that would be one of the
+possible <em>out roots</em>.</dd>
+
+<dt>Out base</dt>
+<dd>is a build (or output) directory of a component in a project.
+If we continue our example, the <em>out base</em> for the <code>test</code>
+component would be <code>/tmp/libhello-i686-pc-linux-gnu/test</code>.</dd>
+</dl>
+
+<p>The <em>build</em> runtime defines four <code>make</code> variables that
+correspond to the last four definitions:</p>
+
+<pre class="make">
+src_root
+src_base
+out_root
+out_base
+</pre>
+
+<p>Below is an example of how you could use some of them.</p>
+
+<pre class="make">
+driver := $(out_base)/driver
+
+$(driver): $(out_base)/driver.o $(out_root)/libhello/libhello.so
+</pre>
+
+<p>Additionally, the <em>build</em> framework defines three more
+variables:</p>
+
+<pre class="make">
+bld_root
+scf_root := $(src_root)/build
+dcf_root := $(out_root)/build
+</pre>
+
+<p><code>bld_root</code> is a root directory of the <em>build</em> runtime.
+Normally you would use it to include one of the <em>build</em>'s files.</p>
+
+<p><code>scf_root</code> stands for static configuration root and
+points to a directory where project's static configuration is kept.
+<code>dcf_root</code> stands for dynamic configuration root and
+points to a directory where project's dynamic configuration is kept.
+We will talk more about those two variables later.</p>
+
+<p>Also note that having <code>src_root</code> the same as
+<code>out_root</code> is perfectly valid and indicates that we
+are building in a source directory.</p>
+
+<h1><a name="first_example">First Example</a></h1>
+
+<p>Now we are ready to examine our first simple example. We
+will skip one-file C-based "hello world", however, because it
+is not very practical and there is not much room for improvement.
+Rather we will start from a <code>libhello</code> library, a test
+driver for it and a <code>hello</code> program that uses the library.
+To make our example even more realistic the <code>libhello</code>
+library and the <code>hello</code> program are two separate projects.
+And, did I mention, they are written in C++. See
+<code>examples/cxx/hello</code>.</p>
+
+<h2><a name="invocation">Invocation</a></h2>
+
+<p>Let's first get some user experience without looking into makefiles.
+Suppose we unpacked <em>build</em> source into <code>/tmp/build-0.1.12</code>.
+First let's try to build <code>libhello</code>:</p>
+
+<pre class="term">
+$ cd /tmp/build-0.1.12/examples/cxx/hello/libhello
+$ make
+
+
+configuring 'libhello'
+
+
+
+Please select the C++ compiler you would like to use:
+
+(1) GNU C++ (g++)
+(2) Intel C++ (icc)
+
+[1]: 1
+
+Would you like the C++ compiler to optimize generated code?
+
+[y]: y
+
+Would you like the C++ compiler to generate debug information?
+
+[y]: y
+
+
+configuring 'libhello'
+
+
+
+Please select the default library type:
+
+(1) archive
+(2) shared object
+
+[2]: 2
+
+
+configuring 'libhello'
+
+
+
+Please enter the g++ binary you would like to use, for example 'g++-3.4',
+'/usr/local/bin/g++' or 'distcc g++'. You can use path auto-completion.
+
+[g++]: g++
+
+Please select the optimization level you would like to use:
+
+(1) -O1 [Tries to reduce code size and execution time, without
+ performing any optimizations that take a great deal of
+ compilation time.]
+(2) -O2 [Performs nearly all supported optimizations that do not
+ involve a space-speed tradeoff.]
+(3) -O3 [Optimize even more.]
+(4) -Os [Optimize for size.]
+
+[2]: 2
+c++ /tmp/build-0.1.12/examples/cxx/hello/libhello/libhello/hello.cxx
+ld /tmp/build-0.1.12/examples/cxx/hello/libhello/libhello/hello.l
+c++ /tmp/build-0.1.12/examples/cxx/hello/libhello/test/driver.cxx
+ld /tmp/build-0.1.12/examples/cxx/hello/libhello/test/driver
+</pre>
+
+<p>Here we were presented with a bunch of configuration questions.
+If you have <code>g++</code> in your default path you can just keep
+hitting enter to select defaults. If you would like to see real commands
+that are being executed (useful when something goes wrong) you can
+say <code>make verbose=1</code>.</p>
+
+<p>From the messages above we can deduce that we have built the
+<code>libhello</code> library (<code>hello.l</code>) and the test driver
+for it (<code>test/driver</code>). So far so good. Now let's try to build
+the <code>hello</code> program:</p>
+
+<pre class="term">
+$ cd /tmp/build-0.1.12/examples/cxx/hello/hello
+$ make
+</pre>
+
+<p>Again you will be asked a bunch of questions you have already seen,
+except these two:</p>
+
+<pre class="term">
+Configuring external dependency on 'libhello' for 'hello driver'.
+
+
+Would you like to configure dependency on the installed
+version as opposed to the development build?
+
+[y]: n
+
+Please enter the out_root for 'libhello'.
+
+[]: ../libhello
+
+Please enter the src_root for 'libhello'.
+
+[]: ../libhello
+</pre>
+
+<p>The <code>hello</code> program depends on <code>libhello</code>. Since
+they are distributed as separate projects <code>hello</code> needs to
+know where to look for <code>libhello</code>. That's why user intervention
+is required. The first question is whether we would like to use an installed
+version of <code>libhello</code> as opposed to the not installed build.
+Since we haven't installed <code>libhello</code> the answer is
+<code>no</code>. The next two questions determine where the
+<code>out_root</code> of the build and the <code>src_root</code> of the source
+code are. Since we built <code>libhello</code> in its source directory both
+become <code>/tmp/build-0.1.12/examples/cxx/hello/libhello</code> or
+<code>../libhello</code> if we are in
+<code>/tmp/build-0.1.12/examples/cxx/hello/hello</code>. After answering
+those questions you will see something like this:</p>
+
+<pre class="term">
+c++ /tmp/build-0.1.12/examples/cxx/hello/hello/hello.cxx
+ld /tmp/build-0.1.12/examples/cxx/hello/hello/hello
+</pre>
+
+<p>And that's it.</p>
+
+<p>One of the nice features of <em>build</em> is that you can have several
+builds in separate directories all from the same source base. Suppose we
+would like to build an <code>-O3</code>-optimized statically-linked version
+of <code>hello</code> without debug information:</p>
+
+<pre class="term">
+$ mkdir /tmp/hello-i686-pc-linux-gnu
+$ cd /tmp/hello-i686-pc-linux-gnu
+$ make -f ../build-0.1.12/examples/cxx/hello/hello/makefile
+
+
+configuring 'hello driver'
+
+
+
+Please select the C++ compiler you would like to use:
+
+(1) GNU C++ (g++)
+(2) Intel C++ (icc)
+
+[1]: 1
+
+Would you like the C++ compiler to optimize generated code?
+
+[y]: y
+
+Would you like the C++ compiler to generate debug information?
+
+[y]: n
+
+
+Configuring external dependency on 'libhello' for 'hello driver'.
+
+
+
+Would you like to configure dependency on the installed
+version as opposed to the development build?
+
+[y]: n
+
+Please enter the out_root for 'libhello'.
+
+[]: /tmp/libhello-i686-pc-linux-gnu
+
+Please enter the src_root for 'libhello'.
+
+[]: ../build-0.1.12/examples/cxx/hello/libhello
+
+
+configuring 'hello driver'
+
+
+
+Please enter the g++ binary you would like to use, for example 'g++-3.4',
+'/usr/local/bin/g++' or 'distcc g++'. You can use path auto-completion.
+
+[g++]: g++
+
+Please select the optimization level you would like to use:
+
+(1) -O1 [Tries to reduce code size and execution time, without
+ performing any optimizations that take a great deal of
+ compilation time.]
+(2) -O2 [Performs nearly all supported optimizations that do not
+ involve a space-speed tradeoff.]
+(3) -O3 [Optimize even more.]
+(4) -Os [Optimize for size.]
+
+[2]: 3
+
+
+configuring 'libhello'
+
+
+
+Please select the C++ compiler you would like to use:
+
+(1) GNU C++ (g++)
+(2) Intel C++ (icc)
+
+[1]: 1
+
+Would you like the C++ compiler to optimize generated code?
+
+[y]: y
+
+Would you like the C++ compiler to generate debug information?
+
+[y]: n
+
+
+configuring 'libhello'
+
+
+
+Please select the default library type:
+
+(1) archive
+(2) shared object
+
+[2]: 1
+
+
+configuring 'libhello'
+
+
+
+Please enter the g++ binary you would like to use, for example 'g++-3.4',
+'/usr/local/bin/g++' or 'distcc g++'. You can use path auto-completion.
+
+[g++]: g++
+
+Please select the optimization level you would like to use:
+
+(1) -O1 [Tries to reduce code size and execution time, without
+ performing any optimizations that take a great deal of
+ compilation time.]
+(2) -O2 [Performs nearly all supported optimizations that do not
+ involve a space-speed tradeoff.]
+(3) -O3 [Optimize even more.]
+(4) -Os [Optimize for size.]
+
+[2]: 3
+c++ /tmp/build-0.1.12/examples/cxx/hello/hello/hello.cxx
+c++ /tmp/build-0.1.12/examples/cxx/hello/libhello/libhello/hello.cxx
+ar /tmp/libhello-i686-pc-linux-gnu/libhello/hello.l
+ld /tmp/hello-i686-pc-linux-gnu/hello
+</pre>
+
+<h2><a name="makefiles">Makefiles</a></h2>
+
+<p>Now let's take a look at the makefiles. We will start from the
+makefile for <code>libhello</code> (<code>hello/libhello/libhello/makefile</code>).
+Note, that I removed support for <code>install</code> target for now.</p>
+
+<pre class="make">
+include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make
+
+cxx_tun := hello.cxx
+cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o))
+cxx_od := $(cxx_obj:.o=.o.d)
+
+hello.l := $(out_base)/hello.l
+hello.l.cpp-options := $(out_base)/hello.l.cpp-options
+
+clean := $(out_base)/.clean
+
+
+# Build.
+#
+$(hello.l): $(cxx_obj)
+
+$(cxx_obj): $(hello.l.cpp-options)
+
+$(hello.l.cpp-options): value := -I$(src_root)
+
+$(call -include,$(cxx_od))
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(hello.l).clean \
+ $(addsuffix .clean,$(cxx_obj)) \
+ $(hello.l.cpp-options).clean
+
+
+# Aliases.
+#
+ifdef %interactive%
+
+.PHONY: clean
+
+clean: $(clean)
+
+endif
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-l.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+</pre>
+
+<p>Let's examine this file line-by-line:</p>
+
+<pre class="make">
+include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make
+</pre>
+
+<p>Every leaf makefile (i.e., one written to build a component) starts from a
+line that looks like this. Its sole purpose is to bootstrap the build system.
+In our case <code>$(dir $(lastword ...))</code> will expand to something
+like</p>
+
+<pre class="make">
+include .../hello/libhello/libhello/../build/bootstrap.make
+</pre>
+
+<p>Let's take a look at <code>libhello/build/bootstrap.make</code>:</p>
+
+<pre class="make">
+project_name := libhello
+include $(dir $(lastword $(MAKEFILE_LIST))).../build/bootstrap.make
+</pre>
+
+<p>The first line just initializes <code>project_name</code> with the name
+of the project. The second line includes the real <code>bootstrap.make</code>.
+See <a href="#bootstrap">Bootstrapping</a> section for more information on
+various ways of bootstrapping the <em>build</em> runtime.</p>
+
+<p>What does <code>bootstrap.make</code> do? Besides other things (which are
+explained as we encounter them) it sets all those <code>*_root</code> and
+<code>*_base</code> variables.</p>
+
+<p>Let's go back to our <code>libhello/makefile</code>. The first line
+should be clear by now so let's move on:</p>
+
+<pre class="make">
+cxx_tun := hello.cxx
+cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o))
+cxx_od := $(cxx_obj:.o=.o.d)
+</pre>
+
+<p>This should be pretty straightforward: <code>cxx_tun</code> contains
+a list of translation units, <code>cxx_obj</code> contains a list of
+object files that will be produced from those translation units, and
+<code>cxx_od</code> contains a list of automatically generated dependency
+files for those translation units. After expansion these variables could
+contain the following values (note, in this example <code>out_root</code>
+is the same as <code>src_root</code>):</p>
+
+<pre class="make">
+cxx_tun := hello.cxx
+cxx_obj := .../hello/libhello/libhello/hello.o
+cxx_od := .../hello/libhello/libhello/hello.o.d
+</pre>
+
+<p>Next chunk:</p>
+
+<pre class="make">
+hello.l := $(out_base)/hello.l
+hello.l.cpp-options := $(out_base)/hello.l.cpp-options
+
+clean := $(out_base)/.clean
+</pre>
+
+<p><code>hello.l</code> and <code>clean</code> are two variables that
+store names of targets. You are probably wondering what the heck
+is <code>hello.l</code>? This is a library abstraction the build system
+provides to deal (besides other things) with archives/shared objects
+uniformly. A user who builds your project can specify what type of
+library they want without any additional effort from you. I encourage
+you to take a look inside <code>hello.l</code>.</p>
+
+<p><code>hello.l.cpp-options</code> is a bit trickier.
+<code>$(out_base)/hello.l.cpp-options</code> keeps C preprocessor options
+that are required to compile library files as well as any piece of code
+that uses it. Hopefully, it will become clear once you see the rest of
+the makefile.</p>
+
+<p>Let's move on:</p>
+
+<pre class="make">
+# Build.
+#
+$(hello.l): $(cxx_obj)
+
+$(cxx_obj): $(hello.l.cpp-options)
+
+$(hello.l.cpp-options): value := -I$(src_root)
+
+$(call -include,$(cxx_od))
+</pre>
+
+<p>The first line tells us that <code>hello.l</code> is built from object
+files listed in <code>cxx_obj</code>. The second line establishes dependency
+of object files on C preprocessor options - in order to build an object file
+we will need C++ source file and C preprocessor options - quite logical. The
+third line sets target-specific variable <code>value</code> for
+<code>hello.l.cpp-options</code>: that's how <code>hello.l.cpp-options</code>
+gets its content. You may be wondering why do we need to add this
+<code>-I$(src_root)</code>. The first line of <code>hello.cxx
+</code> should clear things up:</p>
+
+<pre class="cxx">
+#include "libhello/hello.hxx"
+</pre>
+
+<p>And finally the fourth line includes auto-generated dependency
+information for each object file. You can think of
+<code>$(call -include )</code> as being equivalent to <code>-include</code>
+directive for now.</p>
+
+
+<p>Next chunk:</p>
+
+<pre class="make">
+.PHONY: $(clean)
+
+$(clean): $(hello.l).clean \
+ $(addsuffix .clean,$(cxx_obj)) \
+ $(hello.l.cpp-options).clean
+</pre>
+
+<p>Let's concentrate on the last line. There we are essentially saying that
+cleaning <code>libhello</code> consists of cleaning the library, object
+files and C preprocessor options. How does this work? It is done using
+pattern rules. Part of the build system that defines how to build say
+<code>%.l</code> also defines how to clean after it: <code>%.l.clean</code>.
+You may want to look into <code>build/cxx/gnu/o-l.make</code> for details.</p>
+
+<p>Moving on:</p>
+
+<pre class="make">
+# Aliases.
+#
+ifdef %interactive%
+
+.PHONY: clean
+
+clean: $(clean)
+
+endif
+</pre>
+
+<p>In this part we are creating a short alias (<code>clean</code>)
+for its long equivalent (<code>$(out_base)/.clean</code>). <code>
+%interactive%</code> is a <em>system variable</em> defined by
+the framework. It is initialized only if current makefile is
+used in interactive mode as opposed to being included.</p>
+
+<p>And finally:</p>
+
+<pre class="make">
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-l.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+</pre>
+
+<p>In this makefile fragment we are including parts of the build
+system that actually know <em>how to build</em>. As you might have
+noticed, all the code that we have examined up until now was dealing
+with <em>what to build</em>. <code>o-l.make</code> defines a pattern
+rule to build libraries from object files. <code>cxx-o.make</code>
+defines a pattern rule to build object files from C++ translation units.</p>
+
+<p>And this concludes our examination of the makefile for
+<code>libhello</code>. Next is the test driver(
+<code>hello/libhello/test/makefile</code>):</p>
+
+<pre class="make">
+include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make
+
+cxx_tun := driver.cxx
+cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o))
+cxx_od := $(cxx_obj:.o=.o.d)
+
+hello.l := $(out_root)/libhello/hello.l
+hello.l.cpp-options := $(out_root)/libhello/hello.l.cpp-options
+
+driver := $(out_base)/driver.e
+clean := $(out_base)/.clean
+test := $(out_base)/.test
+
+
+# Build.
+#
+$(driver): $(cxx_obj) $(hello.l)
+
+$(cxx_obj): $(hello.l.cpp-options)
+
+$(call -include,$(cxx_od))
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): $(driver)
+ $&lt;
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).clean $(addsuffix .clean,$(cxx_obj))
+
+
+# Aliases.
+#
+ifdef %interactive%
+
+.PHONY: clean test
+
+test: $(test)
+clean: $(clean)
+
+endif
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+
+
+# Load build information.
+#
+$(call load,$(src_root)/libhello/makefile)
+</pre>
+
+<p>Do you see anything unknown or strange in this makefile? I hope you don't.
+Just to re-iterate, I will remove everything we definitely saw and leave
+only what's new:</p>
+
+<pre class="make">
+hello.l := $(out_root)/libhello/hello.l
+hello.l.cpp-options := $(out_root)/libhello/hello.l.cpp-options
+
+
+# Build.
+#
+$(driver): $(cxx_obj) $(hello.l)
+
+$(cxx_obj): $(hello.l.cpp-options)
+
+
+# Load build information.
+#
+$(call load,$(src_root)/libhello/makefile)
+</pre>
+
+<p>All of what's left deals in one way or the other with linking
+to <code>libhello</code>. The first two lines define variables that
+hold paths to the library and C preprocessor options (since we are in
+the same project we know what those paths are relative to
+<code>out_root</code>/<code>src_root</code>). The third line declares that
+driver consists of object files and should be linked with
+<code>libhello</code>. The next line says that we need C preprocessor options
+to build object files, just like we did for <code>libhello</code>. And finally
+the last line: what does the <code>load</code> function do? The
+<code>load</code> function loads rules and dependency information from the
+makefile specified. Note that it doesn't make variable definitions from that
+makefile available (or, even worse, override ones we set) - only dependencies
+and rules. The major benefit of doing this is in having complete dependency
+information along with the rules in case something gets out of date. If, for
+example, we change something in <code>libhello</code> and then execute
+<code>make</code> in <code>test</code>, <code>make</code> will be able to
+detect that <code>libhello</code> is out of date and will re-build it before
+building the test driver.</p>
+
+<p>Now let's take a look at the makefile from the <code>hello</code> program
+(<code>hello/hello/makefile</code>). Remember that it is a separate project
+(I removed support for <code>install</code> target again):</p>
+
+
+<pre class="make">
+include $(dir $(lastword $(MAKEFILE_LIST)))build/bootstrap.make
+
+cxx_tun := hello.cxx
+cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o))
+cxx_od := $(cxx_obj:.o=.o.d)
+
+hello.e := $(out_base)/hello.e
+clean := $(out_base)/.clean
+
+# Secure default target.
+#
+$(hello.e):
+
+
+# Import information about libhello.
+#
+$(call import,libhello,l: hello.l,cpp-options: hello.l.cpp-options)
+
+
+# Build.
+#
+$(hello.e): $(cxx_obj) $(hello.l)
+
+$(cxx_obj): $(hello.l.cpp-options)
+
+$(call -include,$(cxx_od))
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(hello.e).clean $(addsuffix .clean,$(cxx_obj))
+
+
+# Aliases.
+#
+ifdef %interactive%
+
+.PHONY: clean
+
+clean: $(clean)
+
+endif
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+</pre>
+
+<p>Again I will remove all the parts that we are familiar with leaving
+only what's new:</p>
+
+<pre class="make">
+# Secure default target.
+#
+$(hello.e):
+
+
+# Import information about libhello.
+#
+$(call import,libhello,l: hello.l,cpp-options: hello.l.cpp-options)
+</pre>
+
+<p>Let's see what's going on here. I will start from the call to
+the <code>import</code> function. It is similar to the <code>load</code>
+function with a few exceptions. First of all, since we are importing
+build information from a separate project we don't know where to look
+for its parts; this will require dynamic configuration. Secondly, we
+have no way to figure out where <code>hello.l</code> and
+<code>hello.l.cpp-options</code> are. Thus we have
+<code>`l: hello.l'</code> and <code>`cpp-options: hello.l.cpp-options'</code>
+which essentially means "initialize variable <code>hello.l</code> with
+the library path and variable <code>hello.l.cpp-options</code> with
+the C preprocessor options file path".</p>
+
+<p>One side effect of the call to <code>import</code> function is the
+potential loss of the default target. Thus, the first line.</p>
+
+<p>The inter-project dependency importing architecture is probably
+the most complicated part of the build system. It will be described
+in a separate section.</p>
+
+<p>This concludes our step-by-step examination. It was not trivial
+but neither is building real software.</p>
+
+<h1><a name="inter_project_dependencies">Inter-Project Dependencies</a></h1>
+
+<p>To be completed.</p>
+
+
+<h1><a name="administrivia">Administrivia</a></h1>
+
+
+<h2><a name="license">License</a></h2>
+
+<p>The <em>build</em> runtime (makefiles, scripts, etc.) is distributed under
+the terms of the <a href="http://www.codesynthesis.com/licenses/gpl-2.txt">GNU General
+Public License, version 2</a>. <em>Build</em> documentation is distributed
+under the terms of the <a href="http://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU
+Free Documentation License, version 1.2</a>.</p>
+
+<p>In particular, this means that any makefile, script, etc., that
+includes, calls, or otherwise links to the <em>build</em> runtime must
+be covered by a GPL-compatible license, should you decide to distribute
+them.</p>
+
+
+<h2><a name="bootstrapping">Bootstrapping</a></h2>
+
+<p>There are two ways to use the build system: your project can embed
+all necessary files or you can require the <em>build</em> runtime to be
+installed. The first approach allows you to make your project self-content,
+modulo other external dependencies it might have. The disadvantage of this
+approach manifests itself when your project participates in a build with
+inter-project dependencies established: your project and the rest of the
+build could use different (and potentially incompatible) versions of the
+runtime. There is no such problem with the second approach.</p>
+
+<p>My advice is to go with the installed <em>build</em> unless you have
+a compelling reason to do otherwise.</p>
+
+<p>When you go with the embedded runtime you can copy all necessary files
+to your project's <code>build/</code> directory. When you use external
+<em>build</em> your <code>build/bootstrap.make</code> might look something
+like this:</p>
+
+<pre class="make">
+project_name := libhello
+include build-0.1/bootstrap.make
+</pre>
+
+<p>How will <code>make</code> find <code>build-0.1/bootstrap.make</code>?
+There are two ways this can happen: you have the runtime installed (e.g.,
+into <code>/usr/local/include</code>) where <code>make</code> will look
+for it by default or you can tell <code>make</code> where to look using
+<code>-I</code> option in the command line or by setting
+<code>MAKEFLAGS</code> environment variable.</p>
+
+<h2><a name="versioning">Versioning</a></h2>
+
+<p><em>Build</em> uses a three-digit versioning scheme: <code>X.Y.Z</code>.
+<code>X</code> is a generation number; it is incremented when a completely
+new design is implemented. <code>Y</code> is an interface version; two
+<em>build</em> runtimes with different <code>Y</code> have incompatible
+interfaces even though the ideology is the same (if ideology changes
+<code>X</code> will most likely be incremented). Additionally, odd
+<code>Y</code> indicates that it's a development release (similar to
+the linux kernel). Finally, <code>Z</code> signifies a release number.
+Releases with the same <code>X.Y</code> have the same interface.</p>
+
+<p>To allow co-existence of several versions of <em>build</em> on the
+same system, the <code>X.Y</code> pair is made part of the path (e.g.,
+<code>/usr/include/build-0.1</code>) thus when you bootstrap the runtime
+(in a project-specific <code>bootstrap.make</code>) you specify interface
+version:</p>
+
+<pre class="make">
+include build-0.1/bootstrap.make
+</pre>
+</div>
+
+
+<div id="docinfo">
+<p>Copyright &copy; 2004-2010 <a href="http://www.codesynthesis.com">Code Synthesis Tools CC</a>.</p>
+
+<div class="terms">
+Permission is granted to copy, distribute and/or modify this document under
+the terms of the <a href="http://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU Free
+Documentation License, version 1.2</a>; with no Invariant Sections, no
+Front-Cover Texts and no Back-Cover Texts.
+</div>
+</div>
+
+</body>
+</html>