This commit is contained in:
David Rose 2002-02-06 19:35:22 +00:00
parent c9dbb74fe3
commit aa14222063
3 changed files with 199 additions and 2 deletions

View File

@ -44,6 +44,25 @@ WHY PPREMAKE?
the other.
WHAT IS PPREMAKE, EXACTLY?
By design, ppremake is more of a scripting language framework than a
specific application. It is intended to contain as few assumptions
as possible about the structure of the source tree it is processing
or the precise nature of the makefiles (or other build scripts) it
is generating.
The ppremake executable is hardcoded to define a set of useful
predefined variables and functions, and to follow a particular
procedure to get started scanning a source directory when it is
invoked. However, once it is started, the actual behavior of
ppremake, including the meaning of all the variables defined within
the various Sources.pp files (see below) and all of the generated
output, is almost entirely controlled by scripts written in its own
scripting language. Most of these are control scripts are defined
in the directory $DTOOL/pptempl.
SOURCE TREE AND INSTALL TREE HIERARCHY
The layout of the source tree and of the install tree for Panda are

View File

@ -0,0 +1,142 @@
The following steps are executed when ppremake is invoked:
1. Look in the current directory for a file called Package.pp. If
it is not found, but Sources.pp is present in the current
directory, then look for Package.pp in the parent directory.
Repeat until Package.pp is located; this is the root of the
source directory hierarchy.
2. Read and interpret the Package.pp file. This should, in turn,
read in (via the #include directive; see below) whatever other
configuration scripts are relevant to the current package. The
exact behavior of Package.pp is not hardcoded into ppremake, but
the Package.pp scripts for each of the Panda directories will
ultimately include the following files in order:
Any Package.pp for a dependent tree (e.g. $PANDA/Package.pp, etc.)
$DTOOL/Package.pp
$DTOOL/Config.pp
$DTOOL/Config.Platform.pp
The user's Config.pp file, as specified by $PPREMAKE_CONFIG.
$DTOOL/pptempl/System.pp
The various Package.pp files are designed to cascade down, such
that when you invoke ppremake from a high-level tree, such as
Direct (for instance), ppremake invokes $DIRECT/Package.pp, which
in turn invokes $PANDA/Package.pp, which in turn invokes
$DTOOL/Package.pp. At the bottom level, $DTOOL/Package.pp does
most of the remaining setup work, in particular including the
various Config.pp files, and System.pp.
The Config.pp files are intended to define the variables the user
might customize for a particular build environment; the user's
personal Config.pp file is included last, and may override any of
the default values defined in the system Config.pp files.
One particularly critical variable that is defined by Config.pp
is $[BUILD_TYPE]. This represents the type of makefile rules
that are to be generated, e.g. "unix" to generate standard
Unix-style makefile syntax, or "msvc" to generate syntax specific
to Microsoft's nmake. The particular string specified here
controls the selection of which Template files are to be loaded
in a later step to actually generate output files in each source
directory.
The System.pp file is also essential and defines a few more
variables that ppremake will be looking for during its execution.
This tells ppremake the names of certain critical files that it
needs to include. The use of System.pp to define these
filenames, instead of hardcoding them into ppremake, is
consistent with the ppremake philosophy of letting as much of its
behavior as possible to be controlled from within the scripting
language itself.
3. Once Package.pp has been read, traverse the entire source
hierarchy, and read each Sources.pp file. A separate named scope
is defined for each Sources.pp file; the name of the scope is
taken from the name of the directory containing the file.
4. Read in the global variable declarations. This is loaded from a
particular file specified by System.pp; this file defines global
declarations that will be useful when processing each Template
file later. To save time, this file is read once and stored in a
global scope, rather than re-read with each Template file. The
particular filename is specified by the ppremake variable
$[GLOBAL_FILE], which was set by System.pp; normally this is
$DTOOL/pptempl/Global.pp.
$DTOOL/pptempl/Global.pp will, in turn, also read in the file
$DTOOL/pptempl/Global.$[BUILD_TYPE].pp if it exists, which may
specify further global declarations that are specific to the
particular build type in effect. Remember, $[BUILD_TYPE] was
specified when Config.pp was read, and controls the particular
type of makefiles or build scripts that are to be generated.
5. Build the inter-directory dependency chain. This is the chain of
relationships between different directories within the source
hierarchy. Each directory may depend on code from zero or more
other directories within the same package. (That is, a directory
may include header files define within another directory, and/or
require linking with a library built in that directory.)
This inter-directory dependency is critical to determine things
such as build order. If one directory must be built before
another directory, the makefiles must be constructed with this
relationship explicit.
This relationship is determined for each directory by executing
the script named by $[DEPENDS_FILE] (this variable was set by
System.pp) within each source directory scope. Remember, each
Sources.pp file has already been read in, and assigned its own
unique named scope. The DEPENDS_FILE script is responsible for
defining the variable $[DEPEND_DIRS] to contain the
space-separated list of directories (that is, named scopes) that
the files in this current directory depend on.
Normally, System.pp sets $[DEPENDS_FILE] to
$DTOOL/pptempl/Depends.pp. This script builds up $[DEPEND_DIRS]
based on the $[get_depend_libs] function which is defined in
Global.pp, which is in turn based on variables like $[LOCAL_LIBS]
defined within the Sources.pp file.
The inter-directory dependency information can be accessed from
within ppremake scripts simply by examining the $[DEPEND_DIRS]
variable within the appropriate scope. In addition, the
directory relationships are automatically used to sort the
variables $[SUBDIR] and $[SUBTREE] in order, such that each
directory is listed after the directories it depends on.
There is one other variable which should be defined by the
DEPENDS_FILE script: $[DEPENDABLE_HEADERS] should list the source
files within the current directory that may be named as #include
files in other files. This is used to build file-level
dependencies to support the $[dependencies] built-in function,
and is not related to inter-directory dependencies.
6. Finally, generate the actual output files in each source
directory. This is done by executing the script named by
$[TEMPLATE_FILE] (set by System.pp) within each source directory
scope.
Normally, System.pp sets $[TEMPLATE_FILE] to
$DTOOL/pptempl/Template.$[BUILD_TYPE].pp. Recall again that
$[BUILD_TYPE] was specified when Config.pp was read, and controls
the particular type of makefiles or build scripts that are to be
generated, so there is a different Template script file for each
supported build type.
The Template file is responsible for generating the actual
makefile (or whatever build script is required) as appropriate to
each source directory. It now has all the information required:
all source directories have been read, so the relationships
between different source directories can control the output;
also, the inter-directory and inter-file dependencies are
available.
Generally, a Template file will include at least one #output
directive to generate the appropriate makefile for this
directory. Since there may be different kinds of source
directories, each with very different makefile requirements, the
Template files usually have one large #if condition based on the
value of $[DIR_TYPE], which is set within in each Sources.pp (and
is set in System.pp to default to "src").

View File

@ -77,11 +77,14 @@ scanned:
$[SUBDIRS] - A space-delimited list of source subdirectories within
this source directory. These are simply directory names, without
slashes; prefix each name with $[DIRPREFIX] to make them relative
to $[TOPDIR].
to $[TOPDIR]. These are automatically sorted in dependency order,
such that a particular directory always appears following all the
directories it depends on.
$[SUBTREE] - A space-delimited list of names of all source
subdirectories, including this one, at this level and below. The
subdirectory names are relative to $[TOPDIR].
subdirectory names are relative to $[TOPDIR]. As above, these are
sorted into dependency order.
The following variables are built into the ppremake executable, and
are updated with the current values as *each* different file is read
@ -104,6 +107,39 @@ filled in after all Sources.pp files have been read:
until after all the Sources.pp files have been read, so it cannot
itself be referenced within a Sources.pp file.
The following variables are not set by the ppremake executable, but
are required to be set by one of the startup scripts, typically
$DTOOL/pptempl/System.pp:
$[GLOBAL_FILE] - the full pathname to the file that should be read
within the global scope after reading each Sources.pp file and
before reading each Template file.
$[TEMPLATE_FILE] - the full pathname to the file that should be read
once for each Sources.pp file to generate the actual output
makefiles appropriate to each directory.
$[DEPENDS_FILE] - the full pathname to the file that should be read
once for each Sources.pp file to determine the inter-directory
dependencies and inter-file dependencies.
$[DEPENDENCY_CACHE_FILENAME] - the name of the file (with no
directory part of the filename) that is used to cache the
inter-file dependencies for each source file in a given directory
between sessions. A file by this name is automatically created in
each source directory.
$[DEPEND_DIRS] - the list of directories that the current directory
depends on. This is set by the script named by $[DEPENDS_FILE],
and has a different value within each source directory.
$[DEPENDABLE_HEADERS] - the list of source filenames within the
current directory that are considered source header files and that
might be listed with the #include directory in some other file.
This is used to determine the set of inter-file dependencies.
Like $[DEPEND_DIRS], this is set by the $[DEPENDS_FILE] script,
and has a different value within each source directory.
The following functions are built into the ppremake executable. In
general, these operate on one word or a group of words separated by