help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Feature idea: required version flag


From: John Dill
Subject: Re: Feature idea: required version flag
Date: Mon, 3 Nov 2008 14:55:07 -0500

> Hi, all!
> 
> i know we've discussed the topic of "how to check if the user is
> running Make version XYZ or higher" before, but i just had another
> idea for helping to solve this...
>
> Consider this common makefile header:
> #!/usr/bin/make -f
> # Requires GNU Make 3.80+!
> default: all
>
> What if we could replace the first line with:
> 
> #!/usr/bin/make -R=3.80 -f
>
> (i picked -R off the top of my head (for "Required version") - maybe
> -R is already in use)
>
> In this invokation, make would refuse to run if its version is less
> than 3.80. If its an older make, it would probably puke on the unknown
> -R flag and die anyway, so we're protected either way.

My particular solution is to have an include file that implements some
variables for use in my makefile.  This is an excerpt from my make function
library.

# ********************************************************************
#        File: config.mi
#      Author: John Dill
#       Group: Make eXtension Library
#     Created: 9/25/2006
#    Function: Test what the 'make' program supports.
#         $Id$
# ********************************************************************

ifndef __mxl_config_mi

# Inclusion guard for this file.
__mxl_config_mi:=$(true)

# The Make eXtension Library (mxl) depends on the existance of several
# 'make' functions.  In addition, certain functions implemented in 'mxl'
# may be disabled or have alternate implementations depending on the
# version of 'make'.  The following is a list of 'make' versions and
# the inclusion of certain 'make' functions.
#
# 3.75 - baseline
# 3.76.1 - added wordlist function
# 3.77 - no changes
# 3.78.1 - added call, error, warning, if, dropped invalid
# 3.79 - no changes
# 3.79.1 - no changes
# 3.80 - added value, eval
# 3.81 - added abspath, flavor, lastword, realpath, info, or, and
#
# The 'call' function is required for 'mxl' to even function, so the
# minimum supported 'make' version is 3.78.1.  The 'eval' function is
# also important but not required to use the majority of 'mxl'
# functionality.  The lack of 'eval' will force 'mxl' to use a less-
# efficient workaround to implement variable storage within functions.

# The following parameterizes the boolean values.  In the makefile
# $(if ...) function, empty text represents false, while any text
# represents true.

# This variable represents the true construct.
true:=true

# This variable represents the false construct.
false:=

# This variable represents the empty or null value.  It is used to
# circumvent make's function scoping problems where a child function
# may be able to see a parent function's arguments.  This occurs in 
# versions of make below 3.80.  To prevent that from occuring,
# $(nothing) is used as a placeholder for empty arguments.
nothing:=

# This tests for the existance of $(value) (GNU Make 3.80).
__mxl_have_value:=$(value true)

# The test for the existence of the $(eval) function has complications
# with the inclusion guards of this file in GNU Make 3.80.  This is
# a bug where $(eval) causes an error in a conditional block that 'make'
# reports as "*** missing `endif'.  Stop."
#
# An implementation that would work with GNU Make 3.81 could be:
#
# __mxl_have_eval:=$(false)
# __mxl_eval_test:=$(eval __mxl_have_eval:=$(true))
#
# There are a few ways to workaround this problem.  The first is to
# remove the inclusion guards.  The other is to use deferred expansion
# instead of immediate expansion with the knowledge that the
# '__mxl_have_eval' variable should not be evaluated in a conditional
# when using GNU Make 3.80.  The last option is to check if $(value)
# is available, implying that $(eval) has been implemented.

# This tests for the existance of $(eval) (GNU Make 3.80).
__mxl_have_eval:=$(__mxl_have_value)

# This defines the make compatibility for GNU Make 3.80.
__mxl_have_make_3.80:=$(__mxl_have_value)

# This tests the existance of $(abspath) (GNU Make 3.81).
__mxl_have_abspath:=$(abspath $(true))

# This tests the existance of $(flavor) (GNU Make 3.81).
__mxl_have_flavor:=$(if $(flavor true),$(true))

# This tests the existance of $(lastword) (GNU Make 3.81).
__mxl_have_lastword:=$(lastword $(true))

# This tests the existance of $(realpath) (GNU Make 3.81).
__mxl_have_realpath:=$(realpath $(true))

# This tests the existance of $(info) (GNU Make 3.81).  The $(info)
# function does not evaluate to any text, so instead we'll check if
# another function exists from version 3.81.
__mxl_have_info:=$(__mxl_have_lastword)

# This tests the existance of $(or) (GNU Make 3.81).
__mxl_have_or:=$(or $(true),$(false))

# This tests the existance of $(and) (GNU Make 3.81).
__mxl_have_and:=$(and $(true),$(true))

# This defines the make compatibility for GNU Make 3.81.
__mxl_have_make_3.81:=$(__mxl_have_lastword)

endif # __mxl_config_mi

------------------------------------------------------------------------------------

Then you can use some ifdef condition to have code based on a particular
version.

My 'and' workaround function uses this:

ifndef __mxl_have_and
and=$(if $(strip $1),$(if $(strip $2),$2,$(false)),$(false))
endif

For limiting the makefile to a particular version of make, you could use
this.

ifndef __mxl_have_make_3.81
$(error You should be using make version 3.81!  Go get it!)
endif

Hope this helps,
John Dill





reply via email to

[Prev in Thread] Current Thread [Next in Thread]