The dtrace build system is intended to take some of the repetitive pain
out of make.  The build system's components are:

 - GNUmakefile: the top-level file.  Sets some variables, runs
                everything else

 - Makefunctions: defines a few functions that other files can
                  use, and a set of templates which generate make
                  rules for building various things.

 - */Build: each of these specifies the building of a library
            or a set of commands out of the contents of some
            directory.

 - Makerules: this triggers the building of all commands and
              libraries specified in the Build files.

 - Makeconfig: this can scan for symbols in libraries, like Autoconf's
               AC_CHECK_LIB, and generate a config.h header that describes
               whether those symbols are present.  (This header file exists
               even if no such checks are done, and every compiled C file
               is forced to depend on it.)

The Build files are perfectly normal makefiles, with a few caveats.  Firstly,
they are *included* by the top-level makefile, not recursively run by it.
This has advantages (the ability to do proper cross-directory dependencies
and maximum-speed parallel make) and disadvantages (you have to specify
directory names everywhere).

A note about library construction.  Libraries are somewhat unusually built, in
that libraries (be they shared or static) for installation are assembled from
one or more *build libraries* (which are, as usual, put together from one or
more object files).  You cannot link against build libraries (or not easily,
anyway), you can only assemble them into larger units.  For shared libraries,
some of these build libraries are *primary*, meaning that their entire contents
are included in the shared library whether referenced elsewhere in the shared
library or not: the rest are *secondary*, meaning that their contents are
included only if needed by other parts of the shared library.  (Build libraries
containing symbols in the library's public API should generally be primary).  By
default, all build libraries in a shared library are primary.


This mechanism eases construction of installed libraries from the contents of
more than one directory without requiring Build files to be filled with ugly
cross-directory references, and without sacrificing proper dependency analysis.

You name build libraries, static and shared libraries, and binaries for
installation by assignment to the following variables in Build files.  The names
can be anything you like, and do not have to be the same as the generated output
file, which allows you to have similarly-named output files with different build
rules if you need to do so.

BUILDLIBS += build library target names
LIBS += static library target names
SHLIBS += shared library target names (can also appear in LIBS for libraries
          that should have both static and shared forms)
CMDS += command names

All of the names in the variables above can have the following variables
associated with them, usually in the same Build file:

name_DIR := $(current-dir) (obligatory)
name_TARGET = name of library or binary to build for this name, without
              directory or any necessary suffix.  Build libraries
              get 'build-' stuck on the front of this name automatically,
              to enforce uniqueness. (obligatory)
name_POST := list of names of Make variables which should be run
             after this target is linked: $(1) is the name of the
             target just created, with path, and with initial 'build-'
             for build libraries.

Names in the BUILDLIBS and CMDS (the only things produced directly by
compilation of source code) can have the following variables associated with
them:

name_SOURCES = list of source filenames
name_CPPFLAGS = list of preprocessor flags applying to this target
name_CFLAGS := list of cflags applying only to this target (can also be applied
               to individual source files)
name_NOCFLAGS := list of cflags which should never be applied to this target,
                 even if they would otherwise appear in CFLAGS (can also be
                 applied to individual source files)
name_NOLDFLAGS := list of cflags which should never be applied to this target,
                 even if they would otherwise appear in LDFLAGS
name_EXPLICIT := list of source files with explicit targets for which
                 automatic targets should not be generated
name_DEPS := list of explicit dependencies in the build tree
             applying to this target's link step
name_SRCDEPS := list of explicit dependencies for (built) source files to be
                added to the dep list of every target.  If no pathname is
                specified, the source files are assumed to be in the same
                directory as the name_SOURCES.
name_PROV := name of a DTrade provider definition file (.d) that is to be
             compiled in with the named target (shared library or executable).
             It will be used to generate a header file (.h) containing macros
             for the USDT probes specified for the provider, and a object file
             (.o) with a DOF section that contains the provider definition to
             be passed to the kernel.

Names in the SHLIBS and CMDS (the only things processed by the linker) can have
the following variables associated with them:

name_LDFLAGS := list of ldflags applying only to this target
name_LIBS := list of libraries applying only to this target.  Full ld syntax,
             including -l.  A -L argument specifying the object file directory
             is automatically prepended to this list.

Names in the LIBS and SHLIBS must have the following variables associated with
them:

name_LIBSOURCES := list of BUILDLIBS whose contents go into this target:
                   by default, all are primary.  The leading 'build-' is
                   added automatically.

Names in the SHLIBS can have the following variables associated with them:

name_VERSION := version of this target (strongly recommended)
name_SOANME := soname of this target (strongly recommended)
name_VERSCRIPT := filename of version script for this target
name_SECONDARY := list of secondary BUILDLIBS for this target

Extra targets with custom rules can be added as desired by appending to TARGETS
and name_EXPLICIT: libdtrace/ uses this to build object files and .d files.
There is no attempt to automate installation rules, so you'll probably need
install targets here and there.  You probably don't want to install build
libraries, but there is no explicit attempt to stop you.


Finally, a note on quiet builds.  If 'verbose=yes' is not specified at make time,
all command echoing is suppressed.  To produce output, two make functions are
provided, 'describe-target' and 'describe-install-target', which you might want
to use in custom rules and install targets.  The former, if called like this:

	$(call describe-target,ACTION,file1 file2 file3)

will print

ACTION: file1
ACTION: file2
ACTION: file3

The latter, if called like this:

	$(call describe-install-target,/install/directory,file1 file2 file3)

will print

INSTALL: /install/directory/file1
INSTALL: /install/directory/file2
INSTALL: /install/directory/file3

You probably want to put a single call to 'describe-target' at the top of a
custom rule, and put calls to 'describe-install-target' right before each
invocation of 'install', so that failed installations will indicate their
failure by the last line they print.  (This is notably annoying: in the future,
it may be automated away.)
