Date: Sat, 09 Oct 2010 19:47:12 +0100 From: Christopher Key <cjk32@cam.ac.uk> To: bf1783@gmail.com Cc: obrien@FreeBSD.org, "b. f." <bf1783@googlemail.com>, freebsd-ports@FreeBSD.org Subject: Re: OPTIONS Message-ID: <4CB0B8B0.8030400@cam.ac.uk> In-Reply-To: <AANLkTikrMNGtzDJDrRYc%2ByaB1npRpjMv7gsfiiGC8gVy@mail.gmail.com> References: <AANLkTimaLdFe38VFf%2BXoeT9RW4TQezvd0KbnJWAUZzUu@mail.gmail.com> <AANLkTikrMNGtzDJDrRYc%2ByaB1npRpjMv7gsfiiGC8gVy@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------080802030803070405060004 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit On 06/10/2010 13:42, b. f. wrote: > > You can set those knobs via the command line, or via Makefile.{inc, > ${ARCH}*, ${OPSYS}, local}, or via make.conf, where you can limit the > scope based on the .CURDIR, etc. Although we do have a problem, as > you note in (4), with knobs that are OPTIONS, but are defined > somewhere other than OPTIONSFILE. I hadn't seen: > > http://docs.freebsd.org/cgi/mid.cgi?4C476F69.1060200 > > until swell.k pointed it out (thanks). I think that it does some good > things, but it does have some problems: > > --I don't think the priority is right: the "environment" settings > ought to override the PORTS_DBDIR entries. This is because they will > do so anyway in some circumstances (because of recursion, or the use > of make -e/-E, or because you can't .undef some "environment" > variables), but also because users may want to perform a test build > with knobs defined in the "environment", without having to alter their > settings in PORTS_DBDIR. > > --The parsing of the config files needs to be changed, so that > _OPTION_SRC_${OPT} isn't set to "config" when it should be > "environment" (see above). Also, the entries in OPTIONSFILE.local > ought to override anything in OPTIONSFILE, without regard to > precedence of WITHOUT_*. > > --There needs to be a final sanity-check, that fails with an > appropriate error message if both WITH_* and WITHOUT_* are defined, > because the .undefs are not sufficient to guarantee mutual > exclusivity. > I'm afraid I'm really in a position to look at this closely now, but I think that the latest version (attached) might resolve some of the above problems. Kind regards, Christopher Key --------------080802030803070405060004 Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0"; name="rework-options.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="rework-options.patch" Index: Mk/bsd.port.mk =================================================================== RCS file: /home/ncvs/ports/Mk/bsd.port.mk,v retrieving revision 1.643 diff -u -r1.643 bsd.port.mk --- Mk/bsd.port.mk 15 Jul 2010 14:48:50 -0000 1.643 +++ Mk/bsd.port.mk 26 Jul 2010 12:31:53 -0000 @@ -1291,43 +1291,124 @@ .endif OPTIONSFILE?= ${PORT_DBDIR}/${UNIQUENAME}/options .if defined(OPTIONS) -# include OPTIONSFILE first if exists + +# Firstly, get a list of all options +_OPTIONS_LIST= + +_FIELD= 0 +. for O in ${OPTIONS:C/".*"//} +. if ${_FIELD} == 0 +_FIELD= 1 +_OPTIONS_LIST:= ${_OPTIONS_LIST} ${O} +. else +_FIELD= 0 +. endif +. endfor +. undef _FIELD + +# Get an on/off value for each option defined either in environment, make.conf, ports.conf or on the command line +# Attempt to undef the corresponding WITH_XXX, WITHOUT_XXX (we'll restore them later) so that: +# a) we can detect immutable options from the environment or command line +# b) we can see what we read in +. for OPT in ${_OPTIONS_LIST} +. if defined(WITH_${OPT}) || defined(WITHOUT_${OPT}) +. if defined(WITHOUT_${OPT}) # always check WITHOUT_XXX before WITH_XXX to give WITHOUT_XXX priority +_OPTION_VAL_${OPT}= off +. else +_OPTION_VAL_${OPT}= on +. endif +_OPTION_SRC_${OPT}= site +. undef WITH_${OPT} +. undef WITHOUT_${OPT} +. endif +. endfor + +# Detect which variables we failed to undef. These will have been specified on the command line, and will be +# immutable. Check for duplicate WITH_XXX and WITHOUT_XXX, as we can't clean these up for the port. +# Otherwise, update the option value to give cmdline priority over make.conf, ports.conf, and note that +# this option is immutable, and cannot be overriden. +. for OPT in ${_OPTIONS_LIST} +. if defined(WITH_${OPT}) && defined(WITHOUT_${OPT}) +. error You set both WITH_${OPT} and WITHOUT_${OPT}. Abort. +. elif defined(WITH_${OPT}) || defined(WITHOUT_${OPT}) +. if defined(WITHOUT_${OPT}) # always check WITHOUT_XXX before WITH_XXX to give WITHOUT_XXX priority +_OPTION_VAL_${OPT}= off +. else +_OPTION_VAL_${OPT}= on +. endif +_OPTION_SRC_${OPT}= env+args +_OPTION_IMM_${OPT}= true +. endif +. endfor + +# Include OPTIONSFILE if exists . if exists(${OPTIONSFILE}) && !make(rmconfig) . include "${OPTIONSFILE}" . endif . if exists(${OPTIONSFILE}.local) . include "${OPTIONSFILE}.local" . endif -WITHOUT:= -WITH:= -. if defined(OPTIONS) -REALOPTIONS=${OPTIONS:C/".*"//g} -. for O in ${REALOPTIONS} -RO:=${O} -. if ${RO:L} == off -WITHOUT:= ${WITHOUT} ${OPT} + +# Update our list of option values based on what we read from our config file. Only override the option +# value if it isn't immutable, but always try to unset WITH_XXX and WITHOUT_XXX. We'll restore them later, +# ensuring that WITH_XXX and WITHOUT_XXX are mutually exclusive. +. for OPT in ${_OPTIONS_LIST} +. if defined(WITH_${OPT}) || defined(WITHOUT_${OPT}) +. if !defined(_OPTION_IMM_${OPT}) +. if defined(WITHOUT_${OPT}) # always check WITHOUT_XXX before WITH_XXX to give WITHOUT_XXX priority +_OPTION_VAL_${OPT}= off +. else +_OPTION_VAL_${OPT}= on +. endif +_OPTION_SRC_${OPT}= config +. endif +. undef WITH_${OPT} +. undef WITHOUT_${OPT} +. endif +. endfor + +# Set default value for remaining options +_FIELD= 0 +. for O in ${OPTIONS:C/".*"//} +. if ${_FIELD} == 0 +_FIELD= 1 +OPT:= ${O} +. else +_FIELD= 0 +. if !defined(_OPTION_VAL_${OPT}) +_OPTION_VAL_${OPT}:= ${O:L} +_OPTION_SRC_${OPT}= default . endif -. if ${RO:L} == on -WITH:= ${WITH} ${OPT} . endif -OPT:=${RO} . endfor +. undef _FIELD +. undef OPT + +# restore WITH_XXX, WITHOUT_XXX appropriately +. for OPT in ${_OPTIONS_LIST} +. if ${_OPTION_VAL_${OPT}} == on +WITH_${OPT}= true +. else +WITHOUT_${OPT}= true . endif -# define only if NO WITH/WITHOUT_${W} is defined -. for W in ${WITH} -. if !defined(WITH_${W}) && !defined(WITHOUT_${W}) -WITH_${W}:= true -. endif . endfor -. for W in ${WITHOUT} -. if !defined(WITH_${W}) && !defined(WITHOUT_${W}) -WITHOUT_${W}:= true -. endif + +# shell script to set variables for current option values +_OPTIONS_SET_SH= +. for OPT in ${_OPTIONS_LIST} +_OPTIONS_SET_SH:= ${_OPTIONS_SET_SH} \ + OPTION_SRC_${OPT}=${_OPTION_SRC_${OPT}}; \ + OPTION_VAL_${OPT}=${_OPTION_VAL_${OPT}}; . endfor -. undef WITH -. undef WITHOUT -. undef RO -. undef REALOPTIONS + +# clean up +. for OPT in ${_OPTIONS_LIST} +. undef _OPTION_VAL_${OPT} +. undef _OPTION_SRC_${OPT} +. undef _OPTION_IMM_${OPT} +. endfor +. undef _OPTIONS_LIST + .endif .endif @@ -6102,24 +6183,11 @@ ${MKDIR} $${optionsdir} 2> /dev/null) || \ (${ECHO_MSG} "===> Cannot create $${optionsdir}, check permissions"; exit 1) .endif - -@if [ -e ${OPTIONSFILE} ]; then \ - . ${OPTIONSFILE}; \ - fi; \ + -@${_OPTIONS_SET_SH} \ set -- ${OPTIONS} XXX; \ while [ $$# -gt 3 ]; do \ OPTIONSLIST="$${OPTIONSLIST} $$1"; \ - defaultval=$$3; \ - withvar=WITH_$$1; \ - withoutvar=WITHOUT_$$1; \ - withval=$$(eval ${ECHO_CMD} $$\{$${withvar}\}); \ - withoutval=$$(eval ${ECHO_CMD} $$\{$${withoutvar}\}); \ - if [ ! -z "$${withval}" ]; then \ - val=on; \ - elif [ ! -z "$${withoutval}" ]; then \ - val=off; \ - else \ - val=$$3; \ - fi; \ + val=$$(eval ${ECHO_CMD} $$\{OPTION_VAL_$${1}\}); \ DEFOPTIONS="$${DEFOPTIONS} $$1 \"$$2\" $${val}"; \ shift 3; \ done; \ @@ -6176,21 +6244,11 @@ .if defined(OPTIONS) .if exists(${OPTIONSFILE}) # scan saved options and invalidate them, if the set of options does not match - @. ${OPTIONSFILE}; \ + @${_OPTIONS_SET_SH} \ set ${OPTIONS} XXX; \ while [ $$# -gt 3 ]; do \ - withvar=WITH_$$1; \ - withoutvar=WITHOUT_$$1; \ - withval=$$(eval ${ECHO_CMD} $$\{$${withvar}\}); \ - withoutval=$$(eval ${ECHO_CMD} $$\{$${withoutvar}\}); \ - if [ ! -z "$${withval}" ]; then \ - val=on; \ - elif [ ! -z "$${withoutval}" ]; then \ - val=off; \ - else \ - val=missing; \ - fi; \ - if [ "$${val}" = "missing" ]; then \ + src=$$(eval ${ECHO_CMD} $$\{OPTION_SRC_$${1}\}); \ + if [ "$${src}" != "config" ]; then \ OPTIONS_INVALID=yes; \ fi; \ shift 3; \ @@ -6206,26 +6264,16 @@ .if !target(showconfig) showconfig: -.if defined(OPTIONS) +.if !defined(OPTIONS) + @${ECHO_MSG} "===> No options to configure" +.else @${ECHO_MSG} "===> The following configuration options are available for ${PKGNAME}:" - -@if [ -e ${OPTIONSFILE} ]; then \ - . ${OPTIONSFILE}; \ - fi; \ + @${_OPTIONS_SET_SH} \ set -- ${OPTIONS} XXX; \ while [ $$# -gt 3 ]; do \ - defaultval=$$3; \ - withvar=WITH_$$1; \ - withoutvar=WITHOUT_$$1; \ - withval=$$(eval ${ECHO_CMD} $$\{$${withvar}\}); \ - withoutval=$$(eval ${ECHO_CMD} $$\{$${withoutvar}\}); \ - if [ ! -z "$${withval}" ]; then \ - val=on; \ - elif [ ! -z "$${withoutval}" ]; then \ - val=off; \ - else \ - val="$$3 (default)"; \ - fi; \ - ${ECHO_MSG} " $$1=$${val} \"$$2\""; \ + val=$$(eval ${ECHO_CMD} $$\{OPTION_VAL_$${1}\}); \ + src=$$(eval ${ECHO_CMD} $$\{OPTION_SRC_$${1}\}); \ + ${ECHO_MSG} " $$1=$${val} ($${src}) \"$$2\""; \ shift 3; \ done @${ECHO_MSG} "===> Use 'make config' to modify these settings" --------------080802030803070405060004--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4CB0B8B0.8030400>