diff --git a/panda/src/doc/ppremake-philosophy.txt b/panda/src/doc/ppremake-philosophy.txt index 06a6865f42..68fe334926 100644 --- a/panda/src/doc/ppremake-philosophy.txt +++ b/panda/src/doc/ppremake-philosophy.txt @@ -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 diff --git a/panda/src/doc/ppremake-process.txt b/panda/src/doc/ppremake-process.txt new file mode 100644 index 0000000000..09845ccf91 --- /dev/null +++ b/panda/src/doc/ppremake-process.txt @@ -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"). diff --git a/panda/src/doc/ppremake-variables.txt b/panda/src/doc/ppremake-variables.txt index 40b3cc5031..fc7e6e2351 100644 --- a/panda/src/doc/ppremake-variables.txt +++ b/panda/src/doc/ppremake-variables.txt @@ -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