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.

perl v5.32.0                                       2021-01-06                        MAKEPP_INCOMPATIBILITIES(1)