Provided by: makepp_2.0.98.5-2.1_all bug

NAME

       makepp_incompatibilities -- Incompatibilities between makepp and GNU make

DESCRIPTION

       Makepp was designed to be as close as possible to GNU make
       (<http://www.gnu.org/software/make/manual/make.html>).  GNU autotools
       (<http://www.gnu.org/software/automake/manual/automake.html>), CMake
       (<http://www.cmake.org/>), Premake (<http://industriousone.com/premake> and see remark
       below) or handcrafted legacy build systems should be buildable with makepp.  This is so
       you can either migrate projects effortlessly.  Or if you don't want to enjoy all of
       makepp's advantages (e.g. so others can still build your project with GNU make) while you
       profit from the reliability advantage for your development.

       However, because of the difference in philosophy, some of GNU make's or POSIX make's
       (<http://pubs.opengroup.org/onlinepubs/009695399/utilities/make.html>) features cannot be
       supported.  A few have not been implemented because we haven't had time.  Most of the
       differences from GNU make are quite technical and only rarely cause problems.  Alas the
       workarounds for the short-comings of traditional make are becoming more and more complex,
       and are giving makepp a hard time.

       In a nutshell, if it doesn't build out of the box, try:

           makepp --no-warn makepp_simple_concatenation=1 makepp_percent_subdirs=1 \
               --build-check=target_newer --last-chance-rules --no-remake-makefiles

       If that succeeds, you can try to eliminate those arguments one by one.  But if that fails,
       try adding:

               --traditional-recursive-make

       If that also fails, the build system needs some tweaking to cooperate with makepp.  Even
       if some options described here make something buildable, it is still recommended to adapt
       things slightly, so they become compatible out of the box with both makes.

Forcing more POSIX or GNU make compatibility

       Here are some command line possibilities for getting many legacy build systems to work
       without modification.  They cause makepp to emulate GNU make's behavior precisely.

   Compatibility via the option: "--build-check=target_newer"
       By default, makepp will attempt to rebuild all targets if any of the dependencies have
       changed since the last build, or if the command has changed (see makepp_build_check for
       details).  This is normally what you want.  Sometimes, however, you don't want the target
       to be rebuilt if it has been modified apart from the control of makepp (e.g., by editing
       it, or by running a program manually to make the file).  You can force makepp to use the
       traditional make algorithm, which only rebuilds if any of the targets are newer than the
       dependencies, by adding this option to the command line.

   Compatibility via the option: "--dont-build=config.status"
       There are packages which try to autoconfigure themselves, or do other things, which gmake
       ignores unless being asked to, like:

           config.status : configure
               ./config.status --recheck

           configure : configure.in aclocal.m4
               autoconf

       Most people don't even have "autoconf" installed, so conscientiously doing everything by
       the rules, as makepp does, will fail.  This option prevents that, if you figure out what
       not to build.

   Compatibility via the option: "--last-chance-rules"
       Default rules (pattern rules with no pattern dependencies) are not normally supported.
       Makepp instantiates all rules based on the existing files, so that it is aware of every
       file that could be generated.  Alas this way it does not know how to instantiate a pattern
       rule with no pattern dependency.  The :last_chance mechanism partially remedies that.
       Where this is good enough for legacy makefiles, this option allows turning it on globally.

   Compatibility via the option: "--no-warn"
       This one doesn't improve the result.  Makepp will give warning messages for many things
       which the traditional Unix make accepts without flinching.  This is because there are
       better ways to do them with makepp.  If these warnings annoy you, you can turn them off
       with this option.

   Compatibility via the option: "--hybrid-recursive-make"
       Recursive invocations of make are often considered to be an unsafe practice (see "Better
       system for hierarchical builds" in makepp for details), but they are extremely common in
       existing makefiles.  Makepp supports recursive make for backward compatibility; for new
       makefiles, it is much better to use the "load_makefile" statement, or makepp's implicit
       makefile loading mechanism.

       In order to be able to use repositories for variant builds, and to help make recursive
       invocations of make safer, makepp normally does not actually invoke itself recursively
       even if you tell it to.  Instead, a subprocess communicates with the parent process, and
       the actual build is done by the parent process.

       This works in most cases, but you may not invoke several makefiles from the same
       directory, e.g., the following will not work:

           target: dependencies
               $(MAKE) -f other_makefile targets

       In this case makepp notices it is loading a 2nd makefile and complains.  With this option
       instead it will fall back to the traditional way of building from additional makefiles in
       a separate makepp process each.

       Note: Technically loading several makefiles would be no problem, but they usually have the
       same phony target names.  Keeping that apart would mean a complete redesign of makepp
       internals.  However, this will work, but it is not equivalent:

           target: dependencies
               cd subdir && $(MAKE) -f other_makefile targets

   Compatibility via the option: "--traditional-recursive-make"
       Sometimes the previous option is not enough, especially if the recursive invocations use
       contradictory options.  Makepp uses only one set of global options, so a submake is not
       allowed to modify them, as that would also pertain to other makefiles.

       Adding this option to the command line, has the following undesirable side effects:

       •   Recursive makes do not internally execute in parallel, even if the parent does.
           Unlike gmake there is no overall coordination of the number of processes.  This will
           not be implemented because this way of working is not a design goal of makepp.

       •   Recursive make processes do not know anything about repositories.

       •   Each recursive make process produces its own log file, in the directory it is invoked
           in, instead of producing one log file for the entire build.

       •   Since makepp usually builds more than traditional make deems necessary, and since many
           build systems provide recursive calls in all directions, this may lead to endless
           recursion.  Makepp will pull the brake after 50 rounds and tell you how to increase
           that, in case you really have such deep nesting.

       Even with the "--traditional-recursive-make" option, the environment variables
       "MAKEOVERRIDES" and "MFLAGS" are not set up, and ignored, so makefiles that depend on
       those will not work.

       A Premake generated Makefile is only a funny wrapper to a sub-make invocation in the same
       directory.  If you have some project target XYZ it will have a line like

               @${MAKE} --no-print-directory -C . -f XYZ.make

       In this case you can avoid the "--traditional-recursive-make" option by directly invoking
       makepp with that "-f XYZ.make" option.

   Compatibility without the option: "--jobs=n"
       Legacy makefiles will sometimes not list all dependencies, relying on the order of
       execution to make them in time.  In this situation makepp may manage to call a rule before
       its dependencies have all been made.  Then results may be better with less, or even no
       parallel execution.

   Compatibility via the variable: "makepp_simple_concatenation=1"
       Rc-style substitution is the default way makepp performs variable substitution into text
       strings because it very rarely breaks legacy makefiles and is often useful in new
       makefiles.  However, it does introduce occasional incompatibilities in the substitution of
       variables not surrounded by spaces.  For example,

           INCLUDE_PREFIX := -I/some/include/dir -I
           INCLUDES := $(INCLUDE_PREFIX)/other/include/dir

       will set "INCLUDES" to "-I/some/include/dir/other/include/dir -I/other/include/dir" if rc-
       style substitution is enabled, whereas GNU make would set it to
       "-I/some/include/dir -I/other/include/dir".  E.g., when compiling Redis 2.6.5 it tries to
       run "printfgcc".  Such a funny concatenation of two commands is a strong indication that
       this variable is needed to fall back to make semantics.

       There is also an incompatibility in the handling of whitespace in a variable:

           null :=
           T := -o $(null)             # T contains -o followed by one space.
           OUTFILE = $(T)outfile

       will set "OUTFILE" to "-ooutfile" if rc-style substitution is enabled, whereas GNU make
       would set it to "-o outfile".

       Both of these incompatibilities are removed by setting the "makepp_simple_concatenation"
       variable.  Note, however, that even with "makepp_simple_concatenation", makepp still
       treats whitespace incompatibly in some situations:

           T := -o # Don't delete this comment.

       GNU make sets "T" to contain "-o" followed by a space, whereas makepp strips out the
       trailing space anyway.  If you want the trailing space, you must set
       "makepp_simple_concatenation" and also set "T" using the technique involving a dummy
       variable such as "null", as shown above.

   Workaround option "--no-remake-makefiles"
       Typical open source requires calling "configure" to create the makefiles.  But then these
       makefiles can contain rules to remake the makefile, by calling some command.  Makepp will
       happily comply and update it according to the rule.  But sometimes this is harmful, so
       just skip it.

   Compatibility via the variable: "makepp_percent_subdirs=1"
       By default, "%" in a pattern rule does not match directories.  This means that a rule like
       this:

           %.o: %.c
               $(CC) $(CFLAGS) -c $(input) -o $(output)

       will not be applied to files like "../shared/xyz.c".  If you want it to match files in
       subdirectories too, then set the variable "makepp_percent_subdirs=1" on the command line
       or near the beginning of a makefile.

   Compatibility via the environment variable: $MAKEPP_IGNORE_OPTS
       Sometimes legacy recursive invocations pass options that makepp doesn't understand.
       Hopefully the option is not important, but it prevents makepp from running.  With this
       environment variable you can ask makepp to silently ignore certain options.  The value
       shall be a space separated list of options, which can come in 4 variants:

       --long=x
           A long option that expects an argument.  This fact must be declared through the equals
           sign, though the actual use may also separated by whitespace, either "--long=bla" or
           "--long bla".

       --long
           A long option without an argument.

       -sx A short option that expects an argument.  This fact must be declared by adding
           something directly after the option, though the actual use may also separated by
           whitespace, either "-sbla" or "-s bla".

       -s  A short option without an argument.

       E.g. override makepp's -R option by one without an argument and accept gmake's debug
       option with an argument:

           export MAKEPP_IGNORE_OPTS='-R --debug=x'

Incompatibilities that require Makefile changes

       •   Makefiles that explicitly call make prevent makepp from building everything itself.
           Alas Perl's own "ExtUtils::MakeMaker" commits the second of the following two forms of
           this mistake up to version 6.56 (Perl 5.12.1):

               subdir:
                   cd subdir; make

               MAKE = make

       •   Setting the "VPATH" variable to some value implicitly calls "vpath % value".  "vpath"
           statements are emulated with the repository mechanism.  So, where gmake substitutes
           the path to the file found in the vpath, makepp will instead link it symbolically to
           where it is needed.  Thus makepp will provide an unmodified string, which is usually
           not a problem.

           Targets in a vpath are not supported.  (Gmake considers them if they are newer than
           their dependencies, but if not, the target will be recreated in the current directory
           -- rather inconsistent.)  Unsetting vpaths is not supported.

       •   A pattern rule present later in a makefile overrides one that is present earlier.
           This is backwards from GNU make.

       •   The set of builtin implicit rules is somewhat different from those for GNU make,
           though the variable names are largely compatible.  The builtin rules should
           successfully compile C/C++/Fortran programs, and in fact may be able to guess the
           proper libraries in some cases too.  Support for Modula-2 and RatFor and other rare
           languages is deliberately not present, because I kept running into problems with GNU
           make's rules when I accidentally reused the extensions for those languages.

       •   An action prefix of "+" is silently ignored.

       •   Archive members are not supported, and neither are the associated automatic variables
           $%, "$(%D)", and "$(%F)".

       •   There is no SCCS support.

       •   Leading and trailing whitespace in variable assignments is ignored (even if the
           whitespace is followed by a comment).  For more details on whitespace handling
           incompatibilities, see "Whitespace in variables" in makepp_variables.

       •   Makepp does not attempt to rebuild files included with the "include" statement unless
           the makefile contains a rule for building them before the include statement is seen.
           (It will attempt to rebuild the makefile itself, however.)  This is normally used for
           handling include file dependencies, and is not as useful with makepp since you don't
           need to do that anyway.

       •   The "SHELL" variable is currently partially ignored.  Makepp always uses /bin/sh
           unless /usr/xpg4/bin/sh or /sbin/xpg4/sh is found or unless you export the "SHELL"
           variable in your makefile.  But if you do, the command parser might not fully
           understand what your shell command does.  On Windows Strawberry or ActiveState Perl
           you must instead set your SHELL variable before calling makepp.

       •   Dependencies of anything on the Makefile still work, but are usually unnecessary.
           This is usually used to force a rebuild when compilation options change.  Makepp knows
           when build commands have changed without anything special in the makefile; it stores
           this on a file-by-file basis.  If you change the makefile, it knows exactly which
           files need recompilation.

       •   Intermediate files are not deleted.  (Because makepp insists on having all of the file
           dates be the same as they were on the last build, intermediate files must all be
           present or else rebuilds will occur.)  There is no special status accorded to
           intermediate files.

       •   The only special target that is supported is ".PHONY" and partially ".SUFFIXES".  The
           remaining are simply ingored.

           Specifically, GNU make has the following special targets:

           .SUFFIXES
               Makepp ignores ".SUFFIXES" except for the special case of ".SUFFIXES" with no
               dependencies, like this:

                   .SUFFIXES:

               which tells it not to load any of its default rules.

           .INTERMEDIATE, .SECONDARY, .PRECIOUS
               No special status is accorded to intermediate files and so these targets are not
               meaningful.

           .IGNORE
               This target is ignored.  If you want to ignore errors, put the word "ignore_error"
               (or a minus sign) in front of the command whose exit status is to be ignored.

           .SILENT
               This target is ignored.  If you want commands not to echo, put the word "noecho"
               (or the "@" character) in front of the command which is not supposed to be echoed,
               or use the "--silent" option to makepp.

           .DELETE_ON_ERROR
           .EXPORT_ALL_VARIABLES
           .NOEXPORT
           .POSIX
           .DEFAULT
               These targets are not supported and are simply ignored.

       •   The GNU make functions "eval", "flavor" and "value" are not currently supported.  You
           can achieve the same thing as eval in a more straight-forward way with "$[...]"
           variable or function expansion.

       •   Double colon rules are not fully supported.  (They cannot be: in makepp's paradigm,
           there cannot be more than one way to update a target.)  Currently, each successive
           double colon rule for a given target simply appends its command string and dependency
           list to the command string and dependency list for this target.  For example, if you
           write this:

               a :: b
                   &cat b -o a

               # Later in your makefile:
               a :: c
                   &cat c -o >>a

           it is exactly the same as if you had written

               a : b c
                   &cat b -o a
                   &cat c -o >>a

           This is certainly not what double colon rules are intended for, and it will not always
           work, but it does work for targets like "clean" or for all the stuff that
           ExtUtils::MakeMaker puts into its makefiles.  Don't count on it for anything other
           than legacy makefiles.

       •   The "$(wildcard )" function matches not only files which exist, but also files which
           do not yet exist, but which have a rule which makepp has seen at the time the
           "$(wildcard )" function is evaluated.

       •   The "define" statement is supported, but handling of "@" preceding it is done
           differently.  Currently in makepp, "@" in front of a variable which has a multi-line
           value will only suppress echoing of the first line.  For example,

               define echo-lines
               &echo line1 -o $@
               &echo line2 -o>>$@
               endef

               x:
                   @$(echo-lines)

           will not suppress printing of "&echo line2" as it does in GNU make; it will only
           suppress printing of "&echo line1".

       •   Makepp does not support the following environment variables (it does not set them up,
           and it just ignores them):

           MAKEOVERRIDES
           MFLAGS

   Incompatibilities in order of expression expansion
       •   In makepp, rule actions are expanded before all of the dependencies are guaranteed to
           have been built.  You can work around this by changing rules such as this:

               foo: bar
                   genfoo < $(shell cat bar)

           to this:

               foo: bar
                   genfoo < `cat bar`

           or this, which will make the file during the expansion:

               foo: bar
                   genfoo < $(&cat $(make bar))

           This is preferable here, because the file listed in bar is also a dependency of this
           rule, and makepp can now catch it when lexically analyzing the redirection.

       •   Though I have not seen this used, GNU make allows the following:

               colon = :
               a$(colon) b
                   echo $^

           Makepp expands "$(colon)" too late for this to work.  However it offers the
           alternative "$[colon]" syntax, which can do much more than GNU make, because it is
           expanded very early.

   "$(MAKE)" may include spaces
       In an uninstalled makepp or if the platform doesn't seem to support starting a Perl script
       by magic number or with "--traditional-recursive-make" this variable will include at least
       one space.  That is not a problem when using it as a command.  But when passing it as an
       unquoted parameter to a script (as the Perl 5.14.0 build system does), it will tear it
       apart into separate parameters, leading to confusion.  So as a parameter it is safer to
       quote it as '$(MAKE)'. which doesn't break backward compatibility.

   Target-specific assignments don't propagate
       Makepp's target-specific variables are slightly different from GNU make's in that they
       only apply to the rule for the one file mentioned, and not to any of its predecessors; see
       Target-specific assignments.

   Parentheses or braces don't nest
       Makepp ends expressions at the first matching parenthesis or brace.  Instead of this

           $(somefunction ... ( ) ...) # GNU make style

       you must use either of these

           ${somefunction ... ( ) ...} # GNU make compatible
           $((somefunction ... ( ) ...)) # Makepp extension

       This will probably be fixed in version 2.1, maybe optionally.

   Minor points
       Pattern dependencies don't match phony targets
               %.a: %.b; ...
               $(phony x.b): ; ...         # does not provide a way to build x.a

       Comments don't have continuation lines
               # This is \
               NOT a 2-line comment

Command line incompatibilities

       Makepp supports a few of make's more useful command line options.  The following, however,
       are not supported:

       -d or --debug
       -f -
           Makepp's internal makefile objects are linked to file objects, so it can't handle
           stdin.

       -i
       -l or --load-average or --max-load
       -m  Makepp's "-m" option has to do with signature method selection, whereas GNU make
           ignores -m.

       -p or --print-data-base
       -q or --question
       -R or --no-builtin-variables
           Makepp's "-R" option actually does something completely different.

       -S --no-keep-going or --stop
           The "--stop" option stops (puts to sleep) makepp after learning all the rules, so you
           can continue editing.

       -t or --touch
       -w or --print-directory
           This happens automatically.

       --warn-undefined-variables

       Some of these can be easily supported if anyone cares.

Variable incompatibilities

       Makepp looks in $PATH for a matching command to return for variables like "$(CC)" or
       "$(CXX)", while GNU make has static defaults.  Also makepp gives preference to "gcc" and
       "g++" while surprisingly GNU make returns "cc" for the former, but the same for the
       latter.  You can override these in the makefile, on the command line or by exporting a
       variable of the same name before invoking makepp.