Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
MAKEPP_INCOMPATIBILITIES(1)	    Makepp	   MAKEPP_INCOMPATIBILITIES(1)

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 either one	or both	of:

	       --defer-include
	       --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".

       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 "--defer-include"
       Makepp reads makefiles in a single pass,	where GNU make	is  multipass.
       Hence  this  will  not  work, because GIT-VERSION-FILE must be built to
       process the "include" statement.	 But it	depends	on something  that  is
       unknown at this point.  To solve	this, the ".PHONY" declaration must be
       moved up	before the "include" statement:

	   GIT-VERSION-FILE: FORCE
	       @$(SHELL_PATH) ./GIT-VERSION-GEN
	   include GIT-VERSION-FILE
	   .PHONY: FORCE

       This  option  internally	 reorders the include statements to the	end of
       the makefile.  That may in  turn	 cause	variables  to  have  different
       values,	in  which  case	 you  should  set  the problematic ones	on the
       command line.

   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.

perl v5.36.3			  2012-03-19	   MAKEPP_INCOMPATIBILITIES(1)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=makepp_incompatibilities&sektion=1&manpath=FreeBSD+Ports+14.3.quarterly>

home | help