Provided by: makepp_2.0.98.5-2_all bug


       makepp_scanning -- How makepp finds include files and other hidden dependencies


       Makepp can determine additional dependencies or targets for certain commands that it knows
       something about.  This is especially important for C/C++ compilation, where it is too
       error-prone to list manually all of the include files that a given source file depends on.
       By looking at the compilation command and the source files themselves, makepp is able to
       determine accurately which object files need to be rebuilt when some include file changes.

       Example: Given a rule

           foo.o:                      # Usually %.o: %.c, just for illustration
               time -p /bin/libtool -bar /usr/bin/cc -c -I somewhere foo.c

       makepp knows that "time" and "libtool" must be skipped and that "cc" is the actual command
       to be parsed here.  It understands that foo.c is the input file and thus a dependency of
       this rule.  Moreover it will scan that file looking for include statements, also in
       directory somewhere, because it understood the command options.

       Actually there are three steps to what is historically known as scanning:

       1.  The rule action is split into lines (continuation lines count as one).  Each line
           (except builtins and Perl blocks) is lexically analyzed as one or more Shell commands.
           Redirections are recognized as inputs or outputs to this rule.  The first word of each
           command is looked up (with its directory part but, if not found, again without it) to
           find a parser for it.  These become optional dependencies, they are built if possible,
           but ignored if not found, as makepp can't know which part of a complex command is
           actually run.

           Commands in backquotes are analyzed but not executed.  (Often execution is important,
           but this would be a major interference by makepp.)  It is better style to avoid them.
           Instead have makepp run the command at most once by assigning it in this special way:

               XYZFLAGS ;= $(shell pkg-config --cflags xyz)

           Currently there is only one lexer class, which understands Bourne Shell.  To better
           handle C Shell or "", subclasses might be created.  However, much syntax is
           similar enough to not warrant this.  Get in touch if you want to contribute either.

       2.  For known commands the corresponding command parser (also referred to just as parser)
           analyzes the important options and arguments.  The available ones are described below.

           Even if no specialized parser was found, the generic one makes the command executable
           an input of this rule.  You can change that with the --no-path-executable-dependencies
           command option.

       3.  If the parser recognized any input files, they get sent to the scanner chosen by the
           parser.  It finds further inputs by looking for "#include" or comparable statements.

           This is the most expensive step.  All the results get cached to avoid repeating it

       If makepp thinks it's compiling a C/C++ source but can't find a parser, it will give a
       warning message to let you know.  This usually means that you buried your compiler command
       too deeply in the action for makepp to find it.  For example, I have seen rules like this:

           %.o: %.c
               @echo Compiling $< now; obscure_wrapper gcc -c $< $(CFLAGS) -o $@

       The first words of the actions here are "echo" and "obscure_wrapper", for which there are
       no parsers, so makepp will not scan for include files in this case.  You can ignore the
       prefixed command by:

           register-parser obscure_wrapper skip-word

       The following sections document the built in parsers and scanners.  In the name you can
       use "-" interchangeably with "_".


       The various scanners must be chosen by a command parser, which is given in parentheses:

   C/C++ compilation (c-compilation, gcc-compilation)
       The C/C++ scanner, handles both languages indifferently.  In fact it looks only at
       preprocessor statements, so it can be used for quite a few languages.  The parser that
       activates it has a special variant for gcc's many options, which gets chosen if the
       command name includes the string "gcc" or g++.  If compilers for other languages with C
       preprocessor use the same options as the C compiler (at least "-I") then this parser works

       It looks at the command for "-Idir" options specifying the include path or "-Ldir" options
       specifying the link path.  It then scans any source files for "#include" directives, and
       also looks at the command line to see if there are any source files or libraries mentioned
       which are not listed as dependencies.  It recognizes these by their extension.

       This scanner gives a warning message if files included with "#include "file.h"" are not
       found, or not buildable by makepp, in the include path, or in the directory containing the
       file which is "#includ"ing, or in /usr/include.  No warning is given if a file included
       with "#include <file.h>" is not found.  Makepp assumes it is in some system include
       directory that the compiler knows about, and that files in system include directories
       won't change.

       In addition, files in /usr/include, /usr/local/include, /usr/X11R6/include, and any other
       directory which is not writable are not scanned to see what they include.  Makepp assumes
       that these files won't change.  (If you're running as root, the writability test is
       performed with the UID and GID of the directory you ran makepp from.  This is so compiling
       a program as an ordinary user and then doing "makepp install" as root won't cause extra
       directories to be scanned.)

       This is a fairly simple-minded scanner.  It will get confused if you do things like this:

           #ifdef INCLUDE_THIS
           #include "this.h"

       because it doesn't know about preprocessor conditionals.  This is usually harmless; it
       might cause additional extra files to be labeled as dependencies (occasionally causing
       unnecessary rebuilds), or else it might cause makepp to warn that the include file was not
       found.  You can either ignore the warning messages, or put an empty file "this.h" out
       there to shut makepp up.

       If your compiler has a funny name, you can say either of

           register-parser obscure_c_compiler c-compilation
           register-parser obscure_gcc_alias gcc-compilation

   Embedded SQL C/C++ compilation (esql-compilation)
       These commands, which come with the various databases, preprocess special sections in
       otherwise C/C++-like sources, and produce C/C++ headers and sources.  This finds EXEC SQL
       INCLUDE "filename" or $INCLUDE "filename" directives.

       These preprocessors are recognized: Altibase APRE*C/C++ (apre), CASEMaker DBMaker
       (dmppcc), Firebird / InterBase (gpre), IBM DB2 (db2 precompile, db2 prep) & Informix
       ESQL/C (esql), Ingres (esqlc), Mimer (esql), Oracle (proc), PostgreSQL (ecpg) & YARD
       (yardpc).  If your preprocessor is not recognized, you can say

           register-parser obscure_esqlc_preprocessor esql-compilation

       This will however only handle the style common to Informix and others: Command arguments
       ending in ".ec" are files to be scanned, "-I" defines the include path and EXEC SQL
       INCLUDE directives without a suffix get ".h" appended.

   Swig (swig)
       Swig (Simplified Wrapper and Interface Generator, is a program that
       converts a C/C++ header file into the wrapper functions needed to make your code callable
       from a variety of other languages, such as Perl, Python, Tcl, C#, Ruby, OCaml, and
       probably some others that I don't know about.

       Makepp understands and parses the swig command line, looking for "-I" and "-l" options.
       It also knows how to scan swig's interface definition files (.i files) looking for
       %include, %import, and also "#include" if "-includeall" is in effect.

       If your swig has a funny name, you can say

           register-parser obscure_swig_alias swig

   Vera and Verilog (vcs_compilation)
       If you design hardware, this will come in handy.

   Ignorable wrappers (skip-word, shell)
       Makepp recognizes the following command words and many more and skips over them
       appropriately in in its search for the correct scanner: "condor_compile", "distcc",
       "ignore_error", "libtool", "noecho" "purify".

       There is a variant of this which finds the nested commands in "sh -c 'command1;

       If you have more such commands, you can say

           register-parser command skip-word


       Libtool is a very clever compilation system that greatly simplifies making shared
       libraries by hiding all the system-dependent details away in a shell script.  The only
       difficulty is that the library binary files are not actually stored in the same directory
       as the output file--libtool actually creates a subdirectory, ".libs", which contains the
       real files.  This is ordinarily not a problem, but makepp has to know where the real
       binaries are if it is to link them in from a repository.  At the moment, libtool libraries
       (".la" files) are not linked in from repositories; they are always rebuilt if needed.
       Also, makepp at the moment is not able to use the dependency information that is stored
       inside the ".la" file itself.  This will hopefully change soon.

   Suppressing the scan (none)
       Sometimes you may not want a rule or a certain command to be parsed.  You can turn off
       parsing and thereby scanning with

           register-parser cc none


   Quickscan and smartscan
       The ":quickscan" and ":smartscan" rule options, if applicable, affect the way that files
       are scanned.

       In ":quickscan" mode (the default), all include directives are assumed active. This allows
       for very efficient scanning.

       In ":smartscan" mode, an attempt is made to interpret macros and expressions so that
       inactive include directives are ignored.  For example, the executable produced by
       compiling the following C program ought not to depend on foo.h:

           #if 0
           #include "foo.h"
           int main() { return 0; }


       You can specify your own parser either in a rule option like ":parser foo", or by using
       the "register_parser" or "register_command_parser" statements.

       Either way, as described under "register_parser", there you must directly or indirectly
       (via a class) specify a function that creates a parser object.  This object will usually
       create a scanner object for files, and feed it with its findings from the command line
       options.  These two objects will call the parser's "add_*_dependency" methods which
       forward the information to the somewhat more complicated "Mpp::Lexer::add_*_dependency"
       utility functions.

       However your parser function can also do this work itself for simple cases.  There are a
       couple of special return values if this function doesn't return a parser object:

           The scan info is not cacheable and must be recalculated next time the rule's target
           needs to be built.

       "p_none, p_skip_word" or "p_shell"
           These are in fact numeric constants, which tell the lexer to do the work of these

       any reference, e.g. "\1"
           This is equivalent to returning a parser object of the "Mpp::CommandParser" base
           class, which will only additionally make the command executable itself a dependency.

       In most cases, objects of type "Mpp::CommandParser" should instantiate at least one object
       of type "Mpp::Scanner".  The "Mpp::Scanner" base class takes care of the distinction
       between quickscan and smartscan.  Note that the behavior of "Mpp::Scanner" can be markedly
       affected by this distinction, but that should be transparent to the derived class if it is
       well-formed.  New derived "Mpp::Scanner" classes ought to be tested in both modes.

       If you write your own "Mpp::Scanner" class, you should also base your rescanning decision
       on the build info "RESCAN".  This gets set by "makeppreplay" after signing files without
       scanning.  So despite the signatures being consistent, a rescan is still necessary.  If
       your "Mpp::Scanner" uses the inherited "scan_file1" method, you're probably fine.

       For more details, refer to the respective class documentation.  For examples, see
       "Mpp::CommandParser::Gcc" and "Mpp::CommandParser::Vcs".  Look at the "p_" functions in
       Mpp/ which get aliased into their respective classes as "factory" when loaded.

   Caching scanner info
       If the all of the scanner's important side effects are effected through calls to methods
       of the "Mpp::CommandParser" base class, then those side effects can be cached in the build
       info file, so that they can be played back by a subsequent invocation of makepp without
       doing all of the costly scanning work.  This can save quite a bit of time, especially in
       smartscan mode.

       If the scanner has other important side effects, then it should call the "Rule" object's
       mark_scaninfo_uncacheable method.  Otherwise, the scanner info retrieved from the build
       info may be inaccurate, causing the build result possibly to be incorrect.  This method is
       called automatically when a value from the %parsers hash does not return an object of type
       "Mpp::CommandParser", or when the parser is specified with a rule option and the "p_*"
       routine does not return an object of type "Mpp::CommandParser".

       Cached scan info is invalidated using criteria similar to those used for determining when
       the target is out of date.  Similarly, it can be retrieved from a repository using
       criteria similar to those used for determining when a target can be linked in from a

       You can force makepp to ignore the cached scanner info with the "--force-rescan" option.
       This is useful when a broken scanner may have caused incorrect scanner info to be cached.

   Ad Hoc Scanner
       Often you will have just one or few files which contain dependency information.  You don't
       want to write this into a makefile redundantly (since redundancy later often leads to
       inconsistencies when one update gets forgotten).  But you also don't want to write a
       Mpp::Scanner?  As a workaround you can generate an include file on the fly.  For example
       Qt has .qrc files which can look like:

             <qresource prefix="...">

       If you adhere to the above layout, you can transform the relevant lines into a makepp
       include file, which gets automatically created by being included.

           %.qrc.makepp: %.qrc
               &grep 's!<RCC>\n!$(stem).cc:! || s! *<file>! ! && s!</file>\n!!' $(input) -o $(output)

           include $(wildcard *.qrc)   # .makepp is appended automatically

       Several variants of this are given in the Cookbook.  The drawback is that you begin
       building while reading the makefile.  So the --loop command option will not be so useful
       on the first iteration.