Date: Wed, 21 Jul 2010 23:06:33 +0100 From: Christopher Key <cjk32@cam.ac.uk> To: freebsd-ports@freebsd.org Subject: [patch] Integration between portconf and port options Message-ID: <4C476F69.1060200@cam.ac.uk>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------010902020507020400060909 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit At present, the interaction between portconf and port options is somewhat confusing. Firstly, the output of make showconfig and the defaults displayed by make config are unaffected by anything set in ports.conf. Secondly, its quite easy to unexpectedly end up having both WITH_XXX and WITHOUT_XXX defined. Consider devel/binutils: #v+ # cd /usr/ports/devel/binutils # make rmconfig # make showconfig ===> The following configuration options are available for binutils-2.20.1_3: NLS=off (default) "Enable National Language Support" ===> Use 'make config' to modify these settings # make -V WITH_NLS # make -V WITHOUT_NLS true #v- i.e. one option defaulting to off. We can switch it on with ports.conf: #v+ # make -DWITH_NLS -VWITH_NLS 1 # make -DWITH_NLS -VWITHOUT_NLS #v- however, if options get set then things get confusing: #v+ # make config # make showconfig ===> The following configuration options are available for binutils-2.20.1_3: NLS=off "Enable National Language Support" ===> Use 'make config' to modify these settings # make -V WITH_NLS # make -V WITHOUT_NLS true # make -DWITH_NLS -VWITH_NLS 1 # make -DWITH_NLS -VWITHOUT_NLS true #v- Just by accepting the defaults, we've suddenly got both WITH_NLS and WITHOUT_NLS defined. In this case, the port checks for WITH_NLS, and the build will be unaffected. In general, the port must check for WITH_XXX if the default option value is off (and for WITHOUT_XXX if the default value is on) in order to avoid the build changing as a result of accepting the default configuration presented by make config. This seems rather fragile, and is clearly susceptible to problems should the default option values get changed. The attached patch reworks the options framework slightly to try resolve these two problems. When a port is being built, each option defined in OPTIONS can be on or off, and exactly one of WITH_XXX and WITHOUT_XXX will be defined after including bsd.port.options.mk. There are three locations from which an option can take its value: (in decreasing order of priority) 1) /var/db/ports/*/options 2) ports.conf, make.conf and command line arguments - for now termed environment, although a more descriptive term is desired. 3) default values from OPTIONS When make config is run, the values displayed will be the values of the options seen by the port when building. Typically, this would means that when make config is first run, the values presented would be the defaults (but would reflect anything set in ports.conf too). Subsequent runs would then show the values saved by the last invocation of make config. When make showconfig, the options displayed will again be the values seen by the port when building. It also displays the location from which the option value came from (i.e. config, environment or default). As both /var/db/ports/*/options and ports.conf etc are stored as lists of WITH_XXX and WITHOUT_XXX variables, it is possible for both WITH_XXX and WITHOUT_XXX to be defined simultaneously in one location. If both are defined in one location, then WITHOUT_XXX takes priority. If both are defined, but only in different locations, the the first location on the list takes priority. For example, if /var/db/port/*/options had WITH_XXX set and ports.conf had WITHOUT_XXX set, then the option would be on (and only WITH_XXX would be defined after bsd.port.options.mk), because .../options takes priority. However, if nothing was set in .../options, and ports.conf set both WITH_XXX and WITHOUT_XXX then the option would be off (and only WITHOUT_XXX would be defined after bsd.port.option.mk) because WITHOUT_XXX takes priority. Feedback would be very much appreciated. Kind regards, Christopher Key --------------010902020507020400060909 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 21 Jul 2010 20:31:25 -0000 @@ -1291,43 +1291,88 @@ .endif OPTIONSFILE?= ${PORT_DBDIR}/${UNIQUENAME}/options .if defined(OPTIONS) -# include OPTIONSFILE first if exists + +_OPTIONS_LIST=${OPTIONS:C/".*"//g:S/on//:S/off//} + +# Firstly, get an on/off value for each option defined by make.conf, ports.conf, -D... +# Also undef the corresponding WITH_XXX, WITHOUT_XXX so that we can see what we read in +# from our config file. We'll restore them later. +. 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}?= environment +. undef WITH_${OPT} +. undef WITHOUT_${OPT} +. 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} + +# Update our list of option values based on what we read from our config file. Again, 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(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 +. undef WITH_${OPT} +. undef WITHOUT_${OPT} +. endif +. endfor + +# Set default value for remaining options +. for O in ${OPTIONS:C/".*"//g} RO:=${O} -. if ${RO:L} == off -WITHOUT:= ${WITHOUT} ${OPT} +. if ${RO:L} == on || ${RO:L} == off +. if !defined(_OPTION_VAL_${OPT}) +_OPTION_VAL_${OPT}:= ${RO:L} +_OPTION_SRC_${OPT}:= default . endif -. if ${RO:L} == on -WITH:= ${WITH} ${OPT} +. else +OPT:= ${RO} +.endif +.endfor +.undef RO +.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 -OPT:=${RO} . endfor -. 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 + +# 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 -. for W in ${WITHOUT} -. if !defined(WITH_${W}) && !defined(WITHOUT_${W}) -WITHOUT_${W}:= true -. endif + +# clean up +. for OPT in ${_OPTIONS_LIST} +. undef _OPTION_VAL_${OPT} +. undef _OPTION_SRC_${OPT} . endfor -. undef WITH -. undef WITHOUT -. undef RO -. undef REALOPTIONS +. undef _OPTIONS_LIST + .endif .endif @@ -6102,24 +6147,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 +6208,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 +6228,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" --------------010902020507020400060909--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4C476F69.1060200>